Using the output

Report tour

Five pages, one file. This is what each one is for, what the numbers mean, and what to do when they're bad. Every screenshot here is SpecTracer's own self-report — real numbers, not a mockup.

Live sample report

See the real thing — no setup required. Click below to open a fresh tab with SpecTracer's actual HTML output from this repo, showing all six pages. It's exactly what you'll get after running the tool on your own project.

Open live report in a new tab

The file itself

The report is a single self-contained HTML file. All CSS and JavaScript are inlined, and the data is rendered into the markup server-side rather than shipped as a JSON payload. The one network request is a monospace webfont from a CDN, which degrades to the system monospace if you're offline.

1 · Overview

The page that answers "how are we doing" in about three seconds.

The Overview page: three headline tiles reading 25/44 declared tests matched, 7/25 scenarios fully matched, 220/220 tests passed; below them four health-check cards for Progress, Test pyramid, E2E runtime, and Unlinked.
Overview — headline coverage plus the four health signals.

The three headline tiles

TileNumerator / denominatorRead it as
Declared tests matched Satisfied @require-* layer/module pairs, over all declared pairs. "How much of the coverage we said we needed do we actually have?" This is the headline metric and the one fail_on: ["progress"] gates on.
Scenarios fully matched Scenarios with every declared layer satisfied, over all scenarios. Strictly harder. A scenario needing three layers and having two contributes 2/3 to the first tile but 0 to this one.
Tests passed Passing results over all collected results. Plain suite health. Counts every result, linked or not.
Why the two coverage numbers differ so much In the screenshot above, 57% of declared tests are matched but only 28% of scenarios are fully matched. That gap is the normal shape of a partially-tagged codebase: coverage is spread thinly across many scenarios rather than completed on a few. Watch the gap close as you finish scenarios rather than start them.

The four health cards

Each card is green, amber, or red, and links through to the page that explains it. Thresholds come from health_checks in your config — see Health checks.

Progress amber

Declared-tests-matched percentage against your green/amber thresholds. Amber means "below target but not alarming"; red means below the amber floor.

Test pyramid green

Green while unit tests outnumber integration + E2E combined. Amber at exact parity, red when inverted.

E2E runtime green

Total E2E wall time against your time budget. This is the check that catches a suite getting slowly, invisibly slower.

Unlinked red

Orphaned results. Green at zero, amber at 1–3, red at 4 or more. Visual only — this one cannot gate CI.

2 · Test Pyramid

Test count, duration, and pass rate for each layer, drawn as proportional bars.

The Test Pyramid page: three horizontal bars for E2E (53 tests, 4.9s), Integration (42 tests, 4.4s), and Unit (125 tests, 556ms), each with pass, fail, and skip percentages.
Test Pyramid — execution mix across unit, integration, and E2E.

The shape is the point. A healthy pyramid has a long unit bar and short integration and E2E bars. What to look for:

Counts, not opinions The pyramid reflects what you registered under unit, integration, and e2e in the config. If your "unit" tests spin up a database, SpecTracer will happily report a beautiful pyramid — it can only classify what you tell it.

3 · Feature Breakdown

The traceability matrix, and where you'll spend most of your time. A searchable tree: feature → scenario → individual test result.

The Feature Breakdown page: an expandable tree of features with completion bars and result pills; one scenario expanded to show required-layer chips, the full Gherkin steps, and the individual E2E and unit results that linked to it.
Feature Breakdown — one scenario expanded to show requirements, Gherkin text, and linked results.

Row by row

ColumnWhat it shows
NameFeature or scenario name. Scenario rows also carry the scenario id pill (e.g. FC-006) and, on result rows, the discovery module.
CompletionA bar and a satisfied/declared fraction — green at 100%, amber below.
ResultRolled-up pass/fail/skip status.
DeclaredHow many @require-* pairs this row declares.
ActualHow many test results actually linked. This can exceed Declared — three unit tests can link to a scenario that declares one unit requirement.
DurationSummed wall time of the linked results.

Expanding a scenario

Expanding a scenario row reveals three things:

  1. Required-layer chips — one per declared requirement, showing the layer, the module in parentheses, and OK or MISSING. This is the single most actionable thing in the report: INTEGRATION (renderers) MISSING tells you precisely what to go write.
  2. The full Gherkin text — the Given/When/Then as written, so a reader who isn't in the code can still judge whether the scenario is worth the coverage it's demanding.
  3. The linked results — every test that claimed this scenario, with its layer, module, status, and duration.

Search filters the tree by name. Failure stack traces are deliberately not here — they live on the Failure Breakdown page so this view stays scannable.

4 · Failure Breakdown

Every failed test across all three layers, in one list, with feature and scenario context and the full stack trace on expand.

The value is not that it shows failures — your CI log does that. It's that a failure here arrives attached to the business scenario it broke, across layers that normally live in separate jobs. "Three failures, all under checkout" is a different triage conversation than three unrelated red lines in three log files.

5 · Unlinked Tests

Test results that carry tags but whose @scenario: values matched no scenario's @id:.

This page is your typo detector. On a first run, a large unlinked count and a near-zero coverage number almost always mean the same thing: the tags on one side don't match the tags on the other. Common causes:

Unlinked results still count toward the pyramid and the pass-rate tile — they ran, after all. They just don't count toward coverage.

The JSON twin

Set output_json and the same data is written as schema-validated JSON alongside the HTML. It's built from the same internal model as the HTML renderer, so the two physically cannot disagree.

reading the headline number in CI
jq -r '.summary.completion.percent' reports/spectracer-report.json
jq -r '.summary.health.status'       reports/spectracer-report.json
jq -r '.summary.health.reasons[]'    reports/spectracer-report.json

Use it for PR bots, custom gates the built-in checks don't cover, or posting trends to your own dashboard. Full field reference: Configuration → JSON report.

Using it in a standup

The headline numbers are designed to be said out loud. Unlike line coverage, they mean something to people who don't read code:

Track that trend properly by posting summary from the JSON report to whatever metrics system you already run — see Historical trends.