Debugging, traces & UI mode

Break things, debug them and analyze with the trace viewer.

You recorded your first tests in the previous lesson — but recorded code is rarely the code you ship. Selectors break, pages take a beat to render, the network does something unexpected. Before we write any more tests, let's learn how to figure out why a test failed.

Playwright ships an unusually rich set of debugging tools: UI mode for live development, --debug for terminal step-through, the VS Code extension for breakpoint debugging, and traces (which I like to call "time-travel snapshots") for runs that already happened (CI failures, a co-worker's machine, last night's nightly run).


UI mode — this is the way

For years the community begged for a "watch mode" from the Playwright team. It never came. Instead we got something much better — UI mode.

Playwright UI mode

$ npx playwright test --ui

Inside UI mode you get, all in one window:

  • Watch mode — tests re-run on every file save
  • DOM snapshots — hover over any step to time-travel into the page
  • Network waterfall — every request the test made
  • Console + errors panel — did the page throw? You'll see it
  • Locator picker — point-and-click to generate a robust locator
  • Trace Viewer built in — pause on any step and scrub

Open it. Live in it. You'll thank yourself once the tests start failing.

Note

You can also combine --ui with --headed which is my preferred way of using UI mode.

Todos

Debugging via the Playwright inspector using --debug

Sometimes you just want to step through a test in the terminal without leaving the keyboard. The --debug flag opens the Playwright Inspector and pauses on every action.

Debugging session in the terminal

$ npx playwright test --debug
$ npx playwright test tests/shop.spec.ts --debug

Check all available test options via npx playwright test --help.

Note

To only run a single test in one file from the command line, leverage test.only.

Todo

Debugging in VS Code

For gnarly debugging sessions the official VS Code extension is fantastic — it lets you set breakpoints, inspect variables, and step through your test like any other Node script. It's a native debugging experience for your controlled browser session.

Debugging session in VS Code

Note

If you're running and debugging tests, ensure that you have ticked Show browser to see what's happening.

Show browser option

Todo

Traces — time travel for CI failures

The debugger is great while you're writing tests. But what about a run that failed in CI, on your colleague's machine, or in last night's nightly? You can't attach a debugger after the fact — but you can read a trace.

Debugging a trace

A trace is a snapshot recording of every action your test performed. It includes console messages, network information, full HTML snapshots of every step, screenshots, and much more.

By default Playwright doesn't collect traces locally (they're heavy). To learn what they're about, flip them on for every run in playwright.config.ts:

export default defineConfig({
  use: {
    trace: "on",
  },
  // ...
});

Now run your tests:

$ npx playwright test

trace: on writes a fresh trace.zip per test under test-results/. There are three good ways to open them.

From the HTML report

Whenever a trace was recorded, the generated HTML report links to it.

Traces in HTML report

From the command line

$ npx playwright show-trace test-results/example-has-title-chromium/trace.zip

The trace viewer visualizes every test step, a timeline, and a full HTML snapshot of the page at that step. It's time-travel debugging for your end-to-end tests.

From the online viewer

You don't need Playwright installed at all to read a trace — drag a trace.zip onto trace.playwright.dev and it opens in your browser.

Trace dialog on trace.playwright.dev

Note

In production you probably don't want trace: "on" (every run, every test generates a zip). The defaults you'll most often reach for are "on-first-retry" and "retain-on-failure" — collect traces only when something actually went wrong.

Todo

TODO Speedboard — the timeline view (Playwright 1.58+)

Playwright 1.58 added the Speedboard — a horizontal timeline inside the trace viewer that shows each action with its duration, navigations, and network activity stacked side-by-side. It's the fastest way to spot the part of a test that's slow or stuck.

The Speedboard lives in the trace viewer, both in UI mode and in any show-trace session — no extra config needed. Open a trace and look for the timeline strip above the action list.

It's especially useful when:

  • A test is "slow but passes" and you want to know which step ate the budget
  • An action waited for the network and you want to see which request
  • A flaky test only fails when one specific request is delayed
Note

The Speedboard is part of the trace viewer, so the same trace: "on" / "on-first-retry" setting controls whether you get one.


Hands-on — break it, then fix it

The fastest way to get fluent with the debugging tools is to break a working test on purpose and recover from it.

TODO provide code snippet with a broken test...

Exercise 1 of 3

Break a locator

  1. Open one of the tests you recorded in the previous lesson.
  2. Pick a getByRole / getByLabel call and change its name to something that doesn't exist on the page (e.g. "Add to bucket" instead of "Add to cart").
  3. Run the test — it should fail with a locator timeout.
Exercise 2 of 3

Find it with UI mode

  1. Run the failing test in UI mode: npx playwright test --ui.
  2. Click the failed step in the action list.
  3. Use the DOM snapshot to inspect what was actually on the page when the locator timed out.
  4. Open the locator picker and click the real "Add to cart" button — copy the suggested locator.
  5. Paste it back in, save, and watch UI mode re-run the test green.
Exercise 3 of 3

Read the trace

  1. Set trace: "on" in playwright.config.ts.
  2. Re-break the locator and run npx playwright test (no UI mode this time).
  3. Open the HTML report (npx playwright show-report) and click into the failed test's trace.
  4. Find the failed step in the Speedboard timeline. How long did Playwright wait before giving up?