Principle:Microsoft Playwright Run Tests with Tracing
| Knowledge Sources | |
|---|---|
| Domains | Debugging, Testing |
| Last Updated | 2026-02-11 00:00 GMT |
Overview
Initiating trace recording on a browser context to capture all actions, network traffic, and DOM snapshots during test execution.
Description
Once trace collection has been configured (see Configure_Trace_Collection), the next step is to actually start the trace recording machinery at the beginning of a test or test chunk. This principle concerns the mechanics of activating the various recording subsystems: the HAR (HTTP Archive) tracer for network requests, the snapshotter for DOM state, the screencast recorder for visual frames, and the event listener infrastructure for console messages, dialogs, and page errors.
Starting a trace is not a single atomic operation but rather a coordinated initialization of multiple recording subsystems:
- State allocation: A recording state object is created, holding references to the trace file, network file, resource directory, and SHA1 hash sets for deduplication.
- Network tracing: A HAR tracer is started to intercept and record all network requests and responses.
- DOM snapshotting: A snapshotter is initialized that injects a streaming script into every page frame, enabling on-demand DOM capture.
- Screencast recording: If screenshots are enabled, each page begins emitting screencast frames at regular intervals.
- Event listeners: Console messages, page errors, dialog events, and download events are wired to the trace event stream.
The principle of lazy initialization applies here: subsystems are only started if their corresponding configuration flags are enabled. For example, if snapshots are disabled, the snapshotter is not initialized, saving both CPU and memory overhead.
Usage
Apply this principle at the boundary between test setup and test execution:
- In automated test frameworks, trace start is called automatically by the test runner before each test (or test chunk) based on the configured trace mode.
- In manual scripting, developers call
tracing.start()explicitly on a browser context before performing the actions they want to trace. - In live/UI mode, tracing starts with the
liveflag enabled, causing trace events to be flushed immediately for real-time display.
Theoretical Basis
Trace initiation follows the coordinator pattern: a single entry point orchestrates the startup of multiple independent subsystems, each responsible for capturing a different aspect of the execution.
The abstract lifecycle is:
function startTracing(context, options):
state = allocateRecordingState(context, options)
writeContextCreatedEvent(state)
if options.snapshots:
startHarTracer(context, state)
startSnapshotter(context, state)
if options.screenshots:
for each page in context.pages:
startScreencast(page, state)
listenForNewPages(context, startScreencast)
registerInstrumentationListener(context, state)
registerEventListeners(context, state)
return state
Key design decisions:
- Idempotency guards: Attempting to start tracing when it is already active raises an error rather than silently resetting. This prevents data corruption from overlapping trace sessions.
- Chunk-based recording: Traces are divided into chunks (via
startChunk/stopChunk) so that a single tracing session can produce multiple trace files. This supports scenarios like per-test traces within a shared browser context. - Name-based file routing: Each trace chunk is associated with a name that determines the file paths for trace data, enabling multiple concurrent traces in the same directory.
The separation of start and startChunk is a key architectural distinction. start() initializes the recording infrastructure (HAR tracer, file system directories), while startChunk() begins a new recording segment within that infrastructure. This two-phase design avoids redundant setup when recording multiple test cases in the same browser context.