Playwright
Advanced 16 min read Playwright

Tracing, Screenshots & Debugging

Playwright traces record every action, network request and DOM snapshot for a test, turning a CI failure into a replayable movie. Screenshots, video and the inspector complete the debugging toolbox for diagnosing flaky or failing suites.

trace viewertracingscreenshotsvideo recordinginspectordebugdom snapshotreplay
Introduction

What is this?

Tracing captures a full execution log: console output, network requests, actions, and before/after DOM snapshots at every step. The trace viewer replays these locally with a timeline scrubber. Combined with screenshots, full-page screenshots and video, this is how teams diagnose failures without reproducing them.

Motivation

Why do you need it?

  • A failed CI run becomes a locally replayable trace, so you debug the actual failure instead of guessing.
  • The timeline shows exactly which action, selector and network call preceded a timeout or wrong assertion.
  • DOM snapshots let you inspect what the page actually looked like, not what you assumed it looked like.
  • Videos and screenshots give product and QA teams human-readable evidence without running the app.
  • You enable tracing on demand in CI (only on failure) to keep storage and run time under control.
Think about it

Mental model

Imagine

An airplane black box

Think of

A Playwright trace

When a flight has an incident, the black box replays instruments, controls and comms. A trace replays the test's actions, network and DOM so you can reconstruct the exact moment it went wrong.

Mechanics

How it works

  • Tracing is enabled in the config with trace: 'on-first-retry' or 'retain-on-failure', or manually via browser.newContext({ trace: 'on' }).
  • For each action Playwright records a timestamp, selector, resolved element and a snapshot of the page before and after.
  • Network activity, console messages, errors and page events are appended to the same timeline.
  • The trace file (trace.zip) is attached to the HTML report and can be opened with npx playwright show-trace.
  • Screenshots and video are separate artifacts, captured per config or per step with page.screenshot().

What a single action contributes to the trace timeline.

Test starts
Action: click
DOM snapshot
Network log
Action result
Trace saved
Reference

Key commands

npx playwright show-trace trace.zip

Open a trace file in the viewer to replay actions and inspect network/snapshots.

Trace viewer opens in the browser with a timeline, action list and DOM snapshot panel.
npx playwright show-report

Open the HTML report, which embeds traces, videos and screenshots for failed tests.

npx playwright test --debug

Start the inspector, pause before the first action and step through with live previews.

await page.screenshot({ path: 'shot.png', fullPage: true })

Capture a viewport or full-page screenshot at a precise moment.

npx playwright test --trace on

Force tracing for every test in the run, regardless of the config.

PWDEBUG=1 npx playwright test

Environment variable that launches the debug inspector for the run.

Hands-on

Examples

Configuring tracing on failure plus a manual screenshot

Configuring tracing on failure plus a manual screenshot
import { defineConfig, devices } from "@playwright/test";
export default defineConfig({
use: {
trace: "retain-on-failure",
video: "retain-on-failure",
screenshot: "only-on-failure",
viewport: { width: 1280, height: 720 },
},
projects: [
{ name: "chromium", use: { ...devices["Desktop Chrome"] } },
],
});
// Inside a test, capture a full-page screenshot at a meaningful moment:
import { test, expect } from "@playwright/test";
test("captures a full-page screenshot after checkout", async ({ page }) => {
await page.goto("https://example.com/checkout");
await page.getByRole("button", { name: "Place order" }).click();
await expect(page.getByText("Order confirmed")).toBeVisible();
await page.screenshot({ path: "artifacts/order-confirmed.png", fullPage: true });
});

The config enables tracing, video and screenshots that are only retained when a test fails, so CI artifacts stay small. The test then captures an explicit full-page screenshot after the order confirmation renders, giving QA a documentable artifact alongside the automated assertion.

Real world

In production

  • CI runs with trace: 'on-first-retry' so flaky tests automatically produce traces for diagnosis.
  • Failed-checkout investigations start by replaying the trace to find the exact step and network call.
  • Full-page screenshots are attached to release notes and PR comments as visual evidence.
  • Videos of smoke-test runs give QA a fast human review before a production deploy.
Guidelines

Best practices

  • Use trace: 'on-first-retry' or 'retain-on-failure' in CI to avoid bloating every run's artifacts.
  • Keep screenshot paths inside an artifacts/ directory and gitignore it.
  • Add an explicit page.screenshot() at critical milestones (receipt, success page) even when the test passes.
  • Strip console noise in traces by filtering known third-party messages before debugging.
  • Disable animations in tests (prefers-reduced-motion) so snapshots and video are stable and fast.
Watch out

Common mistakes

  • Enabling trace: 'on' for every run, which slows the suite and floods CI with large zip files.
  • Relying on screenshots instead of reading the trace's network tab and DOM snapshot for the real cause.
  • Capturing page.screenshot() after a navigation completed but before the target rendered.
  • Forgetting to gitignore artifacts/, committing megabytes of png/zip blobs.
Root cause analysis

Common issues

Error
Trace viewer shows 'Could not read trace file'
Root cause

The trace.zip is corrupted or truncated, often from a killed worker.

Fix

Re-run the test with --trace on and regenerate the artifact; ensure the worker wasn't force-killed mid-write.

Error
Screenshot shows a blank white page
Root cause

The screenshot fired before fonts, images or layout finished, or animations froze it early.

Fix

Await a web-first assertion for the target content, then screenshot; consider fullPage for scroll regions.

Error
Video file is empty or missing on failure
Root cause

video config is set to 'off' or the browser context never closed properly.

Fix

Set video: 'retain-on-failure' and verify the context is closed by the runner (don't manually dispose it in the test).

When things break

Debugging tips

  • In the trace viewer, select an action and switch between before/after snapshots to see what changed.
  • Filter the network panel for the failing endpoint and compare timing with the failing assertion.
  • Use the console panel in the trace to catch browser warnings that fired right before the failure.
  • Slow down flaky runs with --repeat-each 3 --workers 1 to observe reproducible timing.
Interviews

Interview checkpoint

Practice

Hands-on lab

Trace the Flake
40 min · advanced
In progress
Objectives
  • Configure tracing to retain artifacts on failure
  • Run a purposely flaky test and capture its trace
  • Inspect actions, network and DOM snapshots in the trace viewer
  • Fix the flake using evidence from the trace

Trace the Flake

40 min · advanced

0/5 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/3
1

Which trace config keeps artifacts only when a test actually fails?

2

The trace viewer can show the DOM snapshot before and after each action.

3

A screenshot captured after a navigation shows a blank page. What is the most likely fix?

Quick reference

Cheat sheet

Artifacts in config
trace: 'on-first-retry'Trace only flaky tests
video: 'retain-on-failure'Video for failed tests
screenshot: 'only-on-failure'Auto screenshot on failure
npx playwright show-trace trace.zipOpen a trace
npx playwright test --trace onForce tracing
npx playwright test --debugStep through with inspector
In-test captures
await page.screenshot({ path, fullPage })Explicit screenshot
await page.locator.screenshot()Element-only shot
await page.emulateMedia({ reducedMotion })Disable animations
await context.newPage()More pages in same trace
Go deeper

Official documentation