Samelogic Logo
ComparePricing

Playwright Debugging for Tests That Pass Alone and Fail in a Suite

Debug Playwright tests that pass alone by preserving predecessor state, locating the first mismatch, and sending a receiver-ready failure packet.

Playwright Debugging for Tests That Pass Alone and Fail in a Suite

A Playwright test that passes alone but fails in a suite usually has a missing predecessor.

Another test, setup hook, worker, reused page, cached response, or shared account changed the browser or backend state before the visible failure. Rerunning only the red test removes that predecessor, so the rerun passes and the most useful evidence disappears.

The practical Playwright debugging workflow is to reproduce the same execution boundary, preserve the state before the failing action, locate the first mismatch, and package the result for the teammate fixing it. This guide shows which Playwright tool to use at each stage and includes a controlled browser-state experiment.

Start with the failure shape

Before opening Inspector or changing a timeout, classify the failure.

Failure shape

First question

Best first move

Fails alone and in the suite

What action or assertion first disagrees?

Run the single test with Inspector or UI Mode

Passes alone and fails after one test

What state did the predecessor leave behind?

Run the pair in the original order and capture a trace

Fails only in parallel

Which account, file, port, or backend record is shared?

Repeat with one worker, then compare resource ownership

Fails only in CI

What differs in browser, viewport, clock, network, secrets, or service readiness?

Preserve the CI trace, logs, and environment facts

Passes on retry

What did the first attempt change before the retry began?

Retain the first-attempt trace and compare starting state

The key rule is simple: reproduce the smallest sequence that still fails. A single-test rerun is useful only when it preserves the condition that created the failure.

Use the Playwright debugging tools in the right order

Playwright offers several debugging surfaces. They answer different questions.

Inspector and UI Mode for live action diagnosis

Use Inspector when you can reproduce the problem locally and need to step through actions, inspect locator matches, or read actionability logs. Playwright's official debugging guide recommends the VS Code extension for live debugging and documents the --debug flag for Inspector.

Playwright debugging example 1

$
npx playwright test tests/project-settings.spec.ts --debug

Inspector is strongest when the problem is present in the current run. It is weaker when pausing or rerunning changes the timing, order, or stored state that made the suite fail.

Verbose API logs for action mechanics

Use Playwright's API logs when you need to know what the runner attempted, which locator resolved, and which actionability condition remained pending.

Playwright debugging example 2

$
DEBUG=pw:api npx playwright test tests/project-settings.spec.ts

API logs can explain why a click never happened. They do not automatically explain why the browser started the test with the wrong role, record, feature flag, or cached response.

Trace Viewer for a completed failure

Use a trace when the failure is intermittent, CI-only, order-dependent, or timing-sensitive. Trace Viewer preserves actions, DOM snapshots, console messages, network activity, source context, and action logs from the completed run.

For a suite-only failure, record the predecessor and failing test in the same diagnostic run. Then compare the last known-good state with the first contradictory state.

The detailed Playwright Trace Viewer workflow explains how to move from the final assertion back to that first mismatch.

Browser and application state readback for durable outcomes

A successful Playwright action means the browser accepted an action. It does not prove the intended state survived navigation, asynchronous work, another test, or a backend write.

Read back the state that matters. Depending on the failure, that can include:

  • the current URL and visible role;

  • a local storage or session storage key;

  • the response body from a save request;

  • the selected record ID;

  • a cookie or feature flag;

  • the backend value after the UI reports success.

Keep the readback narrow and privacy-safe. The goal is not to dump everything. It is to preserve the one state difference that changes the receiver's next action.

Controlled experiment with a leaking browser role

The Samelogic team built a synthetic project-settings page with two roles. A viewer sees ordinary settings. An admin also sees a destructive Delete project control. The page reads the role from local storage.

We ran two modes in headless Google Chrome through Playwright on September 1, 2026. Each mode was repeated five times from a fresh browser launch.

Shared-context mode

The predecessor step sets the role to admin. The receiver step then opens the project-settings page while reusing the same browser context. The receiver expects a clean viewer state.

The result was deterministic. Every repetition opened as Role admin, the stored role remained admin, and the destructive control stayed visible. The receiver check disagreed with its expected starting state before it performed any business action.

Isolated-context mode

The predecessor ran in one browser context. The receiver opened in a new context. The browser process was reused, but cookies, local storage, and session storage were not.

Every repetition opened as Role viewer, the role key was absent, and the destructive control was hidden.

Observation

Shared context

Isolated contexts

Predecessor role

Admin

Admin

Receiver stored role

Admin

Absent

Receiver visible role

Admin

Viewer

Destructive control

Visible

Hidden

First mismatch

Receiver starts with predecessor state

No mismatch

This experiment does not represent a customer incident. It isolates one common failure mechanism: cleanup-based reuse left browser state behind, while a new browser context removed it.

Playwright's isolation documentation describes this design directly. Each Playwright Test test receives an isolated browser context by default. The documentation also warns that cleanup between tests is easy to get wrong and that some state cannot be cleaned reliably.

A runnable isolation pattern

