Skip to main content

HTML Reporter

The @serenity-js/html-reporter module produces a self-contained HTML report from your Serenity/JS test suite — open index.html directly from the filesystem with no server, no Java, and no external dependencies.

Dashboard view of the Serenity/JS HTML Report

Key features

  • Trend history across CI runs — the report preserves execution data across builds, showing pass rate and duration trends over time. Spot regressions the moment they appear, not after they've been hiding for days.
  • Flaky test detection — automatically classifies tests as flaky, degraded, inconsistent, or recovered based on outcome patterns across recent runs.
  • Single self-contained HTML file — all JavaScript, CSS, and chart logic embedded inline. Test data is loaded from a companion data.js file. Open directly from the filesystem, deploy to any static host. No server required.
  • Activity trees with evidence — every Task, Interaction, and assertion shown with timing, screenshots, HTTP exchanges, and video.
  • Error clustering — groups failures by normalised root cause so you see 1 bug with 12 affected tests, not 12 unrelated failures.
  • Living documentationREADME.md files render alongside test results in the Capabilities view, turning your test directory into navigable documentation.
  • Deep linking — every view state (filters, search, sort, selected scenario) is encoded in the URL hash. Share a link to take someone directly to a specific failure.
  • Dark and light themes — respects prefers-color-scheme with a manual toggle; preference persisted in localStorage.
  • Incomplete run detection — detects crashed CI runners and surfaces them with ⚠️ indicators, preventing "false green" results.
  • No Java required — pure Node.js. No JRE download, no .jar files, no classpath issues.
Works with and without the Screenplay Pattern

Trend analysis, flaky test detection, error clustering, and the dashboard KPIs work for all Serenity/JS test suites — including those that haven't adopted the Screenplay Pattern yet. Activity trees, screenshots, and REST exchange panels are available for scenarios that use Screenplay Pattern interactions.

Progressive adoption

You don't need to rewrite your test suite to benefit from the HTML Reporter. Serenity/JS is designed for incremental adoption:

  1. Start with reporting — add the test runner adapter and the HTML Reporter. Your existing tests gain trend tracking, flaky test detection, and a dashboard immediately.
  2. Introduce Screenplay for critical workflows — when you write new tests or refactor high-value scenarios, use Tasks and Interactions. The report shows richer activity trees and evidence for those tests automatically.
  3. Expand gradually — adopt Screenplay at your own pace. Tests with and without it coexist in the same report, the same suite, and the same CI pipeline.

Overview

@serenity-js/html-reporter is a stage crew member that:

  • Collects test execution data, screenshots, and HTTP exchanges during your test run
  • Produces a static HTML report with interactive dashboard, scenario details, and trend history
  • Supports multi-run CI workflows where each job archives data independently, and a final step aggregates everything into one report

The report includes seven views:

ViewPurpose
DashboardKPI cards (pass rate, consistency, confidence), trend chart, consistency highlights
Test ScenariosSearchable, filterable list of all scenarios with outcome, duration, and tags
CapabilitiesRequirements hierarchy tree with health indicators and README rendering
ErrorsError clustering — groups failures by root cause
ConsistencyIdentifies flaky, degraded, and recovered tests across recent runs
TimelineExecution timeline showing parallelism and timing
TagsBrowse scenarios by tag (feature, issue, module, custom)
Live example

See the Serenity/JS HTML Report generated from the framework's own integration test suite.

Installation

Install the module along with @serenity-js/core as development dependencies:

npm install --save-dev @serenity-js/core @serenity-js/web @serenity-js/html-reporter
Screenshots

@serenity-js/web is optional but recommended — it enables Photographer to capture screenshots that the HTML Reporter embeds in the report.

Configuration

The HTML Reporter follows the same crew member configuration pattern as all other Serenity/JS reporters. You add it to the crew array in your test runner configuration.

Playwright Test

playwright.config.ts
import { defineConfig } from '@playwright/test';
import type { SerenityFixtures, SerenityWorkerFixtures } from '@serenity-js/playwright-test';

