Playwright traces make a failed browser test replayable after the run has finished. A retained trace stores the action timeline, DOM snapshots, screenshots, console messages, and network activity that explain what the browser saw at the point of failure.
The trace setting belongs under use in playwright.config.ts, so it applies to every test unless a project or test overrides it. The retain-on-failure mode records each run while it executes, keeps the trace for failed runs, and removes traces from successful runs.
Suites that already use retries often keep retry-only traces with on-first-retry. Use retain-on-failure when the first failing run should leave a trace even without retries, or when a failed run should remain available even if a later retry passes.
Related: How to record Playwright traces
Related: How to view Playwright traces
Related: How to set Playwright test retries
Steps to retain Playwright traces on failure:
- Open a terminal at the Playwright project root.
$ pwd ~/projects/playwright-demo
- Set trace to retain-on-failure in playwright.config.ts.
import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ testDir: './tests', use: { trace: 'retain-on-failure' }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] } } ] });Keep the rest of an existing config file in place. The important change is the trace value under the active use scope.
- Add a temporary failing test to prove trace retention.
import { test, expect } from '@playwright/test'; test('home page shows ready state', async ({ page }) => { await page.setContent('<main>Playwright fixture ready</main>'); await expect(page.getByText('Playwright fixture ready')).toBeVisible(); await expect(page.getByText('Missing text')).toBeVisible(); }); - Run the failing test.
$ npx playwright test tests/home.spec.ts --project=chromium Running 1 test using 1 worker 1 failed [chromium] > tests/home.spec.ts:3:5 > home page shows ready state ##### snipped ##### attachment #2: trace (application/zip) test-results/home-home-page-shows-ready-state-chromium/trace.zipPlaywright prints a trace attachment path only because the run failed. The exact output directory includes the test file, test title, and project name.
- Confirm that the failed run retained a trace archive.
$ find test-results -name trace.zip test-results/home-home-page-shows-ready-state-chromium/trace.zip
- Change the temporary test so it passes.
import { test, expect } from '@playwright/test'; test('home page shows ready state', async ({ page }) => { await page.setContent('<main>Playwright fixture ready</main>'); await expect(page.getByText('Playwright fixture ready')).toBeVisible(); }); - Remove the previous failure artifacts before checking a passing run.
$ rm -rf test-results
This makes the next file check prove the passing run's artifact behavior instead of finding the older failed-run trace.
- Run the passing test.
$ npx playwright test tests/home.spec.ts --project=chromium Running 1 test using 1 worker 1 passed (719ms)
- Confirm that the passing run did not keep a trace archive.
$ find test-results -name trace.zip
No output means Playwright removed the successful run's trace.
- Remove the temporary test and validation output.
$ rm -rf tests/home.spec.ts test-results
Run this cleanup only if tests/home.spec.ts was created for this validation. Keep or rename an existing project test instead of deleting it.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.