Back to Rocket Chat

Code Coverage

docs/coverage.md

8.4.04.6 KB
Original Source

Code Coverage

This document explains how code coverage instrumentation works in Rocket.Chat's build and CI pipeline.

Overview

Coverage is collected during E2E test runs (API, UI, Livechat) to measure how much of the server-side code is exercised by tests. The instrumentation uses Istanbul-compatible tooling, which injects counters (__coverage__) into the compiled code at build time.

Architecture

The coverage pipeline has three components:

  1. Build-time instrumentation - injects coverage counters into the code during Meteor build
  2. Runtime collection - the rocketchat:coverage Meteor package collects __coverage__ data on process exit
  3. CI reporting - test workflows merge coverage data and upload reports
Build (SWC + plugin)  -->  Run tests  -->  Process exit triggers report  -->  Merge & upload

Build-time instrumentation

Modern build stack (SWC)

Rocket.Chat uses Meteor's modern build stack with SWC as the transpiler. For coverage builds, the swc-plugin-coverage-instrument plugin is injected into .swcrc at build time.

This is configured in .github/actions/meteor-build/action.yml:

yaml
env:
  BABEL_ENV: ${{ inputs.type }}  # "production" or "coverage"

When BABEL_ENV=coverage, the build script:

  1. Adds rocketchat:coverage to .meteor/packages
  2. Injects swc-plugin-coverage-instrument into .swcrc via a node script:
js
const swcrc = JSON.parse(fs.readFileSync('./apps/meteor/.swcrc', 'utf8'));
swcrc.jsc.experimental = swcrc.jsc.experimental || {};
swcrc.jsc.experimental.plugins = swcrc.jsc.experimental.plugins || [];
swcrc.jsc.experimental.plugins.push(['swc-plugin-coverage-instrument', {}]);
fs.writeFileSync('./apps/meteor/.swcrc', JSON.stringify(swcrc, null, 2) + '\n');

This approach ensures the same build pipeline (SWC) is used for both regular and coverage builds, avoiding behavioral differences between build modes.

Legacy build stack (Babel)

Before the modern build stack, coverage was handled via babel-plugin-istanbul configured in .babelrc:

json
{
  "env": {
    "coverage": {
      "plugins": [
        ["istanbul", { "exclude": ["**/*.spec.js", "**/*.test.js"] }]
      ]
    }
  }
}

This section is still present in .babelrc as a fallback for files that fall back to Babel compilation (e.g., SWC-incompatible code).

Runtime collection: rocketchat:coverage

The rocketchat:coverage Meteor package (apps/meteor/packages/rocketchat-coverage/) is only added to the build during coverage runs. It:

  1. Registers a process.on('exit') handler
  2. Reads globalThis['__coverage__'] (populated by the instrumentation)
  3. Generates a coverage report using istanbul-lib-coverage and istanbul-reports

Configuration via environment variables:

VariableDescriptionExample
COVERAGE_DIROutput directory for reports/tmp/coverage/api
COVERAGE_FILE_NAMEReport filenameapi-1.json
COVERAGE_REPORTERIstanbul reporter formatjson, lcov

CI workflow

Coverage is collected in the ci-test-e2e.yml workflow:

  1. Build: meteor-build action runs with type: coverage, producing a Docker image with instrumented code
  2. Test: E2E tests run against the instrumented server. On each test shard:
    • COVERAGE_DIR, COVERAGE_FILE_NAME, and COVERAGE_REPORTER are set
    • When the Rocket.Chat process exits after tests, the coverage plugin writes a JSON report
  3. Merge: nyc merge combines per-shard JSON reports into a single coverage file
  4. Upload: Coverage data is uploaded to Codecov

Local development

To build with coverage locally:

bash
cd apps/meteor

# Inject the SWC coverage plugin into .swcrc
node -e "
  const fs = require('fs');
  const swcrc = JSON.parse(fs.readFileSync('.swcrc', 'utf8'));
  swcrc.jsc.experimental = { plugins: [['swc-plugin-coverage-instrument', {}]] };
  fs.writeFileSync('.swcrc', JSON.stringify(swcrc, null, 2));
"

# Add the coverage package
echo -e "rocketchat:coverage\n" >> .meteor/packages

# Set env vars and run
COVERAGE_DIR=/tmp/coverage COVERAGE_FILE_NAME=local.json COVERAGE_REPORTER=lcov yarn dev

Remember to restore .swcrc and .meteor/packages after testing.

Dependencies

PackagePurpose
swc-plugin-coverage-instrumentSWC plugin for Istanbul-compatible instrumentation
istanbul-lib-coverageCoverage map creation (used by rocketchat:coverage)
istanbul-lib-reportReport context creation
istanbul-reportsReport formatters (json, lcov, etc.)