export default defineConfig<SerenityFixtures, SerenityWorkerFixtures>({
testDir: './spec',

reporter: [
['line'],
['@serenity-js/playwright-test', {
crew: [
['@serenity-js/html-reporter', {
outputDirectory: './reports/serenity-js',
specDirectory: './spec', // same as testDir
}],
]
}]
],
});

Learn more about using Serenity/JS with Playwright Test.

WebdriverIO

wdio.conf.ts
import type { WebdriverIOConfig } from '@serenity-js/webdriverio';

export const config: WebdriverIOConfig = {
framework: '@serenity-js/webdriverio',

serenity: {
runner: 'mocha',
crew: [
['@serenity-js/html-reporter', {
outputDirectory: './reports/serenity-js',
specDirectory: './test/specs', // root of your specs directory
}],
]
},

specs: ['./test/specs/**/*.spec.ts'],
};

Learn more about using Serenity/JS with WebdriverIO.

Cucumber

features/support/serenity.config.ts
import { configure } from '@serenity-js/core';

configure({
crew: [
['@serenity-js/html-reporter', {
outputDirectory: './reports/serenity-js',
specDirectory: './features', // root of your .feature files
}],
],
});

Call this in a BeforeAll hook. Learn more about using Serenity/JS with Cucumber.

Mocha

spec/support/serenity.config.ts
import { configure } from '@serenity-js/core';

configure({
crew: [
['@serenity-js/html-reporter', {
outputDirectory: './reports/serenity-js',
specDirectory: './spec', // root of your .spec.ts files
}],
],
});

Require this file via your .mocharc.yml configuration. Learn more about using Serenity/JS with Mocha.

Jasmine

spec/helpers/serenity.config.ts
import { configure } from '@serenity-js/core';

configure({
crew: [
['@serenity-js/html-reporter', {
outputDirectory: './reports/serenity-js',
specDirectory: './spec', // root of your spec files
}],
],
});

Configure Jasmine to load this file via the helpers option in spec/support/jasmine.json. Learn more about using Serenity/JS with Jasmine.

Configuration options

All options are optional. See the HtmlReporterConfig API reference for full details.

OptionTypeDefaultDescription
outputDirectorystring'./reports/serenity-js'Directory for the generated report and test run data
specDirectorystringauto-detectedRoot directory for the requirements hierarchy (enables the Capabilities view)
titlestringproject nameCustom title displayed in the report header
maxHistorynumberunlimitedMaximum test runs to retain; older runs are pruned during aggregation
consistencyWindownumber5Number of recent runs used to classify flaky, degraded, and recovered tests
projectNamestringfrom package.jsonCustom project name displayed in the report
testRunIdstringauto-detectedIdentifier for the test run directory; auto-detects from CI environment variables (GITHUB_RUN_NUMBER, CI_PIPELINE_IID, BUILD_NUMBER, CIRCLE_BUILD_NUM)
moduleIdstringauto-detectedIdentifier for the CI job shard; defaults to working directory name when a CI build number is detected
ciobjectauto-detectedOverride CI/CD context (provider, buildNumber, branch, commit, commitMessage, commitAuthor, jobUrl, repositoryUrl)
consistencyWindow is capped by maxHistory

If you set consistencyWindow: 10 but maxHistory: 5, the reporter uses the 5 available runs for consistency analysis. Ensure maxHistory is at least as large as your desired consistencyWindow.

About specDirectory

When specDirectory is configured, the report's Capabilities view organises your scenarios into a tree that mirrors your directory structure. Directories become capabilities, and README.md files within them render as living documentation. If omitted, the Capabilities view is disabled.

Viewing the report

After your tests complete, the report is available in your configured outputDirectory (default: ./reports/serenity-js).

Open directly: Double-click reports/serenity-js/index.html in your file manager — it works from file:// URLs with no server needed.

Serve locally: Use the built-in server to view the report and share it with others on your network:

npx @serenity-js/html-reporter serve --open

The serve command defaults to ./reports/serenity-js. Use --dir to specify a different location.

