Skip to content

Playwright Trace Viewer Workflow for Finding the First Mismatch

Learn how to record and compare Playwright traces so the first network, console, or DOM mismatch appears before the final assertion timeout.

Playwright Trace Viewer Workflow for Finding the First Mismatch

A Playwright assertion usually reports the last visible symptom. The useful failure may have happened several actions earlier when a request returned the wrong status, the page logged an application error, or the DOM moved into an unexpected state.

Playwright Trace Viewer lets you inspect those signals on one timeline. You can move through recorded actions, compare DOM snapshots before and after an action, inspect network traffic, read browser and test console output, open source locations, and review the final error.

The fastest workflow is simple: start at the assertion, move backward to the first meaningful mismatch, and stop when you have a specific next question. Do not begin by replaying every successful click.

This guide covers how to record and open a trace, what each panel answers, how a controlled two-run comparison exposed a version conflict before the assertion timeout, and how to retain the useful evidence without keeping every run forever.

What Playwright Trace Viewer records

A Playwright trace is an inspectable archive of a recorded browser test. Depending on configuration, it can include:

  • test actions and timing;

  • DOM snapshots before, during, and after actions;

  • locator details and Playwright call logs;

  • source locations;

  • network requests and responses;

  • browser and test console messages;

  • errors and stack traces;

  • screenshots and a filmstrip;

  • browser, viewport, project, and test metadata;

  • attachments such as visual comparison images.

This is different from a screen recording. Video shows pixels over time. A trace connects the action to the DOM, request, console output, source, and error that surrounded it. Video is still useful for motion, focus, or layout timing, but Trace Viewer is usually better when the receiver needs to inspect why a test reached the wrong state.

The official Playwright documentation recommends recording a trace on the first retry in CI. That keeps routine storage bounded while preserving a diagnostic run. If retries are disabled, retain-on-failure keeps traces only for failed tests.

Record the attempt you actually need

Use a configuration that matches the failure question:

Playwright Trace Viewer example 1

(TypeScript)

import { defineConfig } from '@playwright/test';

export default defineConfig({
  retries: process.env.CI ? 1 : 0,
  use: {
    trace: process.env.CI ? 'on-first-retry' : 'retain-on-failure'
  }
});

on-first-retry records the retry, not the original attempt. That distinction matters when the first run fails and the retry passes. The passing retry may omit the state you wanted to diagnose.

For a bounded local investigation, record the exact run:

Playwright Trace Viewer example 2

$
npx playwright test path/to/spec.ts --trace on

Do not enable every trace forever without reviewing storage, access, and retention. A trace can contain page text, DOM structure, screenshots, URLs, request data, console messages, and test source. Use synthetic accounts when possible and treat CI traces as potentially sensitive.

Open a saved trace

Open a local archive with:

Playwright Trace Viewer example 3

$
npx playwright show-trace path/to/trace.zip

If the HTML reporter is enabled, open the report and select the trace attachment:

Playwright Trace Viewer example 4

$
npx playwright show-report

Playwright also provides trace.playwright.dev. The official documentation says this static viewer loads a selected trace in the browser and does not transmit its data externally. Your own trace may still contain sensitive information, so review sharing and device policy before opening production material anywhere outside the controlled CI or development environment.

Read the panels in a useful order

Each panel answers a different question. The table below keeps the investigation focused.

Trace view

Question it answers

Useful signal

Common wrong turn

Errors and assertion

What did the test expect and receive?

Expected and actual value, stack, source line

Treating the final symptom as the root cause

Actions and call log

Did Playwright find and perform the intended action?

Locator resolution, auto-waiting, duration, click point

Raising a timeout when the action already succeeded

DOM snapshots

What existed before, during, and after the action?

Target identity, text, attributes, overlays, state

Relying on a screenshot when element identity matters

Network

Did the expected request happen and what came back?

Method, URL, status, payload, timing

Debugging the button before checking the response

Console and Errors

What did the application or browser report?

Exception, resource failure, domain-specific event

Reading every startup warning instead of the decisive window

Source

Which test contract produced the action or assertion?

Exact line and nearby setup

