@acereports/cucumber
v1.0.0
Published
Ace Reports for Cucumber.js: zero-setup HTML test reports with every Given/When/Then step in the log, API requests and responses, screenshots on failure, retries and flaky scenarios.
Maintainers
Readme
Ace Reports for Cucumber.js
Zero-setup HTML reporting for Cucumber.js. Automatically captures every API request and response, takes a screenshot when a test fails, and tracks logs, retries and flaky tests, all in one self-contained HTML file per run. The same report as Ace Reports for .NET, Java and Python.
Website: https://harshadlambate.github.io/AceReportsWebsite/
Live demo report: https://harshadlambate.github.io/AceReportsWebsite/demo.html
Setup
npm install --save-dev @acereports/cucumberTwo lines in your Cucumber config (cucumber.js, cucumber.mjs, cucumber.json or cucumber.yaml):
module.exports = {
default: {
// ...your paths, require / import, format...
requireModule: ['@acereports/cucumber/support'],
plugin: ['@acereports/cucumber'],
},
};plugin needs Cucumber 12.6 or later. On older versions use the formatter instead of plugin (it writes the
report path into the file you name, so your console formatter keeps stdout):
format: ['progress', '@acereports/cucumber:TestResults/acereports.txt'],Run your scenarios as usual (npx cucumber-js, the IDE, CI) and the report is written to
TestResults/AceReport_<timestamp>.html in the project folder; the path is printed at the end of the run.
To turn it off for one run: ACEREPORTS_ENABLED=false npx cucumber-js
(PowerShell: $env:ACEREPORTS_ENABLED='false'; npx cucumber-js).
Configuration
Optional. Pass options to the reporter (pluginOptions in your Cucumber config):
pluginOptions: {
acereports: { suiteName: 'Checkout Regression', environment: 'UAT', theme: 'dark' },
},
// with the formatter: formatOptions: { acereports: { ... } }| Option | Default | |
| --- | --- | --- |
| suiteName | the project folder's name | shown at the top of the report |
| environment | ACEREPORTS_ENVIRONMENT, else Local | DEV, QA, UAT... |
| outputPath | TestResults/AceReport_<timestamp>.html | a file, or a folder for the timestamped file |
| theme | system | light, dark or system (follows the reader's OS; the report has a toggle) |
| captureHttp | true | record API calls |
| captureConsole | true | add console.log / warn / error output to the test's log |
| screenshotOnFailure | true | take a screenshot when a browser test fails |
| maxBodyLength | 20000 | longer request and response bodies are clipped |
| enabled | true | false switches the report off |
The same settings work as environment variables, e.g. ACEREPORTS_ENVIRONMENT=QA, ACEREPORTS_OUTPUT=reports/run.html,
ACEREPORTS_THEME=dark, ACEREPORTS_ENABLED=false. Or set them from a test, anywhere before the run ends:
import { ace } from '@acereports/cucumber';
ace.suiteName('Checkout Regression');
ace.environmentName('UAT');
ace.darkTheme(); // or lightTheme() / systemTheme()
ace.outputPath('reports/report.html');
ace.captureHttpTraffic(false); // API capture is on by defaultEnvironment name
Resolved in this order, first match wins: ace.environmentName('QA'), the reporter's environment option,
the ACEREPORTS_ENVIRONMENT environment variable, Local.
Logging from a test
import { ace } from '@acereports/cucumber';
ace.info('Submitting payment');
ace.pass('Payment authorized');
ace.fail('Refund was accepted but should have been rejected'); // logs only; use an assertion to fail
ace.warn('Retrying the payment gateway');
ace.debug('Skipping optional 3-D Secure step');
ace.info('Order created', order); // objects are shown as indented JSON
ace.log('GIVEN', 'the cart is empty'); // any levelEach call attaches to the test that is running, so parallel workers keep their logs apart. Outside a test
the calls do nothing, so helpers shared with other code are safe to instrument. console.log, console.warn
and console.error output written during a test is added to its log too.
Screenshots
A screenshot is taken automatically when a step fails, before your After hooks close the browser. Ace Reports
finds the browser on the World: a property named page, context, browser or driver (this.page = ...).
Images you attach with this.attach(png, 'image/png') become screenshot tabs, and this.log('...') lines are kept
in the log.
Take your own at any point; each becomes its own tab in the report:
await ace.takeScreenshot(); // "Screenshot 1", "Screenshot 2", ...
await ace.takeScreenshot('After login'); // named tab
await ace.takeScreenshot('Cart page', pngBuffer); // an image you already have (Buffer or base64)
await ace.screenshotOf(page.locator('#cart'), 'Cart');When Ace Reports cannot find the browser by itself, tell it where it is:
ace.useScreenshotSource(page); // for this test (call it in beforeEach for every test)
ace.setScreenshotProvider(() => DriverManager.driver); // once, for driver factoriesWorks with Playwright (Page, BrowserContext, Browser, Locator), Puppeteer, Selenium WebDriver and WebdriverIO.
A page that never went anywhere (about:blank) is skipped, so an API test that fails gets no empty screenshot.
Automatic API capture
Nothing to add. Every HTTP call a test makes is recorded: method, URL, request and response bodies, status and
duration, plus connection errors. Ace Reports hooks Node's http / https modules and the global fetch, so it
sees calls from axios, fetch, got, superagent / supertest, node-fetch, ky, and from your own API
clients and vendor SDKs built on them.
Calls are shown per attempt in the API tab, JSON indented. Authorization, Proxy-Authorization, Cookie and
Set-Cookie headers are never stored. Turn capture off with captureHttp: false or ace.captureHttpTraffic(false).
What's automatic, and what needs one line
| What | Automatic | Needs one line | Not captured (yet) |
| --- | --- | --- | --- |
| API calls | axios, fetch, got, superagent / supertest, node-fetch, ky, and anything built on Node's http, https or fetch, including calls made through your own wrappers and API clients | | Clients that bypass them (HTTP/2 via the http2 module, gRPC, native add-ons). Log what matters with ace.info('Response', body) |
| Screenshots | A page / context / browser / driver property of the World; images you this.attach(...) | A driver kept elsewhere: ace.setScreenshotProvider(() => DriverManager.driver) once | |
| Retries | --retry (with --retry-tag-filter if you like); every attempt kept with its own logs, error, API calls and screenshots | | |
| Logs | Every step (GIVEN, WHEN, THEN, AND, BUT) with its doc string or data table, the failing step's error, skipped steps, failing hooks, this.log(...), console output | Your own lines: ace.info(...), ace.pass(...), ace.fail(...) | Loggers that write straight to stdout (pino, winston) |
The Logs tab
- Each scenario, and each Examples row of a Scenario Outline, is one row: named after the scenario, grouped by its
feature (and rule), with its tags as categories and the example values (
card=visa) as arguments. - Every step is a line in the Logs tab:
GIVEN,WHEN,THEN,AND,BUT, with its doc string or data table underneath.ace.info(...),this.log(...)andconsole.log(...)lines appear under the step that wrote them. - A failing step carries its error, and the steps it prevented are listed as
SKIPPED. Undefined and pending steps are marked; failing Before / After hooks are shown as setup / teardown errors.
Retries and flaky tests
Each attempt keeps its own logs, API calls, error and screenshots, shown as separate attempt tabs. A test is retried when it took more than one attempt, and flaky when it passed after an earlier attempt failed.
Retries come from retry: 2 in the config or npx cucumber-js --retry 2 (optionally with retryTagFilter: '@flaky').
Parallel runs
--parallel 4 works: every worker's scenarios end up in one report.
Requirements
Node.js 18+, Cucumber.js 10+ (the plugin setup needs 12.6+).
License
Ace Reports is free to use under the PolyForm Perimeter License 1.0.1.
Commercial terms (OEM, white-label, or a full buy-out) are available: see the website.
Found it useful? Buy me a coffee ☕