Add to .gitignore: The report output should not be committed to source control:

reports/serenity-js

The requirements hierarchy

The HTML Reporter uses your test directory structure to build a requirements hierarchy — a tree of capabilities that maps directly to your filesystem layout. This powers the Capabilities view, giving stakeholders a navigable overview of what your system does and how well each area is tested.

How it works

When you set specDirectory, the reporter treats each subdirectory as a capability (a business function or feature area). Test files within a directory are grouped under that capability, and the tree reflects your nesting:

spec/
├── authentication/
│ ├── google-sign-in.spec.ts
│ ├── microsoft-sign-in.spec.ts
│ └── README.md ← rendered as living documentation
├── shopping-cart/
│ ├── item-management.spec.ts
│ ├── save-for-later.spec.ts
│ └── README.md
└── checkout/
├── payment.spec.ts
├── shipping.spec.ts
└── README.md

In the Capabilities view, this produces a tree:

  • authentication (3 scenarios, 100% passing)
    • google-sign-in
    • microsoft-sign-in
  • shopping-cart (2 scenarios, 95% passing)
    • item-management
    • save-for-later
  • checkout (2 scenarios, 100% passing)
    • payment
    • shipping

Each node shows its pass rate, confidence score, and health indicator.

Adding README files

Place a README.md file in any directory to describe that capability. The HTML Reporter renders it inline in the Capabilities view when a user selects that node in the tree.

Use README files to document:

  • What the capability does (business context)
  • Why it exists (user need or business rule)
  • Links to external documentation, design specs, or architecture diagrams
  • Known limitations or planned improvements
<!-- spec/authentication/README.md -->
# Authentication

Single sign-on integrations for corporate and social identity providers.

## Supported providers
- Google Workspace (OAuth 2.0)
- Microsoft Entra ID (SAML)
- Custom SAML/OIDC via company configuration

