The Tracing class enables recording detailed traces of test execution, including screenshots, snapshots, network activity, and console logs. Traces can be viewed in the Playwright Trace Viewer.
Overview
Access tracing through the browser context:
const tracing = context.tracing;
Methods
start
Starts tracing.
await tracing.start();
await tracing.start({
name: 'my-trace',
screenshots: true,
snapshots: true,
sources: true
});
Trace name. If not specified, the trace name is generated from the test file name and title.
Trace title to display in the Trace Viewer.
Whether to capture screenshots during tracing.
Whether to capture DOM snapshots during tracing.
Whether to include source files in the trace.
Returns: Promise<void>
startChunk
Starts a new trace chunk. Useful for recording traces in multiple segments.
await tracing.startChunk();
await tracing.startChunk({
name: 'login-chunk',
title: 'Login Flow'
});
Chunk title to display in the Trace Viewer.
Returns: Promise<void>
stopChunk
Stops the current trace chunk and optionally saves it to a file.
await tracing.stopChunk();
await tracing.stopChunk({ path: 'traces/login.zip' });
Path to save the trace file. If not specified, the trace is discarded.
Returns: Promise<void>
stop
Stops tracing and optionally saves it to a file.
await tracing.stop();
await tracing.stop({ path: 'traces/test.zip' });
Path to save the trace file. If not specified, the trace is discarded.
Returns: Promise<void>
group
Creates a logical group in the trace for better organization.
await tracing.group('Authentication');
await tracing.group('Login Flow', {
location: { file: 'tests/auth.spec.ts', line: 10 }
});
options.location
{ file: string, line?: number, column?: number }
Source code location for the group.
Returns: Promise<void>
groupEnd
Ends the current trace group.
await tracing.groupEnd();
Returns: Promise<void>
Examples
Basic tracing
import { test } from '@playwright/test';
test('basic trace', async ({ page, context }) => {
await context.tracing.start({ screenshots: true, snapshots: true });
await page.goto('https://example.com');
await page.click('#button');
await context.tracing.stop({ path: 'traces/basic-trace.zip' });
});
Tracing with chunks
test('trace chunks', async ({ page, context }) => {
await context.tracing.start({ screenshots: true, snapshots: true });
// First chunk: Login
await context.tracing.startChunk({ title: 'Login' });
await page.goto('https://example.com/login');
await page.fill('#username', 'user');
await page.fill('#password', 'pass');
await page.click('#login');
await context.tracing.stopChunk({ path: 'traces/login.zip' });
// Second chunk: Dashboard
await context.tracing.startChunk({ title: 'Dashboard' });
await page.goto('https://example.com/dashboard');
await page.click('#settings');
await context.tracing.stopChunk({ path: 'traces/dashboard.zip' });
await context.tracing.stop();
});
Grouping trace actions
test('trace groups', async ({ page, context }) => {
await context.tracing.start({ screenshots: true, snapshots: true });
await context.tracing.group('Setup');
await page.goto('https://example.com');
await context.tracing.groupEnd();
await context.tracing.group('User Actions');
await page.click('#button1');
await page.click('#button2');
await context.tracing.groupEnd();
await context.tracing.group('Cleanup');
await page.click('#logout');
await context.tracing.groupEnd();
await context.tracing.stop({ path: 'traces/grouped.zip' });
});
Conditional tracing
test('conditional trace', async ({ page, context }) => {
const shouldTrace = process.env.TRACE === 'true';
if (shouldTrace) {
await context.tracing.start({ screenshots: true, snapshots: true });
}
await page.goto('https://example.com');
await page.click('#button');
if (shouldTrace) {
await context.tracing.stop({ path: 'traces/test.zip' });
}
});
Tracing with source files
test('trace with sources', async ({ page, context }) => {
await context.tracing.start({
screenshots: true,
snapshots: true,
sources: true // Include source files
});
await page.goto('https://example.com');
await page.click('#button');
await context.tracing.stop({ path: 'traces/with-sources.zip' });
});
Trace on failure
import { test as base } from '@playwright/test';
const test = base.extend({
context: async ({ context }, use, testInfo) => {
await context.tracing.start({ screenshots: true, snapshots: true });
await use(context);
// Save trace only on failure
if (testInfo.status !== testInfo.expectedStatus) {
const tracePath = `traces/${testInfo.title.replace(/\s+/g, '-')}.zip`;
await context.tracing.stop({ path: tracePath });
} else {
await context.tracing.stop();
}
},
});
test('example test', async ({ page }) => {
await page.goto('https://example.com');
// Test will save trace if it fails
});
Viewing traces
After collecting traces, view them using the Playwright Trace Viewer:
npx playwright show-trace traces/test.zip
Or start the trace viewer server:
npx playwright trace-viewer traces/
Configuration
Configure tracing in playwright.config.ts:
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
trace: 'on-first-retry', // 'on', 'off', 'retain-on-failure', 'on-first-retry'
},
});
Options:
'on': Record trace for each test
'off': Do not record trace
'retain-on-failure': Record trace for each test, but remove it if test passes
'on-first-retry': Record trace only when retrying a test for the first time