Help Center/Automation & CI/CD/Your test framework

Cypress Test Reports: Mochawesome, JUnit, and Uploading to TestCollab

Generate Cypress test reports as Mochawesome JSON or JUnit XML, map case IDs, and upload automated results to TestCollab.

Cypress uses Mocha reporters and can produce several kinds of test report. TestCollab reads Mochawesome JSON and JUnit XML, so you can choose the format that already fits your pipeline and upload it with @testcollab/cli.

For CLI installation and test-plan setup, see TestCollab CLI: Install and First Run.

Prerequisites

  • A project that already runs tests with Cypress.
  • A TestCollab project and a test plan containing the automated cases.
  • A TestCollab API token set as TESTCOLLAB_TOKEN.
  • Each Cypress test title marked with its TestCollab case ID, such as [TC-42].

Choose a Cypress test reporter

Reporter Output TestCollab format Use when
spec Terminal text Not uploadable You only need readable local output
mochawesome JSON and optional HTML mochawesome You want rich Mocha result details with the shortest TestCollab path
mocha-junit-reporter JUnit XML junit Your CI system and other tools already standardize on JUnit

Cypress runs each spec separately. When a reporter writes one file per spec, merge the files before passing the final report to tc report.

Path A: Generate Mochawesome JSON

TestCollab reads Mochawesome JSON natively. Install the reporter and its merge utility:

npm install --save-dev mochawesome mochawesome-merge

Configure Cypress to write JSON without generating an HTML report:

// cypress.config.js
const { defineConfig } = require('cypress');

module.exports = defineConfig({
  reporter: 'mochawesome',
  reporterOptions: {
    reportDir: 'cypress/results',
    overwrite: false,
    html: false,
    json: true
  }
});

Run Cypress, merge all per-spec JSON files, and upload the merged report:

npx cypress run

mkdir -p artifacts
npx mochawesome-merge "cypress/results/*.json" \
  -o artifacts/mochawesome.json

npx @testcollab/cli report \
  --project 123 \
  --test-plan-id 456 \
  --format mochawesome \
  --result-file ./artifacts/mochawesome.json

Use a clean results directory for each CI job. With overwrite: false, stale JSON from a reused workspace would otherwise be included in the merge.

Path B: Generate JUnit XML

Install mocha-junit-reporter and a JUnit merge utility:

npm install --save-dev mocha-junit-reporter junit-report-merger

Use [hash] in the filename so Cypress does not overwrite the previous spec's XML:

// cypress.config.js
const { defineConfig } = require('cypress');

module.exports = defineConfig({
  reporter: 'mocha-junit-reporter',
  reporterOptions: {
    mochaFile: 'cypress/results/junit-[hash].xml',
    toConsole: true
  }
});

Run Cypress, merge the per-spec files, and upload the combined JUnit report:

npx cypress run

npx jrm \
  ./cypress/results/junit.xml \
  "./cypress/results/junit-*.xml"

npx @testcollab/cli report \
  --project 123 \
  --test-plan-id 456 \
  --format junit \
  --result-file ./cypress/results/junit.xml

A static mochaFile would retain only the last spec in a multi-spec run. The hash plus merge step preserves every suite.

Map Cypress tests with [TC-42] markers

Put the TestCollab test case ID in the individual it title. Both the Mochawesome and JUnit paths preserve it.

describe('Checkout', () => {
  it('[TC-42] customer completes checkout', () => {
    cy.visit('/checkout');
    cy.get('[data-testid="place-order"]').click();
    cy.contains('Order confirmed').should('be.visible');
  });
});

The CLI recognizes [TC-42], TC-42, id-42, and testcase-42, case-insensitively. The number must be a test case ID for a case in the target plan.

Complete GitHub Actions workflow

This example uses Mochawesome JSON. It creates the TestCollab plan first, runs Cypress, merges the per-spec reports even after a failed assertion, and uploads the merged result. Add TESTCOLLAB_TOKEN as a repository secret and the numeric IDs as repository variables.

name: Cypress tests

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    env:
      TESTCOLLAB_TOKEN: ${{ secrets.TESTCOLLAB_TOKEN }}
      TC_PROJECT_ID: ${{ vars.TC_PROJECT_ID }}
      TC_CI_TAG_ID: ${{ vars.TC_CI_TAG_ID }}
      TC_ASSIGNEE_ID: ${{ vars.TC_ASSIGNEE_ID }}
    steps:
      - name: Check out repository
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Create TestCollab test plan
        run: |
          npx @testcollab/cli createTestPlan \
            --project "$TC_PROJECT_ID" \
            --ci-tag-id "$TC_CI_TAG_ID" \
            --assignee-id "$TC_ASSIGNEE_ID"

      - name: Run Cypress
        run: npx cypress run

      - name: Merge Mochawesome reports
        if: always()
        run: |
          mkdir -p artifacts
          npx mochawesome-merge "cypress/results/*.json" \
            -o artifacts/mochawesome.json

      - name: Upload Cypress results to TestCollab
        if: always()
        run: |
          source tmp/tc_test_plan
          npx @testcollab/cli report \
            --project "$TC_PROJECT_ID" \
            --test-plan-id "$TESTCOLLAB_TEST_PLAN_ID" \
            --format mochawesome \
            --result-file ./artifacts/mochawesome.json

The failed Cypress step still controls the job result. The later always() steps preserve and upload its test evidence.

Use the EU region

Add the EU API URL to every TestCollab CLI command when your account is hosted in the EU region:

--api-url https://api-eu.testcollab.io

Migrate from the legacy Cypress plugin

The current integration uses a standard Cypress reporter plus an explicit tc report step. It does not require testcollab-cypress-plugin or a TestCollab-specific Cypress hook.

  1. Remove the legacy plugin dependency and its setup code.
  2. Choose Mochawesome JSON or JUnit XML and configure the corresponding reporter.
  3. Store authentication in TESTCOLLAB_TOKEN.
  4. Run tc report after the reporter files have been merged.

If you must maintain an older project during the transition, see Cypress Reporter Plugin (legacy).

Troubleshooting

Only the last Cypress spec appears

Use overwrite: false for Mochawesome or [hash] in the JUnit filename, then merge the per-spec reports. A single static filename is overwritten during a multi-spec Cypress run.

The merge never runs after a failed test

Run Cypress and the merge as separate CI steps. Put if: always() on both the merge and TestCollab upload steps.

No TestCollab cases are updated

Inspect the merged JSON or XML and verify each test name contains the intended [TC-42] marker. Confirm those cases are included in the target test plan and assigned to the token owner.

The CLI reports invalid Mochawesome JSON

Pass the merged JSON file, not Mochawesome HTML and not an individual file from an incomplete run. Check that the payload contains a non-empty results array.

Last updated 2026-08-26.