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

Cypress自定义截图问题:无法获取specName致路径与文件名异常

Cypress自定义失败截图文件名与路径问题解决

问题根源

你的代码存在以下核心问题导致无法获取specName:

  1. 变量作用域混淆:specName定义在浏览器环境的函数内,但sendSpecNameToPlugin任务运行在Node环境,两者无法共享变量
  2. 事件注册错误:takess.ts中在函数内部注册Cypress.on('after:screenshot'),但该事件在Node端的setupNodeEvents中处理更合适
  3. 路径计算错误:相对路径../../screenshots无法准确定位到目标目录,应该基于Cypress配置的路径构建

修正后的代码实现

1. 重构takess.ts(Node端逻辑)

import fs from 'fs';
import path from 'path';

// 存储specName的变量,在Node环境作用域内
let specName = '';

export const setSpecName = (name: string) => {
  specName = name;
};

export function renameAndMoveScreenshot(details: any) {
  // 优先使用details中的specName,没有则用存储的specName
  const testName = (details.specName || specName).replace(/\.|\/|\s/g, '_');
  const timeStamp = new Date().toISOString().replace(/:/g, '_');
  const fileName = `${testName}--${timeStamp} (failed).png`;

  // 构建目标目录:基于项目根目录到dist/cypress/apps/hr/screenshots/[specName]
  const targetDir = path.resolve(__dirname, '../../dist/cypress/apps/hr/screenshots', specName.replace('.cy.ts', ''));
  const newPath = path.join(targetDir, fileName);

  // 创建目录(递归创建父目录)
  if (!fs.existsSync(targetDir)) {
    fs.mkdirSync(targetDir, { recursive: true });
  }

  return new Promise((resolve, reject) => {
    fs.rename(details.path, newPath, (err) => {
      if (err) {
        reject(err);
      } else {
        resolve({ path: newPath });
      }
    });
  });
}

2. 修正Cypress.config.ts

import { defineConfig } from 'cypress';
import { setSpecName, renameAndMoveScreenshot } from './lib/takess';

export default defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      // 注册任务接收specName
      on('task', {
        sendSpecNameToPlugin: (name: string) => {
          setSpecName(name);
          return null; // 任务必须返回值
        }
      });

      // 在Node端处理after:screenshot事件
      on('after:screenshot', (details) => {
        // 只处理失败测试的截图
        if (details.testFailed) {
          return renameAndMoveScreenshot(details);
        }
        return details; // 非失败截图保持默认处理
      });
    },
  },
});

3. 调整测试文件login.spec.ts

/// <reference types="cypress"/>

describe('screenshot test', () => {
  beforeEach(()=>{
    cy.visit('/');
    // 在每个测试前传递specName
    cy.task('sendSpecNameToPlugin', Cypress.spec.name);
  });

  it('Visits the hr test and fails intentionally', () => {
    // 故意让测试失败,触发自动截图
    cy.get('non-existent-element').should('exist');
  });
});

关键说明

  • 变量作用域:将specName存储在Node环境的作用域内,通过setSpecName函数从测试任务中传递值,确保前后端环境能正确共享
  • 路径构建:使用path.resolve和path.join构建绝对路径,避免相对路径的不确定性,确保截图存入dist/cypress/apps/hr/screenshots/login.cy.ts目录下
  • 失败截图触发:Cypress默认会在测试失败时自动截取截图,通过details.testFailed判断只处理失败的截图,无需手动调用cy.screenshot

内容的提问来源于stack exchange,提问作者Christian Rudolf Tan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 17:47:06