Cypress执行测试后未生成cypress-mochawesome-report的解决方法
Cypress集成cypress-mochawesome-reporter不生成报告的问题
环境与配置信息
使用版本:
cypress: ^13.7.2cypress-mochawesome-reporter: ^3.8.2
已完成的配置步骤:
- 安装依赖:
npm i --save-dev cypress-mochawesome-reporter - 配置
cypress.config.ts(代码如下) - 在
e2e.ts中导入cypress-mochawesome-reporter/register - 在
index.ts中导入cypress-mochawesome-reporter/cucumberSupport
cypress.config.ts 配置
import eyesPlugin from '@applitools/eyes-cypress'; import { addCucumberPreprocessorPlugin } from '@badeball/cypress-cucumber-preprocessor'; import createBundler from '@bahmutov/cypress-esbuild-preprocessor'; import { defineConfig } from 'cypress'; import * as env from './cypress.env.json'; // eslint-disable-next-line @typescript-eslint/no-var-requires const { createEsbuildPlugin } = require('@badeball/cypress-cucumber-preprocessor/esbuild'); // eslint-disable-next-line @typescript-eslint/no-var-requires const { NodeModulesPolyfillPlugin } = require('@esbuild-plugins/node-modules-polyfill'); // eslint-disable-next-line @typescript-eslint/no-var-requires const { verifyDownloadTasks } = require('cy-verify-downloads'); // eslint-disable-next-line @typescript-eslint/no-var-requires const { beforeRunHook, afterRunHook } = require('cypress-mochawesome-reporter/lib'); export default eyesPlugin( defineConfig({ reporter: 'cypress-mochawesome-reporter', reporterOptions: { reportDir: '/Users/alitaha/Development/frontend/cypress/reports', overwrite: true, html: true, json: true, charts: true, reportPageTitle: 'custom-title', embeddedScreenshots: true, inlineAssets: true, saveAllAttempts: false, }, e2e: { baseUrl: 'https://frontend-release-green.com/', specPattern: '**/*.feature', env, defaultCommandTimeout: 20000, experimentalRunAllSpecs: true, requestTimeout: 20000, viewportWidth: 1920, viewportHeight: 1080, screenshotOnRunFailure: false, video: false, async setupNodeEvents( on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions ): Promise<Cypress.PluginConfigOptions> { // This is required for the preprocessor to be able to generate JSON reports after each run, and more, await addCucumberPreprocessorPlugin(on, config); on( 'file:preprocessor', createBundler({ plugins: [NodeModulesPolyfillPlugin(), createEsbuildPlugin(config)], }) ); on('before:run', async (details) => { console.log('override before:run'); await beforeRunHook(details); }); on('after:run', async () => { console.log('override after:run'); await afterRunHook(); }); on('task', verifyDownloadTasks); // Add the cypress-mochawesome-reporter plugin require('cypress-mochawesome-reporter/plugin')(on); // Make sure to return the config object as it might have been modified by the plugin. return config; }, }, component: { devServer: { framework: 'angular', bundler: 'webpack', }, specPattern: '**/*.cy.ts', }, }) );
e2e.ts 配置
// *********************************************************** // This example support/e2e.ts is processed and // loaded automatically before your test files. // // This is a great place to put global configuration and // behavior that modifies Cypress. // // You can change the location of this file or turn off // automatically serving support files with the // 'supportFile' configuration option. // // You can read more here: // https://on.cypress.io/configuration // *********************************************************** import '@applitools/eyes-cypress/commands'; import 'cypress-mochawesome-reporter/register'; // Import commands.js using ES2015 syntax: import { SnackbarType } from '../../src/app/@shared/components/snackbar/model/snackbar.model'; import * as profile from '../e2e-mocked/signin/mocks/get.profile.json'; import * as settings from '../e2e-mocked/signin/mocks/get.settings.json'; import * as util from '../e2e-mocked/signin/mocks/get.util.json'; import { ApiMock } from '../interfaces/api-mock'; import './commands'; Cypress.on('uncaught:exception', () => { // returning false here prevents Cypress from // failing the test return false; }); Cypress.Commands.add('login', (username: string, password: string) => { cy.request({ method: 'POST', url: '/api/auth/signin', headers: { 'Content-Type': 'application/x-www-form-urlencoded', Cookie: 'XSRF-TOKEN=1', 'X-XSRF-TOKEN': '1', }, body: { username, password }, }); }); Cypress.Commands.add('dismissModal', () => cy.get('.cdk-overlay-backdrop').click()); Cypress.Commands.add('clickAway', () => { cy.get('body').click(); }); Cypress.Commands.add('waitLoading', (state = 'not.exist') => cy.getBySelector('loading-spinner').should(`${state}`)); Cypress.Commands.add('waitSnackbar', (state = 'not.exist', type: SnackbarType = 'success') => cy.get(`.sfc-snackbar.${type}`).should(`${state}`) ); // support/commands.ts or support/index.ts Cypress.Commands.add('waitUntilLoading', (timeout = 20000) => { cy.get('.mat-progress-spinner'); cy.get('.mat-progress-spinner', { timeout }).should('not.exist', { failOnStatusCode: false }); }); Cypress.Commands.add('onMockedIntercept', ({ method, url, response, alias }: ApiMock<unknown>) => { if (Cypress.env('mock')) { cy.intercept(method, url, response).as(alias); } }); Cypress.Commands.add('prepareMockTest', () => { cy.intercept('**/api/**', { statusCode: 404, log: false, }).as('mocked-but-not-intercepted'); cy.intercept('**/api/auth/signin', {}); cy.intercept('**/api/usermanagement/users/preferences', { enableAppNotifications: true, enableEmailNotifications: true, }); cy.intercept('**/api/util', util); cy.intercept('**/api/users/profile', profile); cy.intercept('**/api/application_settings/get_mfa', {}); cy.intercept('**/api/application_settings/settings', settings); cy.intercept('**/api/configuration/features/surveillance', { isEnabled: true }); cy.intercept('**/api/configuration/features/supervision', { isEnabled: true }); cy.intercept('**/api/notifications/unread-count', { unreadCount: 0 }); }); // eslint-disable-next-line @typescript-eslint/no-var-requires require('cy-verify-downloads').addCustomCommand(); declare global { // eslint-disable-next-line @typescript-eslint/no-namespace namespace Cypress { interface Chainable { login(username: string, password: string): Chainable<Response<unknown>>; waitUntilLoading(timeout?: number): Chainable<void>; dismissModal(): Chainable<JQuery<HTMLElement>>; clickAway(): Chainable<JQuery<HTMLElement>>; onMockedIntercept(mock: ApiMock<unknown>): Chainable<Response<unknown>>; verifyDownload( file: string, options?: { contains?: true; timeout?: number; interval?: number; } ): Chainable<boolean>; waitLoading(state?: 'be.visible' | 'not.exist'): Chainable<JQuery<HTMLElement>>; waitSnackbar(state?: 'be.visible' | 'not.exist', type?: SnackbarType): Chainable<JQuery<HTMLElement>>; prepareMockTest(): void; } } } beforeEach(() => { const mockBackend = Cypress.env('mock'); if (mockBackend) { cy.prepareMockTest(); } });
index.ts 配置
import 'cypress-mochawesome-reporter/cucumberSupport';
问题
测试执行正常,但未生成任何Mocha报告,求解决方法。
解决方案
1. 调整插件注册顺序
由于集成了@badeball/cypress-cucumber-preprocessor,报告器插件需要优先注册以确保兼容性。修改setupNodeEvents中的代码顺序:
async setupNodeEvents(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions): Promise<Cypress.PluginConfigOptions> { // 先注册报告器插件 require('cypress-mochawesome-reporter/plugin')(on); // 再初始化Cucumber预处理器 await addCucumberPreprocessorPlugin(on, config); on( 'file:preprocessor', createBundler({ plugins: [NodeModulesPolyfillPlugin(), createEsbuildPlugin(config)], }) ); on('task', verifyDownloadTasks); return config; }
2. 修复报告目录配置
- 检查
reportDir的绝对路径是否存在,以及当前用户是否有读写权限。建议改用相对路径避免权限或路径错误:reporterOptions: { reportDir: 'cypress/reports', // 其他配置保持不变 } - 手动创建
cypress/reports目录,确保目录存在。
3. 移除冲突的钩子配置
你手动添加的before:run和after:run钩子会与cypress-mochawesome-reporter的默认钩子冲突,直接删除以下代码块:
on('before:run', async (details) => { console.log('override before:run'); await beforeRunHook(details); }); on('after:run', async () => { console.log('override after:run'); await afterRunHook(); });
4. 统一Cucumber支持导入位置
将cypress-mochawesome-reporter/cucumberSupport直接导入到e2e.ts中,确保加载顺序正确:
// 在e2e.ts顶部添加 import 'cypress-mochawesome-reporter/cucumberSupport';
5. 确认测试运行方式
- 使用命令行运行测试:
npx cypress run,GUI模式下部分报告器功能可能受限。 - 检查运行日志,查看是否有报告生成相关的错误提示。
6. 更新依赖版本
执行命令更新cypress-mochawesome-reporter到最新版本,确保与Cypress 13.x的兼容性:
npm update cypress-mochawesome-reporter --save-dev
内容的提问来源于stack exchange,提问作者Ali Taha
相关产品推荐
相关产品推荐

