The screenshot steps save PNG captures - plus a matching .html snapshot of the page source - to a configurable directory. They give stakeholders visual evidence they can scan, and give QA the failure forensics they depend on: alongside the manual steps documented below, a built-in hook automatically captures a screenshot whenever a step fails, and scenarios tagged @screenshots get a capture after every passing step.
Every capture writes two files: a PNG taken with Playwright's screenshot API, and an HTML file containing the full page markup at that moment (optionally prefixed with context lines such as the current URL, feature, step, and datetime). The HTML sidecar is invaluable when a rendering problem is easier to diagnose in the DOM than in pixels, and it still works on drivers without screenshot support.
Filenames are generated from a token pattern - {datetime}, {feature_file}, {step_line}, {step_name}, {url_path}, and friends - so captures sort predictably in CI artifacts. Failed-step captures get their own pattern with a failed_ prefix by default, making them easy to spot in a large run. All behavior is configurable per project via worldParameters.screenshot in cucumber.js, and overridable per run via WEBSHIP_SCREENSHOT_* environment variables.
Quick reference
| Step | What it does |
|---|---|
Then I save screenshot | Save a screenshot at the current viewport size. |
Then I save fullscreen screenshot | Save a full-page screenshot (entire scrollable area). |
Then I save 1440 x 900 screenshot | Resize the viewport to width x height, then save a screenshot. |
Then I save fullscreen 1440 x 900 screenshot | Resize the viewport, then save a full-page screenshot. |
Then I save screenshot with name "homepage.png" | Save a screenshot using an explicit filename (tokens supported). |
Then I save fullscreen screenshot with name "homepage-full.png" | Save a full-page screenshot using an explicit filename (tokens supported). |
All phrasings accept I, we, or no pronoun (Then save screenshot), and work equally as When or Then.
Steps in detail
Then I save screenshot
Captures the visible viewport as a PNG and saves the page HTML next to it, using the configured filename pattern (default {datetime}.{feature_file}.feature_{step_line}.{ext}). The screenshot directory is created on demand. If alwaysFullscreen is enabled in configuration, this step captures the full page instead.
Given I am on "/about-us.html"
Then I save screenshot
Then I save fullscreen screenshot
Same as above but passes fullPage: true to Playwright, capturing the entire scrollable height of the document rather than just the viewport. Use it for long articles, landing pages, or anywhere below-the-fold content matters.
Given I am on "/about-us.html"
When I wait 2 seconds
Then I save fullscreen screenshot
Then I save 1440 x 900 screenshot / Then I save fullscreen 1440 x 900 screenshot
Resizes the viewport to the given width and height first, then captures. Note the resize persists for the rest of the scenario - later steps run at the new size. Handy for capturing a page at several device sizes in one scenario: common pairs are 375 x 667 (phone), 768 x 1024 (tablet), and 1920 x 1080 (desktop). The fullscreen variant additionally captures the full scrollable page at that width.
Given I am on homepage
Then I save 375 x 667 screenshot
And I save 768 x 1024 screenshot
And I save fullscreen 1920 x 1080 screenshot
Then I save screenshot with name "homepage.png" / ...fullscreen screenshot with name "..."
Uses your filename instead of the configured pattern. The name may embed any of the tokens from the table below - "un-landing-{datetime}.png", "{feature_file}_{step_line}", "{url_path}.png" - and if it does not end with .{ext} or an explicit extension token, the extension is appended automatically (so both PNG and HTML variants are written). The fullscreen variant captures the full page.
Given I am on "/news"
Then I save screenshot with name "news-latest.png"
And I save fullscreen screenshot with name "news-{datetime}.png"
Complete example
Feature: Save screenshots to disk.
As a tester,
I want to capture screenshots at arbitrary points in my scenarios
so that I can review rendered pages and debug failures.
Background:
Given I am on homepage
Scenario: Save a screenshot at the current viewport size.
Then I save screenshot
Scenario: Save a full-page screenshot at a fixed viewport.
Then I save fullscreen 1200 x 800 screenshot
Scenario: Save a screenshot with filename tokens.
Then I save screenshot with name "{feature_file}_{step_line}_{datetime}.png"
@screenshots
Scenario: Auto-capture a screenshot after every step in a tagged scenario.
Given I am on "/about-us.html"
Then I should see "About Us"
Configuration
Settings are resolved per scenario with this priority: WEBSHIP_SCREENSHOT_* environment variables (CI / shell - highest), then worldParameters.screenshot.* in cucumber.js, then built-in defaults.
| Env var | worldParameters key | Default | Purpose |
|---|---|---|---|
WEBSHIP_SCREENSHOT_DIR | dir | ./screenshots | Output directory (created if missing). |
WEBSHIP_SCREENSHOT_PURGE | purge | false | Empty the directory once at the start of the run. |
WEBSHIP_SCREENSHOT_ON_FAILED | onFailed | true | Auto-capture when a step fails. |
WEBSHIP_SCREENSHOT_ON_EVERY_STEP | onEveryStep | false | Capture after every passing step, in every scenario. |
WEBSHIP_SCREENSHOT_FULLSCREEN | alwaysFullscreen | false | Make every capture full-page. |
WEBSHIP_SCREENSHOT_FAILED_PREFIX | failedPrefix | failed_ | Prefix used by the failed-capture pattern. |
WEBSHIP_SCREENSHOT_PATTERN | filenamePattern | {datetime}.{feature_file}.feature_{step_line}.{ext} | Filename pattern for normal captures. |
WEBSHIP_SCREENSHOT_PATTERN_FAIL | filenamePatternFailed | {failed_prefix}{datetime}.{feature_file}.feature_{step_line}.{ext} | Filename pattern for failed-step captures. |
WEBSHIP_SCREENSHOT_INFO_TYPES | infoTypes | (empty) | Comma list of context lines prepended to the HTML capture: url,feature,step,datetime. |
Filename tokens
| Token | Expands to |
|---|---|
{datetime} | Capture timestamp, default format Ymd_His (e.g. 20260721_142530). A custom format is supported: {datetime:YYYY-MM-DD_HH-mm-ss}. |
{feature_file} | Feature filename without the .feature extension. |
{step_line} | Line number of the current step; zero-padded with a sprintf-style format such as {step_line:%03d}. |
{step_name} | Current step text, sanitized (spaces to underscores, quotes stripped). |
{url}, {url_origin}, {url_domain}, {url_path}, {url_query}, {url_fragment}, {url_relative} | The current page URL or a component of it, sanitized for filesystem use. |
{failed_prefix} | The configured failed prefix (default failed_). |
{ext} | File extension - png or html, filled in per capture. |
Tips
- Tag a scenario
@screenshotsto record a capture after every passing step of that scenario only - a lightweight alternative to enablingonEveryStepglobally. - Failed-step capture is on by default; disable it with
WEBSHIP_SCREENSHOT_ON_FAILED=falseif your reporter already attaches screenshots. - Set
WEBSHIP_SCREENSHOT_PURGE=truein CI so each run starts with an empty artifacts directory (the purge happens only once per run). - The viewport-resizing steps do not restore the previous size - resize back, or use the responsive steps, if later assertions are size-sensitive.