The Trace Viewer is a standalone browser-based application for inspecting .zip trace archives produced by context.tracing. It renders recorded actions, DOM snapshots, screenshots, network traffic, console output, and source code in an interactive interface.
This page covers the Trace Viewer's UI component hierarchy, the HTTP server that serves trace data, and how DOM snapshots are replayed in iframes. For information on how traces are recorded (the tracing API, beforeSnapshot, afterSnapshot), see the Core API pages. For how the Trace Viewer is embedded into the live UI Mode workflow, see UI Mode. For the Recorder and code generation tooling, see Recorder and Code Generation.
The Trace Viewer consists of two parts:
startTraceViewerServer) that serves the React app bundle and responds to REST-style requests for trace data (actions, resources, snapshots, source files).Workbench component hierarchy.Diagram: Trace Viewer System Overview
Sources: packages/playwright-core/src/server/index.ts tests/config/traceViewerFixtures.ts155-196
The trace viewer is launched from the CLI via show-trace:
node packages/playwright-core/cli.js show-trace --port 0 [trace.zip]
startTraceViewerServer, openTraceViewerApp, and openTraceInBrowser are the three exported entry points from packages/playwright-core/src/server/index.ts31
Once running, the server:
--stdin flag that allows trace file paths to be pushed over stdin for multi-trace workflows.The fixture used in tests (tests/config/traceViewerFixtures.ts156-196) illustrates the lifecycle: the process writes Listening on http://... to stdout, a browser is launched, and the URL is loaded.
All UI code lives under packages/trace-viewer/src/ui/. The entry point is Workbench, which composes all sub-panels.
Diagram: Workbench Component Tree
Sources: packages/trace-viewer/src/ui/workbench.tsx348-404
The properties sidebar can be docked to the bottom (default) or the right. This is controlled by a persistent setting (propertiesSidebarLocation) toggled by toolbar buttons inside Workbench. The SplitView orientation switches between 'vertical' and 'horizontal' accordingly.
Workbench holds all cross-panel state. State is split into two categories (packages/trace-viewer/src/ui/workbench.tsx76-90):
| State variable | Scope | Purpose |
|---|---|---|
selectedNavigatorTab | UI setting | Which navigator tab is active (Actions/Metadata) |
selectedPropertiesTab | UI setting | Which properties tab is active |
sidebarLocation | UI setting | Bottom or right docking |
actionsFilter | UI setting | Which action categories are hidden |
selectedCallId | Per-model | Which action is selected |
selectedTime | Per-model | Time window filter on the timeline |
highlightedCallId | Per-model | Hovered action on timeline |
treeState | Per-model | Expansion state of the action tree |
The activeAction is resolved as highlightedAction ?? selectedAction. Most tabs render relative to activeAction. The selectedAction falls back to the failed action if present, or the last non-After-Hooks action.
Sources: packages/trace-viewer/src/ui/workbench.tsx76-147
ActionList (packages/trace-viewer/src/ui/actionList.tsx) renders the hierarchical action tree in the navigator panel.
Key behaviors:
buildActionTree(actions) from traceModel.ts to build a tree of ActionTreeItem nodes (supporting test.step, tracing.group, fixtures, etc.).TreeView<ActionTreeItem> from packages/web/src/components/treeView.tsx.renderAction(item.action, options), which shows:
action.title or a methodMetainfo lookup).renderTitleForCall parses {paramName} tokens in the title format string and substitutes parameter values inline, styled as action-title-param.Action Filtering:
ActionsFilterButton in workbench.tsx exposes a dialog to hide entire categories:
| Filter key | Hides |
|---|---|
getter | Getter-only API calls |
route | Network route registrations |
configuration | Configuration-only actions |
The hiddenActionsCount is shown as a badge on the filter button when any filter is active.
Sources: packages/trace-viewer/src/ui/actionList.tsx49-111 packages/trace-viewer/src/ui/workbench.tsx407-443
Timeline (packages/trace-viewer/src/ui/timeline.tsx) renders a horizontal time axis at the top of the workbench (hidden when hideTimeline is set, as in UI Mode's live view).
It maintains three lanes of colored bars:
| CSS class | Color | Data source |
|---|---|---|
.timeline-bar.action | Orange | ActionTraceEventInContext entries |
.timeline-bar.network | Blue | model.resources |
.timeline-bar.console-message | Purple | ConsoleEntry items |
.timeline-bar.action.error | Red | Actions with .error set |
Interaction:
selectedTime window. Actions outside the window are dimmed in ActionList.Position-to-time conversion is done by positionToTime / timeToPosition using the Boundaries object (min/max timestamps across the model).
Sources: packages/trace-viewer/src/ui/timeline.tsx41-289
FilmStrip (packages/trace-viewer/src/ui/filmStrip.tsx) renders screenshot thumbnail strips inside the timeline, one FilmStripLane per page.
200×45 pixels (tileSize).model.pages[i].screencastFrames.model.createRelativeUrl('sha1/' + frame.sha1).film-strip-hover) appears above the cursor, showing the screenshot at the hovered timestamp plus the current action title.Sources: packages/trace-viewer/src/ui/filmStrip.tsx38-150
SnapshotTabsView (packages/trace-viewer/src/ui/snapshotTab.tsx43-100) is the central panel showing the DOM state for the selected action.
Three snapshot variants are available per action:
| Tab | Source key | Description |
|---|---|---|
Action | inputSnapshot (fallback: afterSnapshot) | State at the moment of interaction (shows click cursor) |
Before | beforeSnapshot (fallback: previous action's afterSnapshot) | State just before the action ran |
After | afterSnapshot (fallback: last nested action's snapshot) | State after the action completed |
collectSnapshots(action) in snapshotTab.tsx implements this fallback logic (packages/trace-viewer/src/ui/snapshotTab.tsx374-416).
extendSnapshot(traceUri, snapshot, ...) builds three URLs per snapshot:
snapshotUrl → snapshot/{pageId}?trace=...&name=... — the iframe src.snapshotInfoUrl → snapshotInfo/{pageId}?... — fetched for viewport dimensions and page URL.popoutUrl → snapshot.html?r=...&trace=... — opened in a new tab via the toolbar button.Sources: packages/trace-viewer/src/ui/snapshotTab.tsx420-443
SnapshotView uses two <iframe> elements in a switcher pattern: one visible, one hidden. When a new snapshot URL arrives, the hidden iframe loads it; once loaded, visibility swaps. This eliminates flicker between actions (packages/trace-viewer/src/ui/snapshotTab.tsx102-192).
SnapshotWrapper measures the available container and scales the snapshot iframe to fit, preserving the recorded viewport aspect ratio. A BrowserFrame chrome is drawn around it (packages/trace-viewer/src/ui/snapshotTab.tsx194-233).
Diagram: Snapshot Data Flow
Sources: packages/trace-viewer/src/ui/snapshotTab.tsx43-460
InspectModeController runs inside the iframe when the "Pick Locator" button is active. It calls createRecorders(...) which walks the iframe's frame tree and attaches a Recorder instance to each frame window. The Recorder highlights elements under the cursor and calls back elementPicked(elementInfo) when clicked, setting highlightedElement which propagates to InspectorTab.
Sources: packages/trace-viewer/src/ui/snapshotTab.tsx245-321
Displays structured key-value pairs for the selected action: start time, duration, parameters, and return value. Renders via CallTab (not shown in files provided but referenced from workbench.tsx line 206).
Renders the action's internal log lines — timing-stamped messages from the browser automation engine (e.g., attempting click action, click action done).
ErrorsTab (packages/trace-viewer/src/ui/errorsTab.tsx87-150) renders all errors from model.errorDescriptors. For each error:
renderAction).A "Copy prompt" button (CopyPromptButton) assembles a formatted prompt string including the error message, code frame context (surrounding source lines), and test metadata, suitable for pasting into an LLM.
useErrorsTabModel aggregates errors via model.errorDescriptors into a Map<string, ErrorDescription> deduplicated by message.
Sources: packages/trace-viewer/src/ui/errorsTab.tsx
SourceTab (packages/trace-viewer/src/ui/sourceTab.tsx73-124) renders the test source file at the stack frame of the selected action.
sha1/src@{hash}.txt), falling back to file?path={encoded}.CodeMirrorWrapper renders the file with a running highlight on the active line and error highlights for inline failures.StackTraceView alongside shows all frames; clicking a frame changes selectedFrame to navigate the source.vscode://file//... URI.The calculateSha1 utility hashes a file path string (not content) using crypto.subtle.digest, used as a cache key.
Sources: packages/trace-viewer/src/ui/sourceTab.tsx
NetworkTab (referenced from workbench.tsx line 261) shows all network requests in the selectedTime window, or all requests if no time window is set. It supports filtering by:
Each request row shows method, status, MIME type, and an aborted or continued badge for routes. 404 responses are highlighted in red.
ConsoleTab shows browser console messages. Each entry has a severity icon (status-none, status-warning, status-error). Clicking an entry in the console can jump to the action that was active at that timestamp. When an action is selected, console entries are styled to indicate which were emitted during that action's time range.
AttachmentsTab (referenced from workbench.tsx line 267) lists all visibleAttachments from the model. It exposes revealedAttachmentCallId to scroll to an attachment linked from an action row badge.
MetadataView shows the trace's context information (project, browser, start time) in the navigator's Metadata tab.
WorkbenchLoader (not in the provided files but referenced via CSS at packages/trace-viewer/src/ui/workbenchLoader.css) provides the outer shell: a header bar with the Playwright logo, a drag-and-drop zone to load .zip files by dropping them in the browser, and a progress dialog for loading multi-file traces.
| Type | File | Role |
|---|---|---|
TraceModel | traceModel.ts | Root data model for a loaded trace |
ActionTraceEventInContext | traceModel.ts | Single action augmented with context info |
ActionTreeItem | traceModel.ts | Tree node for ActionList / TreeView |
Boundaries | geometry.ts | { minimum, maximum } timestamps for timeline scaling |
SnapshotInfo | snapshotTab.tsx | { url, viewport, timestamp } fetched from snapshotInfo/ |
Snapshots | snapshotTab.tsx | { action?, before?, after? } for a selected action |
FilmStripPreviewPoint | filmStrip.tsx | { x, clientY, action } for hover preview |
WorkbenchProps | workbench.tsx | Props type for the top-level Workbench component |
ErrorsTabModel | errorsTab.tsx | { errors: Map<string, ErrorDescription> } |
Sources: packages/trace-viewer/src/ui/workbench.tsx50-63 packages/trace-viewer/src/ui/snapshotTab.tsx323-372 packages/trace-viewer/src/ui/filmStrip.tsx27-32 packages/trace-viewer/src/ui/errorsTab.tsx43-55
TraceModelContext (imported in workbench.tsx and used in sourceTab.tsx, filmStrip.tsx, and errorsTab.tsx) is a React context that holds the current TraceModel. It allows deeply nested components to access the model without prop-drilling. It is provided by Workbench at packages/trace-viewer/src/ui/workbench.tsx67-69 and consumed via useTraceModel().
When the Trace Viewer is embedded inside UI Mode (5.2) rather than launched standalone, Workbench is used directly with hideTimeline={false} and isLive={true} while a test is running. The status and annotations props are also populated to show the current pass/fail state and test annotations in the workbench-run-status bar above the ActionList.
Sources: packages/trace-viewer/src/ui/workbench.tsx314-338 tests/playwright-test/ui-mode-trace.spec.ts700-724
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.