skip to content

Recorded Output

The files a finished run drops on disk for somebody to open later - trace zips, video, images and anything attached to a result. Asked because what you enable in CI is a cost decision.

on this pageshow

explore

questions

14

In Playwright Test, what does the screenshot: 'only-on-failure' option capture, and where does the file land?

level: juniorimportance: must knowfreq 76%

answer

  1. A config switch, not a test call
  2. Four values, one of them conditional
  3. Fires after the verdict, not at the assertion
  4. Lands beside the trace and the video
  5. Viewport only unless you ask otherwise

basics

~20 s

The runner itself photographs every page open in the test at the moment the test ends failed, and only then. Each PNG is written into that test's folder under outputDir, test-results by default, and attached to the result.

solid answer

~40 s

`screenshot` is a Playwright Test runner option set under `use`, not something a test calls. In Playwright 1.63 it takes `'off'`, `'on'`, `'only-on-failure'` or `'on-first-failure'`, plus an object form such as `{ mode: 'only-on-failure', fullPage: true }`. With `'only-on-failure'` the runner captures each open page after a test ends failed or timed out, writes `test-failed-1.png` (then `-2`, one per page) into the test's directory under `outputDir` (`test-results/` by default), and records it as an attachment named `screenshot` so the HTML report shows it inline. The capture is viewport-only unless you ask for `fullPage`, and it happens after the test body has finished, so it shows the aftermath of the failure rather than the instant of it. Per-test output folders are cleaned before the test runs, so images never leak across runs.

code

typescript · 8 lines
typescript
import { defineConfig } from '@playwright/test';

export default defineConfig({
  outputDir: 'test-results',
  use: {
    screenshot: { mode: 'only-on-failure', fullPage: true },
  },
});

go deeper

for a junior

Recall the four mode values and that this is config, set under use, not a call inside a test. Know the file lands in the test's folder under outputDir, test-results by default.

for a middle

Explain the timing: capture happens after the test body ends, one image per open page, viewport only unless fullPage is set, and the file is attached to the result so reporters can show it.

for a senior

Show judgment about cost and noise: only-on-failure versus on-first-failure on a flaky suite, fullPage on long pages, and knowing when a screenshot is too late and a trace is the right evidence.

for a principal

Own the evidence budget across projects: which suites get images at all, how retries multiply artefacts, and how config scoping expresses that policy instead of ad-hoc captures scattered through tests.

## What the option actually is `screenshot` is a **Playwright Test runner option**, not a page API. You set it under `use` in `playwright.config.ts`, or narrow it with `test.use({ screenshot: 'only-on-failure' })` inside a file or a `describe` block. When it is on, the runner takes the picture itself around the end of a test; your test code calls nothing. That is the whole point: evidence you did not have to remember to capture, on the runs where you were not watching. Its manual counterpart, `page.screenshot()`, is a separate mechanism you drive yourself mid-test. The two coexist happily, and most mature suites use both. ## The four modes In Playwright 1.63 the option accepts four string values: | Value | When the runner captures | Why you would pick it | |---|---|---| | `'off'` | never | the default; nothing is written | | `'on'` | at the end of every test, pass or fail | short smoke suites where you want a picture of every result | | `'only-on-failure'` | when a test ends failed or timed out | the usual CI setting: evidence exactly where it matters | | `'on-first-failure'` | on the first failing attempt only, not on later retries | stops a retried flaky test writing near-identical images | `'only-on-failure'` fires on **every** failed attempt, so a test that fails three times leaves three sets of images; `'on-first-failure'` leaves one. ## Which pages get captured, and when The runner captures each page open in the test, so an order-tracker test that opened the customer page plus a driver-detail popup produces two files, `test-failed-1.png` and `test-failed-2.png`. The timing matters more than people expect. Capture happens **after the test body has ended**, which means: - a toast that had already faded is not in the image; - a page you closed in a cleanup step cannot be photographed at all; - an element that only appeared while an action was in flight is long gone. The screenshot shows the *aftermath* of the failure, not the moment of it. For the moment itself you want a recorded trace or your own capture taken at the point you care about. ## Where the file lands 1. The runner picks a directory for the test inside **`outputDir`** (`test-results/` unless the config changes it), named from the spec file, the test title and the project, with a `-retry1` suffix on a retried attempt so attempts never overwrite each other. 2. It writes `test-failed-1.png` there, numbering upwards for each additional page. 3. It records the file as an **attachment** named `screenshot` on the test result, which is how the HTML report and other reporters render it inline instead of making a reader dig through folders. A test's output folder is cleaned before that test runs, so you never inherit an image from an earlier run; equally, anything you write outside `outputDir` is yours to manage. ## The object form The string form is shorthand for an object: ```ts use: { screenshot: { mode: 'only-on-failure', fullPage: true }, } ``` - `mode` -- one of the four values above. - `fullPage` -- capture the whole scrollable document instead of the viewport. The default is viewport-only, which on a long delivery-tracking page can crop away the driver map and the timeline, leaving you a photograph of a header. - `omitBackground` -- capture with a transparent background where the page paints none. ## What it is not - **Not a baseline.** These images are evidence of what happened; checking an image against an approved reference is a different mechanism with its own storage and approval flow. - **Not a replacement for a recorded trace.** One PNG of the end state is far less than a step-by-step recording; screenshots are the thing a human glances at first, not the whole story. - **Not free on `'on'`.** A full-page capture on every passing test buys wall-clock time and CI disk for images nobody opens. - **Not per-test selective on its own.** The mode applies to whatever scope you set it in; deciding which cases deserve which evidence is a policy call you express through config scoping. ## A sane default For a food-delivery order tracker, `'only-on-failure'` with `fullPage: true` in the shared config pays for itself: green runs write nothing, and a red one hands the reviewer the entire page -- status banner, driver map and footer -- without anyone editing a test.

  • How does 'on-first-failure' behave differently from 'only-on-failure' on a test that fails three times?
    `'only-on-failure'` captures on each failed attempt, so three attempts leave three sets of images in three per-attempt folders. `'on-first-failure'` captures on the first failing attempt only, so retries add nothing. On a flaky suite that is a large reduction in near-identical files for no loss of diagnostic value.
  • The automatic screenshot shows the order tracker with no error toast visible, although the test failed on that toast. Why?
    The runner captures after the test body has ended, which is often seconds after the failing assertion, and the toast had auto-dismissed by then. Take your own `page.screenshot()` at the point of interest, or read a recorded trace, which keeps a snapshot per action rather than one picture of the aftermath.