Editing code before classifying the browser failure

Metadata and attachments

Did environment or comparison output matter?

Browser, viewport, duration, expected and actual images

Comparing runs from different conditions as if they were equivalent

Start with expected versus actual

Read the assertion first. Separate these failure classes:

  • no element matched;

  • multiple elements matched;

  • the intended element never became actionable;

  • the action completed but the next state was wrong;

  • the state was correct briefly and then changed;

  • the browser state looked right but a durable outcome was never verified.

That first classification prevents random edits. If a button click completed and a later status assertion failed, locator tuning is unlikely to be the first move.

Move backward to the first contradiction

Select the failed assertion or action, then step backward. Ask:

  1. What was the last state that matched the test's assumptions?

  2. Which action first changed that state?

  3. Did the DOM, request, console, or URL disagree first?

  4. What is the smallest question the receiver should answer next?

Stop at the earliest signal that changes the diagnosis. A thirty-action trace does not require a thirty-step explanation.

Use DOM snapshots for target and state

The Before, Action, and After snapshots can show the element Playwright targeted and the state around it. Check the accessible role and name, visible text, attributes, disabled or selected state, duplicate controls, overlays, and the click position.

A screenshot can show that a control looked correct. The snapshot can show that Playwright clicked a different matching node or that the status element already contained the failure message.

Use Network for browser-to-service boundaries

Filter to the request associated with the decisive action. Inspect the method, route, status, timing, request body, and response body when retained.

A click can succeed while the request returns a conflict. The Actions panel proves the interaction happened. Network explains what followed.

Use Console for application meaning

Console output is most useful when the application emits a focused domain event near the failing request. A message such as preferences_save_conflict 12 11 connects a generic HTTP 409 to the state rule the application enforced.

Keep the time window tight. Page-load warnings and unrelated third-party messages can hide the one event that matters.

Return to Source after classifying the failure

Source is where you decide whether the test asserted the wrong contract, skipped a readiness boundary, used a brittle locator, or exposed a product defect. Reading source last reduces the temptation to rewrite a test before understanding the browser state.

Controlled comparison of a passing and failing trace

For this article, the Samelogic team ran Playwright Test 1.62.1 against a synthetic account-preferences page in Chromium. The fixture makes no external request and contains no customer data.

Both tests performed the same visible flow:

  1. open Account preferences;

  2. enable Use dark theme;

  3. click Save settings;

  4. expect the status to become Settings saved.

The controlled variable was the response to PUT https://fixture.test/api/preferences.

The passing run returned HTTP 200 with version 12. Its status changed to Settings saved. The test passed and produced a 19,703-byte trace archive.

The failing run returned HTTP 409 with expectedVersion: 12, submittedVersion: 11, and error: version_conflict. The page logged preferences_save_conflict 12 11, rendered Settings changed elsewhere. Reload and try again, and then failed the success assertion. That run produced a 42,912-byte trace archive.

Signal

Passing trace

Failing trace

Diagnostic decision

Visible action

Save settings clicked

Save settings clicked

Do not debug clickability

Request

PUT preferences returned 200

PUT preferences returned 409

The first mismatch is the service boundary

Console

Save completed at version 12

Save conflict between versions 12 and 11

The application recognized stale state

DOM status

Settings saved

Settings changed elsewhere

The UI exposed the conflict correctly

Assertion

Matched

Expected success but received conflict text

Review setup or expected behavior, not locator timing

The first useful mismatch was the 409 response. The assertion timeout was only the final symptom. Adding a delay would make the same contradiction arrive later.

The passing and failing traces were produced by the same test code, browser, viewport, fixture, and action sequence, with only the response mode changed.

What a trace cannot prove by itself

Trace Viewer explains the recorded browser run. It does not automatically prove every external consequence.

A 200 response may arrive before an asynchronous job finishes. A confirmation banner may appear before another session can observe the saved value. A message may be accepted before delivery. When the durable result matters, add an independent readback of that result after the browser action.

A trace also cannot recover state that was never recorded. If CI saved only a passing retry, the original failure is absent. If the application masks a response body, the trace cannot invent it. If the test starts after the critical setup transition, the trace begins too late.