## Architecture
See the [authentication design doc](https://wiki.example.com/auth-design) for sequence diagrams.

README files support standard Markdown including headings, lists, code blocks, tables, and links. Relative links between README files are resolved within the report — linking to ../shopping-cart/README.md navigates to that capability in the tree.

Auto-detection

When specDirectory is not explicitly configured, Serenity/JS looks for conventional directories such as features, specs, spec, tests, test, or src in your project root. If found, the reporter uses it automatically. Set specDirectory explicitly when your spec files live in a non-standard location.

Comparison with Serenity BDD

The requirements hierarchy in the HTML Reporter works the same way as in the Serenity BDD Reporter — your directory structure defines the tree, and README.md files provide documentation. The key differences:

HTML ReporterSerenity BDD Reporter
README renderingInline in the Capabilities viewRendered in the living documentation
Health indicatorsPass rate + confidence score per nodePass/fail count per node
Tree navigationSingle-page interactive tree with expand/collapseMulti-page navigation
ConfigurationspecDirectory optionspecDirectory option + --features CLI flag

Report views

Dashboard

The Dashboard provides a 30-second answer to "Can we ship this?" — showing confidence score, pass rate, consistency, completeness, trend chart, and a summary of recently changed tests.

Dashboard with KPI cards and trend chart

Test Scenarios

A searchable, filterable list of all test scenarios. Click any scenario to see its full execution details: activity tree, screenshots, REST exchanges, and error diagnostics.

Test Scenarios view with search and outcome filters

Scenario detail

Each scenario shows its activity tree (auto-expanded to the first failure), a photo strip with lightbox, REST query panels, and execution history across recent runs.

Scenario detail showing activity tree and execution history

Capabilities

When specDirectory is configured, the Capabilities view renders your test directory structure as a requirements tree. Each node shows its health (pass rate), and README.md files render inline as living documentation.

Capabilities view with requirements hierarchy and README rendering

Errors

Groups failures by root cause using error fingerprinting. Normalises away machine-specific paths and timestamps so the same underlying bug clusters into one entry regardless of which CI runner hit it.

Errors view clustering failures by root cause

Consistency

Identifies tests whose behaviour has changed across recent runs:

ClassificationMeaning
FlakyPasses only via retry — the build goes green, but the test needed multiple attempts
InconsistentFinal outcome differs across runs — masks a deeper problem
DegradedWas passing, now consistently failing
RecoveredWas failing, now passes cleanly (no retry needed)
Consistency view identifying flaky and degraded tests

CI integration

Single-job setup

For simple CI pipelines with a single test job, the default configuration is all you need. The HtmlReporter crew member both archives the data and generates the report when the test run finishes:

.github/workflows/test.yml
- name: Run tests
run: npx playwright test

- name: Upload report
if: always()
uses: actions/upload-artifact@v4
with:
name: html-report
path: reports/serenity-js/index.html

Multi-job setup with TestRunArchiver

For parallel CI pipelines (e.g., sharded Playwright, multi-browser WebdriverIO), use TestRunArchiver in each job to archive data only, then aggregate in a final step.

Step 1: In each parallel job, use TestRunArchiver instead of the full HtmlReporter:

playwright.config.ts
reporter: [
['@serenity-js/playwright-test', {
crew: [
['@serenity-js/html-reporter:TestRunArchiver', {
outputDirectory: './reports/serenity-js',
specDirectory: './spec',
}],
]
}]
],

Each job produces a db.json file in reports/serenity-js/test-runs/<runId>/<moduleId>/.

Step 2: In a final aggregation job, combine all archived data into one report:

.github/workflows/test.yml
aggregate-report:
needs: [test-chrome, test-firefox, test-webkit]
if: always()
steps:
- uses: actions/download-artifact@v4
with:
pattern: test-run-data-*
path: reports/

- name: Aggregate report
run: |
npx @serenity-js/html-reporter aggregate \
--input "reports/*/test-runs/*" \
--output ./reports/serenity-js \
--title "My Project" \
--spec-dir ./spec \
--max-history 20

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
publish_dir: ./reports/serenity-js

CLI reference

aggregate

Aggregates test run data from multiple sources into a single HTML report.

npx @serenity-js/html-reporter aggregate \
--input "reports/*/test-runs/*" \
--output ./reports/serenity-js \
--title "My Project" \
--spec-dir ./spec \
--max-history 20 \
--consistency-window 5
OptionRequiredDefaultDescription
--inputGlob pattern(s) for directories containing db.json files (comma-separated for multiple)
--output./reports/serenity-jsOutput directory for the generated report
--titleReport title displayed in the header
--spec-dirRoot directory for the requirements hierarchy
--max-historyunlimitedMaximum test runs to keep
--consistency-window5Number of recent runs for flaky test detection

The --input option automatically resolves db.json files within matched directories. If your pattern doesn't already end with db.json or db-*, the CLI appends /**/db.json and /**/db-*.json to locate all test run data. This means --input "reports/*/test-runs/*" and --input "reports/*/test-runs/**/db.json" produce the same result — the shorter form is recommended.

Multiple input sources can be combined with commas: --input "ci-data/*/test-runs/*,local/test-runs/*".

serve

Serves the generated report on a local HTTP server.

npx @serenity-js/html-reporter serve --dir ./reports/serenity-js --open
OptionDefaultDescription
--dir./reports/serenity-jsDirectory containing the generated report
--port8080Port to listen on
--host0.0.0.0Host to bind to (accessible from other devices on the network)
--openOpen the report in the default browser

Choosing a reporter

Serenity/JS offers two HTML reporting options. Unless your project already has a dependency on Java, the HTML Reporter is typically the better choice — it's simpler to set up, requires no external tooling, and provides trend analysis that Serenity BDD doesn't offer.

HTML ReporterSerenity BDD Reporter
OutputSingle self-contained HTML fileMulti-page HTML site
DependenciesNode.js onlyRequires Java (JRE)
Living documentationREADME rendering in Capabilities viewNarrative-driven living documentation with requirements coverage
Trend historyBuilt-in trend charts across runs
CI aggregationNative CLI (aggregate command)Serenity BDD CLI (serenity-bdd run)
Offline viewingWorks from file:// URLsWorks from file:// URLs
Best forTeams wanting lightweight, zero-dependency reporting with CI trend trackingTeams already using Serenity BDD, or mixed JavaScript and Java codebases
Use both reporters

You can use both reporters simultaneously — they collect data independently and don't conflict. See Migrating from Serenity BDD Reporter for a configuration example.

Integration architecture

The HTML Reporter listens to domain events emitted by actors and test runner adapters, just like any other crew member.

The HtmlReporter composes two internal crew members:

  • TestRunArchiver — collects scene data, screenshots, and artifacts into db.json files during test execution
  • HtmlReportGenerator — aggregates db.json files and produces the final index.html when the test run finishes

For CI pipelines, you can use TestRunArchiver alone in parallel jobs, then run the CLI aggregate command in a final step to produce the report.

Migrating from Serenity BDD Reporter

If you're currently using @serenity-js/serenity-bdd, you can migrate to the HTML Reporter in stages — run both side by side first, then switch fully when you're comfortable.

Running both reporters together

Both reporters coexist in the same crew array. They write to different directories and don't conflict:

crew: [
// New HTML Reporter — generates report automatically
['@serenity-js/html-reporter', {
outputDirectory: './reports/html',
title: 'My Project',
}],

// Existing Serenity BDD Reporter
'@serenity-js/serenity-bdd',
['@serenity-js/core:ArtifactArchiver', { outputDirectory: './reports/serenity-bdd' }],
]

Try this approach first to compare reports side by side before fully migrating.

Replacing Serenity BDD entirely

Step 1: Install the HTML Reporter

npm install --save-dev @serenity-js/html-reporter

Step 2: Remove Serenity BDD packages

npm uninstall @serenity-js/serenity-bdd rimraf npm-failsafe

Keep rimraf if you use it elsewhere. Only remove npm-failsafe if the serenity-bdd run step was its sole purpose.

Step 3: Update crew configuration

Remove @serenity-js/serenity-bdd and @serenity-js/core:ArtifactArchiver from the crew array. Replace with @serenity-js/html-reporter:

 crew: [
- '@serenity-js/serenity-bdd',
- ['@serenity-js/core:ArtifactArchiver', { outputDirectory: 'target/site/serenity' }],
+ ['@serenity-js/html-reporter', {
+ outputDirectory: './reports/serenity-js',
+ title: 'My Project',
+ }],
]
Keep Photographer

If you use Photographer for screenshots, keep it — it captures the images that the HTML Reporter embeds in the report. What you can remove is ArtifactArchiver, since the HTML Reporter handles artifact storage internally.

Step 4: Simplify package.json scripts

The HTML Reporter generates the report automatically when the test run finishes. There is no separate generation step:

 {
"scripts": {
- "clean": "rimraf target",
- "test": "failsafe clean test:execute test:report",
- "test:execute": "npx playwright test",
- "test:report": "serenity-bdd run --features='./tests' --source='./target/site/serenity' --destination='./target/site/serenity'"
+ "test": "npx playwright test"
}
}

No clean step, no failsafe wrapper, no test:report step. The report appears in your configured outputDirectory as soon as the tests complete.

Step 5: Update .gitignore

Replace the old output path with the new one:

- target/site/serenity
+ reports/serenity-js

Step 6: View the report

See Viewing the report — open index.html directly or use npx @serenity-js/html-reporter serve --open.

What about screenshots?

SetupWho captures?Who stores?
Serenity BDDPhotographerArtifactArchiver (separate crew member)
HTML ReporterPhotographerHtmlReporter (built-in)

Remove ArtifactArchiver when switching — the HTML Reporter handles artifact storage internally. Keep Photographer in the test-level crew if you want screenshots.

Do I still need Java?

No. The HTML Reporter is pure Node.js — no JRE, no JAR downloads, no serenity-bdd update.

What replaces serenity-bdd run?

Nothing — the report generates automatically at the end of the test run. For multi-job CI aggregation, use the aggregate CLI command instead.

Learn more