saying these in an interview costs you the question

  • Thinks the runner captures at the instant the assertion fails
  • Believes only-on-failure also compares the image against a baseline
  • Assumes the automatic screenshot is full page by default
  • Expects images from previous runs to survive in test-results
  • Thinks a test must call page.screenshot for the option to work
  • Says the mode only captures the first page and ignores popups
open as a page

In Playwright, what does the config option trace: 'on-first-retry' record?

level: juniorimportance: must knowfreq 78%

basics

~10 s

Playwright records a trace only while a test runs its first retry. The original failing attempt is never traced, and if the project allows no retries, no trace is produced at all.

open as a page

How do you open a Playwright trace zip to step through a failed run?

level: juniorimportance: must knowfreq 70%

basics

~10 s

Run npx playwright show-trace path/to/trace.zip to open it in Playwright's Trace Viewer, or drag the same zip onto trace.playwright.dev, which renders it in the browser with nothing installed.

open as a page

Why does Playwright's video: 'retain-on-failure' still cost time on tests that pass?

level: middleimportance: must knowfreq 58%

basics

~20 s

Because the browser records the whole test regardless. Recording starts when the context opens, long before a verdict exists, so every test pays capture, encoding and disk writes. Retain-on-failure only deletes the file afterwards when the test passed.

open as a page

How do Playwright's trace modes 'on' and 'retain-on-failure' differ in what survives a run?

level: middleimportance: must knowfreq 62%

basics

~10 s

Both record every test attempt, so both pay the full capture cost. The difference is afterwards: 'on' keeps every trace zip, while 'retain-on-failure' deletes the ones belonging to tests that passed.

open as a page

In Playwright's Trace Viewer, what do the Before, Action and After snapshots show?

level: middleimportance: must knowfreq 60%

basics

~20 s

They are three recorded DOM states around one action: the page as the call began, the moment input was delivered with the target point marked, and the page once the call returned. Comparing them shows what the action changed.

open as a page

In Playwright, when is locator.screenshot() a better capture than page.screenshot() with clip or fullPage?

level: middleimportance: should knowfreq 44%

basics

~20 s

Whenever the subject is one element. Playwright's locator.screenshot scrolls it into view, waits for it to be stable and measures its box at capture time, while a clip rectangle is a fixed region you computed yourself that goes stale as soon as the layout moves.

open as a page

In Playwright's page.screenshot, what does the mask option do to the captured image?

level: middleimportance: should knowfreq 31%

basics

~20 s

It takes locators and paints a solid box over each matching element's bounding box while the image is being taken, pink by default and any CSS color via maskColor. Those pixels never reach the file.

open as a page

In Playwright, what do tracing's screenshots, snapshots and sources options each capture?

level: middleimportance: should knowfreq 45%

basics

~20 s

Screenshots capture image frames of the page over time, snapshots capture the DOM around each action so the page can be re-rendered, and sources copies the test files that drove the run into the zip.

open as a page

A Playwright test writes a debug screenshot to shots/map.png, yet the run's report shows no image; why?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Writing a file is not the same as reporting one. Playwright shows attachments, so the capture must be attached with testInfo.attach, and its path should come from testInfo.outputPath so it is unique per test and per attempt.

open as a page

A Playwright CI job set trace: 'on-first-retry' but a failing test produced no trace zip; how do you diagnose it?

level: seniorimportance: should knowfreq 48%

basics

~20 s

Check whether a retry actually ran. That mode records only during a retry, so zero retries, a run aborted before the retry, or a command-line trace override all leave a failure with no trace at all.

open as a page

You have only the trace zip from a Playwright run where an order-tracker test timed out in CI. Which Trace Viewer tabs do you read, and what does each settle?

level: seniorimportance: should knowfreq 48%

basics

~20 s

Start at the failing action, then let each tab answer one question: Call for the recorded arguments, Log for what the call waited on, the snapshots for what was on screen, Network and Console for why.

open as a page

What do you weigh before sharing a Playwright trace zip outside the team that produced it?

level: principalimportance: should knowfreq 36%

basics

~20 s

That the archive is evidence, not a screenshot: it carries recorded requests and responses, headers, page DOM and test source. Anything a session token, a customer address or an internal endpoint touched during the run is inside it.

open as a page

In a Playwright script, when would you use tracing.startChunk() instead of tracing.start()?

level: seniorimportance: nice to knowfreq 28%

basics

~10 s

Use chunks when one long-lived browser context should produce several separate trace zips. Tracing is started once on the context, then each startChunk and stopChunk pair records and exports one segment of the session.

open as a page