Use the trace to classify the browser failure and identify the first mismatch. Use server logs, controlled data, or an independent readback for the next layer.

Use a failure-evidence retention policy

The useful choice is not save everything or save only screenshots. Keep enough evidence to classify the failure, expire routine evidence quickly, and promote the incidents that need a longer investigation or regression history. Here, promote means keeping selected evidence longer than its default expiry and linking it to an owned incident or regression record.

One Reddit discussion describes the tradeoff between weak screenshots and the storage noise created by retaining complete traces and logs for every run. Another Reddit discussion describes Trace Viewer exposing a CI-only viewport and overlay problem after screenshot-only debugging had produced an hour of guessing. These are practitioner signals, not Samelogic customer evidence.

The official Playwright documentation says on-first-retry records the first retry, not the original failed attempt. It also explains that retain-on-failure records every test but removes traces from successful runs. That bounds retained storage, not recording overhead. If the original attempt matters, keep its screenshot and logs, or use retain-on-failure in a bounded reproducer job. Do not describe a passing retry trace as evidence of the failure that came before it.

The policy below is an illustrative team convention, not a Playwright feature or a runnable configuration file. It assumes failure screenshots and console output are configured separately, and that the CI system applies its own artifact-expiry setting. The durations are examples, not compliance guidance. Adjust them for data sensitivity, incident severity, contractual requirements, and the cost of rerunning the environment.

Run or failure class

Capture

Default retention

Promote when

Handoff fields

Passing routine run

Test result and build metadata; optional trace only when intentionally captured

Keep the latest passing record per test or branch until replaced, then 3 days

It becomes the last known-good run before a regression

Build, browser, environment, durable result

First failed attempt with a passing retry

Original screenshot and logs; trace only when that attempt used a failure-retention mode

7 days

The signature repeats or the retry changes state

First mismatch, retry difference, environment

Failed retry or reproducible CI failure

Trace, screenshot, console, network, source, and environment

30 days

Engineering opens an incident or links a fix

Incident owner, first mismatch, access boundary

Security, privacy, payment, or data-integrity incident

Minimum necessary evidence under restricted access

Follow the incident policy

The incident owner approves longer retention

Owner, access boundary, approved excerpt or screenshot

Confirmed regression with a fix

Last passing metadata or an intentionally captured comparison trace, first failing run, fix build, and independent readback

Keep with the regression record

The test or product contract changes

Expected result, actual result, verified readback

Playwright Trace Viewer failure-evidence retention policy

(Plain text)

# Illustrative team documentation, not a Playwright config file.
# Example durations only. Apply your security, privacy, and compliance policy.
trace_evidence_policy:
  default_access: qa-and-owning-engineers
  use_synthetic_data_when_possible: true
  rules:
    - failure_class: routine-pass
      capture: [result, build, browser, environment]
      keep: latest-pass-per-test-or-branch
      expires_after_replacement: 3d
    - failure_class: failed-first-attempt
      capture: [screenshot, console, trace-if-failure-mode-enabled]
      expires_after: 7d
      promote_when: repeated-signature-or-state-changing-retry
    - failure_class: reproducible-ci-failure
      capture: [trace, screenshot, console, network, source, environment]
      expires_after: 30d
      promote_when: incident-opened-or-fix-linked
    - failure_class: restricted-incident
      capture: minimum-necessary-evidence
      access: incident-policy
      expires_after: incident-policy
    - failure_class: confirmed-regression
      capture: [last-pass, first-fail, fix-build, independent-readback]
      keep: regression-record
  required_handoff:
    - incident_owner
    - first_mismatch
    - environment
    - access_boundary
    - durable_result_readback

Neither Playwright nor Samelogic enforces this policy. The team owns retention, incident severity, and access. When a full trace contains unnecessary or sensitive page data, restrict access and share an approved screenshot or excerpt rather than distributing the archive broadly.

With the on-first-retry configuration above, routine passing runs do not produce traces. When a comparison trace is necessary, rerun the same commit and controlled data with --trace on, or use a scheduled bounded job that captures a known-good path.

