Skip to main content
Code coverage shows how much of your application code runs during tests. TestDino collects coverage from your Playwright tests, merges data across shards, and displays a per-file breakdown on the dashboard.

Quick Reference

TopicLink
Coverage metricsStatements, branches, functions, lines
Instrument your appbabel-plugin-istanbul, nyc, vite-plugin-istanbul
Enable coverageCLI flags and reporter config
Coverage fixtureAuto-fixture and manual fixture
Sharded runsMerge coverage across CI shards
Data handlingWhat gets uploaded and stored
TroubleshootingCommon issues and fixes

Coverage Metrics

TestDino tracks four standard coverage metrics:
MetricWhat it measures
StatementsHow many individual code statements ran
BranchesHow many if/else paths were taken (both the true and false side)
FunctionsHow many functions were called at least once
LinesHow many source lines ran

Prerequisites

  • @testdino/playwright installed (CLI reference)
  • TestDino API token (generate one)
  • Your application instrumented with Istanbul so window.__coverage__ is available in the browser

Instrument Your Application

Instrumentation adds small tracking counters around every statement, branch, and function in your code. When your app runs, these counters record what was executed. The result is stored in a global window.__coverage__ object that TestDino reads after each test.
Instrumented builds are for testing only. Never deploy them to production. Instrumentation slows performance by 10-30%, increases bundle size by 2-3x, and exposes your source code file structure.
Pick the method that matches your build tool:
Best for React apps using Babel (Create React App, Next.js with Babel, etc.).Install the plugin:
npm install -D babel-plugin-istanbul
Add it to your Babel config so it only runs during test builds:
babel.config.json
{
  "env": {
    "test": {
      "plugins": ["istanbul"]
    }
  }
}
Build with instrumentation enabled:
NODE_ENV=test npm run build
Only use instrumented builds for test environments. All other environments should use regular builds.
EnvironmentBuild TypeNODE_ENVPurpose
DevelopmentRegulardevelopmentLocal development
Testing / QAInstrumentedtestE2E tests with coverage
StagingRegularproductionPre-production validation
ProductionRegularproductionLive users

Enable Coverage

There are two ways to enable coverage: CLI flags or reporter config. Both produce the same result.

CLI Flags

Pass coverage flags directly to tdpw test:
npx tdpw test --coverage
Generate a local HTML report alongside the dashboard upload:
npx tdpw test --coverage --coverage-report --coverage-report-dir=./coverage-report
FlagDescription
--coverageEnable coverage collection
--coverage-reportGenerate a local Istanbul HTML report
--coverage-report-dirOutput directory for the local report (default: ./coverage)
CLI flags override reporter config options. See the Node.js CLI reference for all available flags.

Reporter Config

Add the coverage option to the @testdino/playwright reporter in your Playwright config:
playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
  reporter: [
    ['list'],
    ['@testdino/playwright', {
      token: process.env.TESTDINO_TOKEN,
      coverage: {
        enabled: true,
        localReport: true,
        localReportDir: './coverage-report',
      },
    }],
  ],
  projects: [
    { name: 'chromium', use: { browserName: 'chromium' } },
    { name: 'firefox', use: { browserName: 'firefox' } },
    { name: 'webkit', use: { browserName: 'webkit' } },
  ],
  use: {
    baseURL: 'http://localhost:3000',
  },
});

Coverage Options

OptionTypeDefaultDescription
enabledbooleanfalseTurn on coverage collection
localReportbooleanfalseGenerate a local Istanbul HTML report
localReportDirstring./coverageOutput directory for the local report

Use the Coverage Fixture

The fixture is the piece that reads window.__coverage__ from the browser after each test finishes. The reporter then merges all the collected data and sends it to TestDino.

Run Tests

1

Start the instrumented application

Run your app using the instrumented test build:
NODE_ENV=test npm start
2

Set your API token

export TESTDINO_TOKEN="your-api-token"
3

Run Playwright tests

npx playwright test
4

Review results

After tests complete, the console prints a coverage summary table.If localReport is enabled, open ./coverage-report/index.html for the full Istanbul HTML report.Open the test run in TestDino and select the Coverage tab to see overall metrics and a per-file breakdown.

Sharded Runs

When you split tests across multiple CI shards, each shard collects coverage only for the tests it runs. TestDino merges all shard data into one combined report. Step 1: Set a CI run ID so all shards group into one test run:
export TESTDINO_CI_RUN_ID=$CI_PIPELINE_ID
Step 2: Run each shard:
npx playwright test --shard=1/3
npx playwright test --shard=2/3
npx playwright test --shard=3/3
How merging works: The server takes the union of covered lines from every shard. If shard 1 covers lines 1-50 of auth.ts and shard 2 covers lines 30-80, the merged report shows lines 1-80 as covered.

Example CI Workflow

.github/workflows/coverage.yml
name: Playwright Coverage
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        shard: [1/3, 2/3, 3/3]
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm ci

      - name: Install Playwright
        run: npx playwright install --with-deps

      - name: Build for coverage
        run: NODE_ENV=test npm run build

      - name: Run tests
        env:
          TESTDINO_TOKEN: ${{ secrets.TESTDINO_TOKEN }}
        run: npx playwright test --shard=${{ matrix.shard }}

Data Handling

TestDino uploads only coverage metrics (percentages and hit counts per file). No source code, raw coverage maps, or window.__coverage__ payloads are stored on the server.
DataStored on serverPurpose
Per-run summary (statements, branches, functions, lines)YesDashboard summary tiles
Per-file metrics (path, percentages, hit counts)YesFile-by-file breakdown and trends
Source codeNoNever leaves your machine
Raw Istanbul coverage mapsNoProcessed locally, then discarded
When window.__coverage__ is not present in the browser, the reporter skips coverage collection and proceeds normally. Tests run without any performance impact.

Troubleshooting

Open your app in the browser and type window.__coverage__ in the DevTools console. If it returns undefined, your app is not instrumented.Check that:
  • Your build command uses NODE_ENV=test or VITE_COVERAGE=true
  • coverage.enabled is set to true in the reporter config
  • Your test files import test from @testdino/playwright (not @playwright/test)
This is expected when coverage.projects is set to a single browser (for example, ['chromium']). To collect coverage from all browsers, remove the projects option.
Only files that run during tests appear in the report. If a file shows 0% or is missing, no test triggered the code path that imports it.To include all source files (even untouched ones), configure your Istanbul tool’s include/exclude settings to cover the full source directory.
This is normal. Branch coverage counts both sides of every if/else. If your tests only exercise one side (for example, the success path but not the error path), branch coverage drops while line coverage stays higher.
Enable debug logging to see what the reporter collects:
['@testdino/playwright', {
  token: process.env.TESTDINO_TOKEN,
  debug: true,
  coverage: { enabled: true },
}]
Check the console for messages prefixed with [TestDino].
Set up coverage, view per-run reports, and configure CI.