The Trace Viewer turns a mysterious CI failure into a step-by-step replay you can inspect like DevTools. In this lesson you will configure tracing, open traces in several ways, learn every panel of the viewer and follow a real debugging walkthrough.
๐ What You’ll Learn: what a trace contains, trace configuration values, opening traces from the report, CLI and trace.playwright.dev, every Trace Viewer panel, a CI debugging walkthrough, test.step, tracing in plain scripts, and handling traces in CI safely.
๐ต๏ธ What Is a Playwright Trace?
A trace is a complete recording of a test run that you can open after the fact. Unlike a video, it is interactive: for every action you can see the DOM before and after, the exact element that was targeted, network requests, console messages and the source line that ran.
That makes the Trace Viewer the best tool for the hardest failures: the ones that only happen in CI, at night, on someone else’s machine. Instead of guessing, you replay the run step by step.
โ๏ธ Turn On Tracing
Configure tracing once in playwright.config.ts:
import { defineConfig } from '@playwright/test';
export default defineConfig({
retries: process.env.CI ? 2 : 0,
use: {
trace: 'on-first-retry',
},
});
| Value | When a trace is recorded or kept |
|---|---|
'off' | Never (default) |
'on' | For every test (heavy, use for debugging sessions) |
'retain-on-failure' | Recorded for every test, kept only for failures |
'on-first-retry' | Only on the first retry of a failed test (recommended with retries in CI) |
'on-all-retries' | On every retry |
'retain-on-first-failure' | Kept only for the first failed attempt |
๐ก Tip: Use 'on-first-retry' in CI when retries are enabled, or 'retain-on-failure' when they are not. Both give you a trace for every failure without slowing down passing tests much.
Force tracing for one run from the command line:
npx playwright test tests/cart.spec.ts --trace on
๐ Open a Trace
Traces are saved as trace.zip files inside test-results/. Open them in any of these ways:
- From the HTML report: run
npx playwright show-report, open the failed test, and click the trace image or link. - From the command line:
npx playwright show-trace test-results/<test-folder>/trace.zip - In the browser: drag the zip onto trace.playwright.dev. The viewer runs entirely in your browser; the file is not uploaded to a server.
- In UI mode (
--ui) and the VS Code extension (enable Show trace viewer), traces open automatically.
๐งญ Tour of the Trace Viewer
| Area | What it shows | How it helps |
|---|---|---|
| Actions (left) | Every Playwright action and assertion, with duration | Find the failing step and slow steps |
| Timeline (top) | Filmstrip of screenshots over time | See what the user would have seen |
| Snapshots (centre) | DOM snapshots: Before, Action, After | Inspect the real page at that moment |
| Locator picker | Pick or type a locator against the snapshot | Fix locators against the exact failing DOM |
| Call | Parameters, locator and timing of the action | Check what Playwright actually did |
| Log | Actionability checks for the action | See “waiting for element to be visible” and similar |
| Errors | Error messages and stack | Jump to the failure |
| Console | Browser console logs and page errors | Spot JavaScript errors in the app |
| Network | Every request with status, timing, headers and body | Find failed or slow API calls |
| Source | Your test code, with the current line highlighted | Connect the step to your code |
| Attachments | Screenshots and files attached in the test | Extra evidence |
Reading the “Action” snapshot
Click a click-step and choose the Action tab: a red dot shows exactly where Playwright clicked. If the dot is on an overlay or the wrong element, you have found the bug.
๐งช A Debugging Walkthrough
Imagine this test fails only in CI with “Timeout 30000ms exceeded” on click():
test('checkout', async ({ page }) => {
// ...log in, add item...
await page.getByRole('button', { name: 'Checkout' }).click();
});
In the trace:
- Actions: the click step is red and took 30 seconds.
- Log: the element is visible, enabled and stable, followed by repeated “another element would receive the click”.
- Snapshot (Before): a cookie consent banner covers the bottom of the page in the CI viewport.
- Network: the banner script loaded only in CI because a feature flag differed.
Fix: accept or close the banner in a beforeEach (or set the consent cookie), and align the viewport with production. No guessing, no “works on my machine”.
๐ท๏ธ Make Traces Easier to Read with test.step
Group actions into named steps; they appear as collapsible sections in the trace and the HTML report:
import { test, expect } from '@playwright/test';
test('purchase a backpack', async ({ page }) => {
await test.step('log in', async () => {
await page.goto('https://www.saucedemo.com/');
await page.getByPlaceholder('Username').fill('standard_user');
await page.getByPlaceholder('Password').fill('secret_sauce');
await page.getByRole('button', { name: 'Login' }).click();
});
await test.step('add backpack to cart', async () => {
await page.locator('[data-test="add-to-cart-sauce-labs-backpack"]').click();
await expect(page.locator('.shopping_cart_badge')).toHaveText('1');
});
});
๐ ๏ธ Record Traces Outside the Test Runner
In plain Playwright library scripts, start and stop tracing on the context:
import { chromium } from 'playwright';
(async () => {
const browser = await chromium.launch();
const context = await browser.newContext();
await context.tracing.start({ screenshots: true, snapshots: true, sources: true });
const page = await context.newPage();
await page.goto('https://www.saucedemo.com/');
await context.tracing.stop({ path: 'trace.zip' });
await browser.close();
})();
โ๏ธ Traces in CI
To use traces from CI runs, upload the report folder as a build artifact (shown in full in the GitHub Actions and Jenkins lessons):
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 14
Download the artifact, open the HTML report, and click the trace of the failed test.
โ ๏ธ Common mistake: Traces contain everything the page saw, including cookies, tokens and form values. Treat trace files like logs with sensitive data: limit who can download CI artifacts and use test accounts only.
๐ Assignment
- Set
trace: 'retain-on-failure', break one Sauce Demo test, and open its trace from the HTML report. - In the trace, find the failing action, read its Log, and inspect the Before and After snapshots.
- Use the locator picker in the trace to find a working locator for the element you broke.
- Open the Network tab and list the requests made when the inventory page loaded.
- Wrap your test in two or three
test.stepblocks and see how the trace groups actions. - Open the same trace with
npx playwright show-traceand on trace.playwright.dev. - Bonus: record a trace from a plain Node script with
context.tracing.start().
โ FAQ
๐ค What is the Playwright Trace Viewer?
A GUI tool that replays a recorded test run action by action, with DOM snapshots, network requests, console logs and source code, so you can debug failures after they happened.
๐ค How do I open a Playwright trace?
From the HTML report, with npx playwright show-trace path/to/trace.zip, or by dropping the file onto trace.playwright.dev.
๐ค Which trace setting should I use in CI?
'on-first-retry' when retries are enabled, or 'retain-on-failure' otherwise. Both keep traces for failures without recording every passing test permanently.
๐ค Is trace.playwright.dev safe for private traces?
The viewer loads the file locally in your browser and does not upload it. Still follow your company’s policy for handling files that contain sensitive data.
๐ค What is the difference between a trace and a video?
A video only shows pixels. A trace lets you inspect the DOM, locators, network, console and source for every step, which makes root-cause analysis much faster.
๐ฏ Next Steps
- ๐ญ Reporters and the HTML Report
- ๐ญ Debugging: Inspector, UI Mode and VS Code
- ๐ญ Screenshots and Video Recording
- ๐ญ Playwright Tutorial with TypeScript
๐ฌ Watch the full Playwright tutorial series on YouTube!
Subscribe to SqaToolsByDY • Practice on sqatools.in