You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cypress中通过字符串插值指定所有子目录读取截图文件?

解决Cypress中读取多级目录下测试截图的问题

问题原因

cy.readFile() 不支持glob模式的通配符(比如**),只能接收具体的文件路径,所以直接在路径中添加**无法匹配多级子目录。

解决方案

我们需要先通过Node.js的文件系统工具递归查找目标截图的准确路径,再传入cy.readFile()进行读取。以下是两种可行实现方式:

方式1:使用原生Node.js fs模块(无额外依赖)

首先在cypress.config.js中注册一个自定义任务,用于递归查找文件:

const { defineConfig } = require('cypress');
const fs = require('fs').promises;
const path = require('path');

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('task', {
        // 查找指定的测试截图
        findScreenshot: async ({ screenshotsFolder, specName, screenshotFileName }) => {
          // 递归遍历所有子目录,找到包含specName目录且文件名匹配的文件
          const allFiles = await fs.readdir(screenshotsFolder, { recursive: true });
          const targetFileRelativePath = allFiles.find(file => 
            file.includes(`${specName}/`) && file.endsWith(screenshotFileName)
          );

          if (!targetFileRelativePath) {
            throw new Error(`未找到截图:${screenshotFileName}`);
          }

          return path.join(screenshotsFolder, targetFileRelativePath);
        }
      });
    },
  },
});

然后在测试的afterEach钩子中调用该任务,获取路径后读取文件:

afterEach(() => {
  const screenshotsFolder = 'test-results/screenshots';
  const screenshotFileName = `${testState.feature.name} -- ${testState.currentScenario.name} (failed).png`;

  cy.task('findScreenshot', {
    screenshotsFolder,
    specName: Cypress.spec.name,
    screenshotFileName
  }).then((screenshotPath) => {
    cy.readFile(screenshotPath, "base64").then((imgData) => {
      stepResult.attachment = {
        data: imgData,
        media: { type: "image/png" },
        index: testState.currentStep,
        testCase: testState.formatTestCase(testState.currentScenario),
      };
    });
  }).catch(err => {
    // 处理未找到截图的情况,避免影响后续流程
    console.log(err.message);
  });
});

方式2:使用glob包(更简洁,需额外安装)

如果希望用glob语法快速匹配路径,可以先安装glob包:

npm install glob --save-dev

然后在cypress.config.js中注册任务:

const { defineConfig } = require('cypress');
const glob = require('glob');

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('task', {
        findScreenshot: ({ screenshotsFolder, specName, screenshotFileName }) => {
          const pattern = `${screenshotsFolder}/**/${specName}/${screenshotFileName}`;
          const matchedFiles = glob.sync(pattern);

          if (matchedFiles.length === 0) {
            throw new Error(`未找到截图:${screenshotFileName}`);
          }

          // 返回第一个匹配的文件路径
          return matchedFiles[0];
        }
      });
    },
  },
});

测试中的afterEach代码和方式1完全一致。


内容的提问来源于stack exchange,提问作者user9847788

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 11:55:25