When the test runner owns the page fixture, keep the default per-test context. Avoid sharing a page or context across tests for speed unless the suite explicitly proves that reuse is safe.

Playwright debugging example 3

(TypeScript)

import { test, expect } from '@playwright/test';

test('admin can see destructive controls', async ({ page }) => {
  await page.goto('/project/settings');
  await page.evaluate(() => localStorage.setItem('role', 'admin'));
  await page.reload();
  await expect(page.getByRole('button', { name: 'Delete project' })).toBeVisible();
});

test('viewer cannot see destructive controls', async ({ page }) => {
  await page.goto('/project/settings');
  await expect(page.getByText('Role viewer')).toBeVisible();
  await expect(page.getByRole('button', { name: 'Delete project' })).toBeHidden();
});

If this still fails only in the suite, the shared state may be outside the browser context. Look for a reused user account, backend record, service worker, file, test database, or worker-scoped fixture.

Debug suite-only failures with this sequence

1. Preserve the original order

Record the failing test's immediate predecessor, worker count, project, browser, retry number, and account or fixture identity. Do not start by shuffling tests or adding retries.

2. Reduce to the smallest failing sequence

Run the predecessor and failing test together in their original order. If the pair passes, add the next nearest predecessor until the failure returns. This is sequence reduction, not single-test isolation.

3. Compare starting state before the first action

At the beginning of the failing test, read the state that the test assumes. For the controlled example, the decisive readback was the role key and the visibility of the destructive control.

Do this before clicking, navigating again, or running cleanup. Otherwise the test may overwrite the evidence.

4. Find the first mismatch

The final assertion may say a button was visible when it should have been hidden. The first mismatch happened earlier: the receiver test started as an admin.

Name the earliest disagreement in plain language. Do not jump from a symptom to an unproved root cause.

5. Choose the tool that preserves that mismatch

  • Use Inspector when the mismatch reproduces live without changing timing.

  • Use API logs when the action mechanics are unclear.

  • Use Trace Viewer when the completed order, DOM, network, or console history matters.

  • Use explicit state readback when the durable browser or backend value matters.

A practitioner discussion in the Ministry of Testing community reaches a similar practical conclusion from different workflows. Contributors describe using CI videos, Inspector, Trace Viewer, logs, screenshots, DOM snapshots, and backend timestamps. The useful artifact depends on the failure, but context beyond the final error is a recurring need.

6. Fix ownership before adding waits

If the mismatch is shared state, longer waits only make the leak slower. Prefer one of these fixes:

  • restore the default per-test browser context;

  • replace worker-scoped mutable fixtures with test-scoped fixtures;

  • allocate a unique account or record per test;

  • reset backend state through a verified API;

  • wait for a specific durable condition rather than arbitrary time;

  • remove dependencies on test order.

7. Prove the fix under the original boundary

Run the reduced failing sequence repeatedly with the original worker and retry settings. Then run the relevant suite. Confirm that the receiver starts from the intended state and that the expected backend or browser value survives.

Send a receiver-ready failure packet

A screenshot of the red assertion is rarely enough for an order-dependent failure. Send the teammate fixing it a bounded packet:

Playwright debugging example 4

(Plain text)

Failure shape
Passes alone and fails after the admin settings test

Smallest failing sequence
admin test followed by viewer test in the same shared context

Expected starting state
viewer role, no stored role key, Delete project hidden

Actual starting state
admin role, role key equals admin, Delete project visible

First mismatch
viewer test begins with predecessor browser state

Artifacts
trace from the reduced sequence, focused state readback, relevant API log

Next question
Which fixture or helper owns the shared browser context?

This packet gives the receiver a reproducible boundary and one next question. It avoids claiming a root cause before the fixture ownership is inspected.

Common Playwright debugging mistakes

Debugging only the final assertion

The assertion reports where the test noticed the problem, not necessarily where the problem began. Walk backward to the first mismatch.

Running only the failing test

For an order-dependent failure, this removes the predecessor. Reduce the sequence without deleting the condition.

Turning on every artifact forever

Full video, trace, screenshots, verbose logs, and network capture on every passing test can create noise and cost. Retain richer artifacts on first failure or during a bounded diagnostic run.

Reusing contexts to save time

Browser contexts are designed to be fast and isolated. Measure before trading isolation for reuse. A faster suite that produces unexplained order failures is not cheaper to operate.

Treating a retry as a fix

A retry can pass because the first attempt changed the state. Preserve the first attempt and compare both starting states.

The practical Playwright debugging rule

Match the tool to the missing fact.

Use Inspector for a live action, API logs for runner mechanics, Trace Viewer for completed browser history, and explicit readback for durable state. When a test passes alone, keep the predecessor in the reproduction until you can name the first state difference.

If the problem begins before the final screen, install CSS Selector & XPath Finder by Samelogic, deliberately start capture before the state-changing sequence, and send that bounded path to the teammate investigating it. Samelogic capture is initiated by the practitioner. It is not passive session replay.

If the test originated from generated code, review the locator and assertion choices with the Playwright Codegen commit checklist. For browser-agent runs, separate action acceptance from durable outcome using the Playwright MCP verification guide.

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