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.
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.
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.
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.
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:
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.

