Implementation:Microsoft Playwright Tracing Start
| Knowledge Sources | |
|---|---|
| Domains | Debugging, Testing |
| Last Updated | 2026-02-11 00:00 GMT |
Overview
Concrete API for initiating trace recording on a Playwright BrowserContext or APIRequestContext, provided by the Playwright library.
Description
The Tracing class in Playwright's server-side implementation manages the lifecycle of trace recording. The start() method initializes the recording infrastructure by creating file paths, allocating a RecordingState object, and conditionally starting the HAR tracer for network capture. The subsequent startChunk() method begins an actual recording segment within the initialized infrastructure.
On the server side (packages/playwright-core/src/server/trace/recorder/tracing.ts), the Tracing class extends SdkObject and implements InstrumentationListener, SnapshotterDelegate, and HarTracerDelegate interfaces. This allows it to receive callbacks for API calls, DOM snapshots, and network events respectively.
On the client side (packages/playwright-core/src/client/tracing.ts), the Tracing class provides the public API that developers use. Calling start() on the client sends tracingStart and tracingStartChunk channel messages to the server, then begins collecting client-side call stacks via _startCollectingStacks().
The constructor (server-side, Lines 95-127) accepts a BrowserContext or APIRequestContext and an optional tracesDir. It initializes a HarTracer for network capture, creates a Snapshotter for DOM capture (only for BrowserContext), and prepares the initial context-options trace event with metadata about the browser, platform, and Playwright version.
Usage
Use this API to:
- Start tracing programmatically in scripts that use the Playwright library directly (not the test runner).
- Record multiple trace chunks within a single browser context by calling
startChunk()/stopChunk()repeatedly. - Enable live tracing for UI mode by passing
live: truein the options.
Code Reference
Source Location
- Repository: playwright
- Server implementation:
packages/playwright-core/src/server/trace/recorder/tracing.ts(Lines 79-176) - Client implementation:
packages/playwright-core/src/client/tracing.ts(Lines 38-51)
Signature
// Server-side TracerOptions
type TracerOptions = {
name?: string;
snapshots?: boolean;
screenshots?: boolean;
live?: boolean;
};
// Server-side RecordingState (internal)
type RecordingState = {
options: TracerOptions;
traceName: string;
networkFile: string;
traceFile: string;
tracesDir: string;
resourcesDir: string;
chunkOrdinal: number;
networkSha1s: Set<string>;
traceSha1s: Set<string>;
recording: boolean;
callIds: Set<string>;
groupStack: string[];
};
// Server-side Tracing class
class Tracing extends SdkObject implements InstrumentationListener,
SnapshotterDelegate, HarTracerDelegate {
constructor(context: BrowserContext | APIRequestContext,
tracesDir: string | undefined);
start(options: TracerOptions): void;
startChunk(progress: Progress,
options?: { name?: string; title?: string }): Promise<{ traceName: string }>;
stop(progress: Progress | undefined): Promise<void>;
stopChunk(progress: Progress | undefined,
params: TracingTracingStopChunkParams): Promise<{ artifact?: Artifact; entries?: NameValue[] }>;
}
// Client-side Tracing class
class Tracing extends ChannelOwner<TracingChannel> implements api.Tracing {
async start(options?: {
name?: string;
title?: string;
snapshots?: boolean;
screenshots?: boolean;
sources?: boolean;
_live?: boolean;
}): Promise<void>;
async startChunk(options?: { name?: string; title?: string }): Promise<void>;
async stop(options?: { path?: string }): Promise<void>;
async stopChunk(options?: { path?: string }): Promise<void>;
}
Import
// Client-side usage (via BrowserContext):
const context = await browser.newContext();
await context.tracing.start({ name: 'my-trace', snapshots: true, screenshots: true });
// CLI usage:
// npx playwright test --trace on
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| context | APIRequestContext | Yes | The context on which to enable tracing. Passed to the constructor. |
| tracesDir | undefined | No | Directory for storing trace files. Required for BrowserContext; a temp directory is created if not provided. |
| name | string |
No | Name for the trace. Used as the base filename for .trace and .network files. Defaults to a generated GUID.
|
| snapshots | boolean |
No | Whether to enable DOM snapshot capture. When true, starts the HarTracer and Snapshotter. |
| screenshots | boolean |
No | Whether to enable screencast frame capture. When true, starts screencast on all pages. |
| live | boolean |
No | Whether to flush trace events immediately for real-time viewing. Used in UI mode. |
| title | string |
No | A display title for the trace chunk. Included in the context-options event.
|
Outputs
| Name | Type | Description |
|---|---|---|
| RecordingState | object |
Internal state object (server-side) holding file paths, SHA1 sets, and recording flags. |
| .trace file | file |
Newline-delimited JSON file at {tracesDir}/{traceName}.trace containing action and snapshot events.
|
| .network file | file |
Newline-delimited JSON file at {tracesDir}/{traceName}.network containing HAR network entries.
|
| resources/ | directory |
Directory at {tracesDir}/resources/ containing SHA1-named resource blobs (images, stylesheets, etc.).
|
| traceName | string |
Returned by startChunk(), the name of the current trace chunk for client-side stack collection.
|
Usage Examples
Basic Example
// Start tracing with all options enabled
const context = await browser.newContext();
await context.tracing.start({
name: 'login-trace',
snapshots: true,
screenshots: true,
});
// Perform test actions
await page.goto('https://example.com/login');
await page.fill('#username', 'user');
await page.fill('#password', 'pass');
await page.click('#submit');
// Stop and save the trace
await context.tracing.stop({ path: 'traces/login-trace.zip' });
Chunk-based Recording Example
// Start the tracing infrastructure once
const context = await browser.newContext();
await context.tracing.start({ snapshots: true, screenshots: true });
// Record first test as a chunk
await context.tracing.startChunk({ title: 'Test: Login' });
await page.goto('https://example.com/login');
await page.fill('#username', 'user');
await context.tracing.stopChunk({ path: 'traces/login.zip' });
// Record second test as another chunk
await context.tracing.startChunk({ title: 'Test: Dashboard' });
await page.goto('https://example.com/dashboard');
await context.tracing.stopChunk({ path: 'traces/dashboard.zip' });
// Clean up
await context.tracing.stop();
Server-side Initialization Reference
// From tracing.ts:L141-176 - start() method
start(options: TracerOptions) {
if (this._isStopping)
throw new Error('Cannot start tracing while stopping');
if (this._state)
throw new Error('Tracing has been already started');
const traceName = options.name || createGuid();
const tracesDir = this._createTracesDirIfNeeded();
this._state = {
options,
traceName,
tracesDir,
traceFile: path.join(tracesDir, traceName + '.trace'),
networkFile: path.join(tracesDir, traceName + '.network'),
resourcesDir: path.join(tracesDir, 'resources'),
chunkOrdinal: 0,
traceSha1s: new Set(),
networkSha1s: new Set(),
recording: false,
callIds: new Set(),
groupStack: [],
};
this._fs.mkdir(this._state.resourcesDir);
this._fs.writeFile(this._state.networkFile, '');
if (options.snapshots)
this._harTracer.start({ omitScripts: !options.live });
}