Debugging Intermediate

When Playwright tests fail, Claude Code becomes your debugging partner. Learn how to use AI to analyze failures, interpret trace files, fix broken locators, stabilize flaky tests, and build a systematic debugging workflow.

1. Using Claude Code to Debug Failing Tests

When a test fails, copy the error output and ask Claude Code to diagnose and fix it:

Claude Code Session
Claude > Run npx playwright test tests/e2e/cart.spec.ts and
         fix any failing tests

# Claude runs the test, sees the failure, reads the error,
# examines the test code and app code, then fixes the issue
Pro Tip: Include the full error output when asking Claude Code to debug. The more context it has about the failure, the faster it can identify the root cause.

2. Trace Viewer Analysis

Playwright's trace viewer records a detailed log of test execution, including screenshots, DOM snapshots, network requests, and console logs. Configure trace recording in your playwright.config.ts:

TypeScript (playwright.config.ts)
use: {
  // Record trace on first retry of a failed test
  trace: 'on-first-retry',

  // Or always record traces (useful during development)
  // trace: 'on',
}
Claude Code Session
Claude > Run the tests with tracing enabled, then open the trace
         viewer for any failed test:
         npx playwright test --trace on
         npx playwright show-trace test-results/*/trace.zip

3. Screenshot Comparison

When visual tests fail, Claude Code can help analyze the differences:

Claude Code Session
Claude > The visual snapshot test is failing. Look at the diff image
         in test-results/ and tell me what changed. Then decide
         if we should update the baseline or fix the code.

# To update baselines after intentional UI changes:
Claude > Update all screenshot baselines:
         npx playwright test --update-snapshots

4. Auto-Fixing Locators

Broken locators are the most common cause of test failures. Claude Code can read your updated HTML and fix the locators:

Claude Code Session
Claude > The login test is failing because the button text changed
         from "Login" to "Sign In". Read the current LoginForm
         component and update all tests that reference the old
         button text.

# Claude searches for all occurrences and updates them
Best Practice: Use resilient locators that are less likely to break. Prefer getByRole(), getByLabel(), and getByTestId() over CSS selectors or XPath. Ask Claude Code to refactor your locators to use these preferred methods.
Locator Type Resilience Example
getByRole High page.getByRole('button', { name: 'Submit' })
getByLabel High page.getByLabel('Email address')
getByTestId High page.getByTestId('submit-btn')
getByText Medium page.getByText('Welcome back')
CSS Selector Low page.locator('.btn-primary')
XPath Low page.locator('//button[@class="submit"]')

5. Handling Flaky Tests

Flaky tests pass sometimes and fail other times. Common causes include timing issues, race conditions, and external dependencies. Claude Code can help diagnose and fix them:

Claude Code Session
Claude > This test is flaky - it passes about 70% of the time.
         Analyze the test and the app code, identify potential
         race conditions or timing issues, and fix them.
         The test is in tests/e2e/checkout.spec.ts

Common fixes Claude Code might apply:

TypeScript (Common Flaky Test Fixes)
// BAD: No waiting for the element
await page.click('#submit');

// GOOD: Wait for element to be ready
await page.getByRole('button', { name: 'Submit' }).click();

// BAD: Hard-coded wait
await page.waitForTimeout(3000);

// GOOD: Wait for specific condition
await page.waitForResponse('**/api/orders');

// BAD: Checking element immediately after navigation
await page.goto('/dashboard');
const text = await page.textContent('h1');

// GOOD: Wait for the page to be in the expected state
await page.goto('/dashboard');
await expect(page.getByRole('heading')).toBeVisible();

6. Step-by-Step Debugging Workflow

When a test fails, follow this systematic workflow with Claude Code:

  1. Run the failing test in isolation

    Ask Claude Code: "Run npx playwright test tests/e2e/checkout.spec.ts --headed" to see the browser during execution.

  2. Analyze the error message

    Share the full error output with Claude Code and ask it to interpret the failure.

  3. Check the trace (if available)

    Ask Claude Code to open the trace viewer: "Run npx playwright show-trace" and examine the execution timeline.

  4. Compare current app state with test expectations

    Ask Claude Code to read the relevant component code and compare it with the test assertions.

  5. Apply the fix and re-run

    Let Claude Code make the fix and run the test again to verify it passes.

Practice Debugging

Intentionally break a passing test (change a locator or assertion), then use Claude Code to diagnose and fix the failure. This builds muscle memory for the debugging workflow.

Next: Advanced Workflows →

Ready to Go Deeper?

Live instructor-led courses from our partners. Affiliate disclosure.