Generate multiple mocha reports in a single mocha execution.
npx @tessl/cli install tessl/npm-cypress--multi--reporters@2.0.0Cypress Multi Reporters is a Mocha reporter that enables multiple report formats to be generated in a single test execution. It allows you to combine different reporters like spec, JSON, XML, TAP, and custom reporters simultaneously, providing flexibility for different stakeholders who require different report formats from the same test suite.
npm install --save-dev cypress-multi-reportersconst MultiReporters = require("cypress-multi-reporters");# With default configuration
mocha --reporter cypress-multi-reporters
# With custom configuration file
mocha --reporter cypress-multi-reporters --reporter-options configFile=config.jsonconst Mocha = require('mocha');
const mocha = new Mocha({
reporter: "cypress-multi-reporters",
reporterOptions: {
reporterEnabled: "spec,json,xunit",
jsonReporterOptions: {
output: "results.json"
},
xunitReporterOptions: {
output: "xunit.xml"
}
}
});
mocha.addFile('test/sample.test.js');
mocha.run();// cypress.config.js
const { defineConfig } = require('cypress');
module.exports = defineConfig({
e2e: {
reporter: 'cypress-multi-reporters',
reporterOptions: {
configFile: 'reporter-config.json'
}
}
});Cypress Multi Reporters works as a meta-reporter that:
The main class that implements the multi-reporter functionality.
/**
* Multi-reporter class that coordinates multiple Mocha reporters
* @param {Object} runner - Mocha test runner instance
* @param {Object} options - Configuration options
*/
function MultiReporters(runner, options) {}/**
* Merges default, custom, and dynamic options into resultant configuration
* @param {Object} options - Input options object
* @returns {Object} Merged configuration options
*/
MultiReporters.prototype.getOptions = function(options) {}/**
* Loads custom configuration from JSON/JS file or directly from options
* @param {Object} options - Input options object containing configFile reference
* @returns {Object} Custom configuration from file or reporterOptions
*/
MultiReporters.prototype.getCustomOptions = function(options) {}/**
* Loads and parses default configuration from CONFIG_FILE
* @returns {Object} Default configuration options
*/
MultiReporters.prototype.getDefaultOptions = function() {}/**
* Extracts and processes configuration options for a specific reporter
* @param {Object} options - Global options object
* @param {string} name - Name of the specific reporter
* @returns {Object} Reporter-specific configuration options
*/
MultiReporters.prototype.getReporterOptions = function(options, name) {}/**
* Coordinates completion of all enabled reporters with done handlers
* @param {number} failures - Number of test failures
* @param {Function} fn - Callback function to execute after all reporters are done
*/
MultiReporters.prototype.done = function(failures, fn) {}/**
* Default configuration file path
* @type {string}
*/
MultiReporters.CONFIG_FILE = '../config.json';{
"reporterEnabled": "spec,json,xunit",
"reporterOptions": {
"id": "default"
},
"jsonReporterOptions": {
"output": "results.json"
},
"xunitReporterOptions": {
"output": "xunit.xml"
}
}Configuration options for each reporter follow the pattern: {camelCasedReporterName}ReporterOptions
{
"reporterEnabled": "@my-org/custom-reporter,mocha-junit-reporter",
"myOrgCustomReporterReporterOptions": {
"output": "custom-report.json"
},
"mochaJunitReporterReporterOptions": {
"mochaFile": "junit.xml"
}
}// reporter-config.js
const locale = process.env.SITE_LOCALE || 'US';
module.exports = {
"reporterEnabled": "mochawesome,mocha-junit-reporter",
"mochawesomeReporterOptions": {
"reportDir": `.reports/${locale}`
},
"mochaJunitReporterReporterOptions": {
"mochaFile": `./junit/${locale}/results.xml`
}
};Dynamic output file replacement mechanism for parameterized test runs.
{
"reporterEnabled": "json,xunit",
"jsonReporterOptions": {
"output": "results-{id}.json"
},
"xunitReporterOptions": {
"output": "xunit-{id}.xml"
}
}Command line usage:
mocha --reporter cypress-multi-reporters --reporter-options configFile=config.json,cmrOutput=json+output+testSuite1This replaces {id} placeholders with testSuite1 in the JSON reporter output path.
The package automatically detects and loads built-in Mocha reporters:
Support for npm packages and local reporter files:
{
"reporterEnabled": "mocha-junit-reporter,@my-org/custom,./local-reporter.js"
}mocha.reporters[name]require(name)require(path.resolve(process.cwd(), name))"reporter_name" reporter not found when reporters cannot be found or loaded"reporter_name" reporter blew up with error: followed by stack trace for reporter initialization failuresUnable to invoke fn(failures) - no reporters were registered if no reporters load successfully.js configuration files with dynamic logic and environment variablesCouldn't determine Mocha version if version detection failsHandles npm scoped packages with automatic option key transformation:
// Reporter: @angular/testing-reporter
// Options key: angularTestingReporterReporterOptions
{
"reporterEnabled": "@angular/testing-reporter",
"angularTestingReporterReporterOptions": {
"output": "angular-results.json"
}
}mocha/lib/stats-collector for enhanced statisticsJavaScript configuration files enable environment-specific setups:
module.exports = {
"reporterEnabled": process.env.CI ? "json,junit" : "spec",
"jsonReporterOptions": {
"output": `./reports/${process.env.BUILD_NUMBER || 'local'}/results.json`
}
};interface ReporterOptions {
/** Comma-separated list or array of enabled reporters */
reporterEnabled: string | string[];
/** Custom configuration file path (JSON or JS) */
configFile?: string;
/** Dynamic output replacement specification */
cmrOutput?: string | string[];
/** Global options applied to all reporters */
reporterOptions?: Record<string, any>;
/** Skip reporter execution (for testing) */
execute?: boolean;
}
interface ReporterConfig {
reporterEnabled: string;
reporterOptions: Record<string, any>;
[reporterName: string]: any;
}
interface DynamicOutputSpec {
/** Target reporter name */
reporter: string;
/** Property to replace */
property: string;
/** Replacement value */
value: string;
}{
"reporterEnabled": "spec,mocha-junit-reporter,json",
"mochaJunitReporterReporterOptions": {
"mochaFile": "./test-results/junit.xml"
},
"jsonReporterOptions": {
"output": "./test-results/results.json"
}
}#!/bin/bash
for env in dev staging prod; do
export TEST_ENV=$env
mocha --reporter cypress-multi-reporters --reporter-options configFile=multi-env-config.js
done{
"reporterEnabled": "spec,./custom-slack-reporter.js",
"customSlackReporterReporterOptions": {
"webhook": "https://hooks.slack.com/...",
"channel": "#test-results"
}
}