如何在Cypress测试中模拟带Authorization头的curl请求下载文件到本地
问题原因
原有代码存在两个核心问题:
- Cypress测试代码默认运行在浏览器沙箱上下文,直接调用Node.js原生
https、fs模块没有执行权限,无法操作本地文件系统 - 原生请求逻辑未和Cypress测试生命周期绑定,执行顺序混乱导致写入动作未正常触发
解决方案1:小文件快速实现(无需额外配置)
直接使用Cypress内置的cy.request + cy.writeFile组合实现,适合体积较小的文件下载:
it('下载带授权验证的文件到本地', () => { // 替换为实际的授权token值 const token = '你的授权token'; // 下载路径支持相对路径(相对Cypress项目根目录)或绝对路径 const savePath = 'cypress/downloads/目标文件名.后缀'; cy.request({ method: 'GET', url: '替换为实际的下载接口地址', auth: { bearer: token }, encoding: 'binary' // 二进制文件必须保留该配置,避免文件损坏 }).then((response) => { // 校验接口请求成功 expect(response.status).to.eq(200); // 写入文件到本地路径 cy.writeFile(savePath, response.body, 'binary'); }); });
注意事项:
- 二进制类文件(压缩包、图片、音视频、Excel等)必须在请求和写入时都指定
binary编码 - 路径如果使用相对路径,默认是相对于Cypress项目的根目录
cy.request不受浏览器跨域策略限制,不需要额外处理跨域问题
解决方案2:大文件流式下载(性能更优)
如果需要下载数百MB以上的大文件,推荐通过Cypress自定义Task调用Node层流式写入,避免内存占用过高:
步骤1:注册自定义下载Task
在cypress.config.js中新增如下配置:
const { defineConfig } = require('cypress'); const fs = require('fs'); const https = require('https'); const { URL } = require('url'); module.exports = defineConfig({ e2e: { setupNodeEvents(on, config) { // 注册下载自定义任务 on('task', { downloadFile({ downloadUrl, token, savePath }) { return new Promise((resolve, reject) => { const parsedUrl = new URL(downloadUrl); const requestOptions = { hostname: parsedUrl.hostname, path: parsedUrl.pathname + parsedUrl.search, method: 'GET', headers: { 'Authorization': `Bearer ${token}` } }; https.get(requestOptions, (response) => { if (response.statusCode !== 200) { return reject(new Error(`下载失败,状态码:${response.statusCode}`)); } const writeStream = fs.createWriteStream(savePath); response.pipe(writeStream); writeStream.on('finish', () => { writeStream.close(); resolve(`下载完成,文件路径:${savePath}`); }); writeStream.on('error', (err) => { fs.unlink(savePath, () => reject(err)); }); }).on('error', (err) => { reject(err); }); }); } }); return config; } } });
步骤2:测试用例中调用Task
it('流式下载大体积文件', () => { const token = '你的授权token'; const savePath = 'cypress/downloads/大文件.后缀'; cy.task('downloadFile', { downloadUrl: '替换为实际的下载接口地址', token: token, savePath: savePath }).then((result) => { cy.log(result); expect(result).to.include('下载完成'); }); });
内容的提问来源于stack exchange,提问作者Pranjal Prakash Srivastava
相关产品推荐
相关产品推荐