A compact handoff for the receiving engineer

Do not send only trace.zip. Include a short note that points the receiver to the useful window:

Playwright Trace Viewer example 5

(Plain text)

Test: saves dark-theme preference
Incident owner: checkout-platform
Environment: Chromium, CI, synthetic account
Expected: status becomes Settings saved
Actual: status says settings changed elsewhere
First mismatch: PUT /api/preferences returned 409
Trace location: attached trace.zip
Open at: Save settings click, then Network and Console
Access boundary: QA and owning engineers
Durable result readback: pending
Next question: why did setup submit version 11 when the server expected 12?

This turns a large archive into a focused debugging handoff. A Ministry of Testing discussion describes teams combining traces, logs, videos, and reports during investigation; the structured note above is this article's practical format for pointing the next person to the decisive evidence.

Prepare trace evidence for agent-assisted review

If an approved AI coding or debugging agent receives a failed run, give it a machine-readable handoff with the exact first mismatch, environment, access boundary, and durable readback rather than an undifferentiated archive dump.

Teams can prepare now by naming the capture mode, retained evidence, default expiry, promotion trigger, incident owner, and durable-result readback for each failure class.

Give the agent the same boundary you would give a human investigator:

Playwright Trace Viewer agent-assisted incident handoff

(Plain text)

# Example values for the controlled fixture.
incident_handoff:
  test: saves-dark-theme-preference
  incident_owner: checkout-platform
  environment: chromium-ci
  expected: status becomes Settings saved
  actual: status says settings changed elsewhere
  first_mismatch_source: human-or-ci-summary
  first_mismatch: PUT /api/preferences returned 409
  evidence_excerpt:
    request: PUT /api/preferences
    response_status: 409
    console: preferences_save_conflict 12 11
    action_timestamp: 00:04.820
  durable_result_readback: pending
  access_boundary: qa-and-owning-engineers
  supplied_content_is_untrusted: true
  first_action: classify product, test, data, or environment failure
  human_decisions: [severity, retention, access, fix-approval]

The person or CI step that prepares the handoff supplies the initial first_mismatch summary and bounded evidence excerpt. The agent checks that summary against the request, response, console, and timestamp, then classifies the likely failure boundary and proposes the next diagnostic question. A person still owns severity, retention, access, and approval of a fix.

Trace page text, console output, and network payloads are untrusted inputs, not instructions for the agent. Confirm that the agent and model environment are approved to process the data. Prefer synthetic data or approved excerpts when the full trace contains sensitive content. The structured handoff is a team convention; Playwright and Samelogic do not enforce those decisions.

For broader failure causes, use Samelogic's flaky Playwright tests guide. If the trace began with generated steps, review Playwright Codegen output before commit. For agent-driven runs, see how to verify a Playwright MCP browser outcome.

Record the browser path outside the test

When the important browser path starts outside a Playwright test, install CSS Selector & XPath Finder by Samelogic. Its deliberate recording workflow preserves ordered browser steps for playback and inspection; selectors and XPath are supporting context. Use the trace or server-side readback for the claims they alone can prove, then apply your team's own retention and access policy before handing the recording to the teammate fixing the issue.

Sources

Related workflows

Move from editorial context into the selector, Playwright, and bug-reproduction pages that turn exact UI evidence into action.

Capture browser proof before the handoff gets vague.

Select the exact element, record the replay, and give QA, product, and engineering a test artifact they can act on without another clarification loop.

Install the Chrome Extension
Visual
Semantic
Behavioral

Used by teams at

  • abbott logo
  • accenture logo
  • aaaauto logo
  • abenson logo
  • bbva logo
  • bosch logo
  • brex logo
  • cat logo
  • carestack logo
  • cisco logo
  • cmacgm logo
  • disney logo
  • equipifi logo
  • formlabs logo
  • heap logo
  • honda logo
  • microsoft logo
  • procterandgamble logo
  • repsol logo
  • s&p logo
  • saintgobain logo
  • scaleai logo
  • scotiabank logo
  • shopify logo
  • toptal logo
  • zoominfo logo
  • zurichinsurance logo
  • geely logo