Skip to main content
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
});
options.name
string
Trace name. If not specified, the trace name is generated from the test file name and title.
options.title
string
Trace title to display in the Trace Viewer.
options.screenshots
boolean
default:"false"
Whether to capture screenshots during tracing.
options.snapshots
boolean
default:"false"
Whether to capture DOM snapshots during tracing.
options.sources
boolean
default:"false"
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'
});
options.name
string
Chunk name.
options.title
string
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' });
options.path
string
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' });
options.path
string
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 }
});
name
string
required
Group name.
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

Build docs developers (and LLMs) love