Share a Cucumber HTML report

Cucumber reports exist to be read by people who don't run the suite. That is the whole premise of BDD: the scenarios are written in the language of the business so the business can check them. Then CI takes the report, zips it, and puts it behind a login the business doesn't have.

The mismatch is the problem, not the format. @cucumber/html-formatter already produces exactly the right artifact — one self-contained file, the run's messages embedded, a bundled React app rendering the feature tree. It needs a URL, not a build system.

Publish it with one curl

npx cucumber-js --format html:cucumber-report.html

curl -fsS -X PATCH \
  "https://commareports.com/api/v1/reports/$COMMA_REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html cucumber-report.html \
        --arg title "Acceptance — $(git rev-parse --short HEAD)" \
        '{title: $title, html: $html}')"

PATCH on a saved report id instead of POST means every run appends a revision at the same URL. The link in the team channel is written once and never goes stale. Use a scoped tokenreports:write is all this needs.

For cucumber-jvm, the same file comes out of @CucumberOptions(plugin = "html:target/cucumber-report.html"); for Behave or SpecFlow, point the curl at whatever single HTML file the reporter wrote. Nothing here is JS-specific.

What changes when the report has a URL

  • A failing scenario gets a thread on it. A reviewer highlights the step that broke and pins a comment there — "this is the pricing change from Tuesday, expected" — and the thread stays put across the next dozen runs. See commenting on HTML.
  • Product owners can actually open it. No CI seat, no repo access, no zip. The sharing model is per report: private, team-visible, domain-gated, or named reviewers.
  • Run-over-run diffs. "Which scenarios flipped since the last green build?" is a revision diff rather than two tabs and a memory test.
  • Announcements. A webhook on revision.created posts each run into Slack.

Limits worth knowing

  • HTML body: 5 MB. Base64 screenshots inlined by the formatter add up quickly. Past the cap, upload them as assets (25 MB per file, 250 MB per report) instead of inlining.
  • Scripts run, sandboxed. The report renders in an iframe with sandbox="allow-scripts" and no allow-same-origin, so the interactive feature tree works. Reports that fetch sibling files at view time need those files uploaded as assets — see Playwright for that shape.
  • Rate limits are per token, 60/minute. One publish per build is not close.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history. Publish one suite and send the link to someone who has never logged into your CI.

Create your first report →

Related