Selectors break.
pw-doctor heals them.

A CLI that repairs broken Playwright test selectors. Captures DOM from failed tests, analyzes it with five strategies, and patches your code.

npm install -D pw-doctor
$ npx pw-doctor heal

pw-doctor v0.0.1
Found 2 failures in .pw-doctor/captures/

   login.spec.ts:14
    page.locator('#submit-btn')
    Element not found

     page.getByRole('button', { name: 'Sign in' })
      attribute_match · confidence 0.94

   dashboard.spec.ts:28
    page.locator('.user-menu .name')
    Element not found

     page.getByTestId('user-display-name')
      text_match · confidence 0.87

Applied 2 fixes. Run tests to verify.
How it works

Three steps to working tests

01

Capture

Add the reporter to your Playwright config. When tests fail, pw-doctor captures a DOM snapshot of the page at the moment of failure.

// playwright.config.ts

export default defineConfig({
  reporter: [
    ['pw-doctor/reporter'],
    ['html'],
  ],
});
02

Analyze

Run pw-doctor heal. Five repair strategies — from semantic attribute matching to AI — analyze the captured DOM and find replacement selectors.

$ npx pw-doctor heal

   page.locator('#submit-btn')

    Candidates:
    1. getByRole('button', { name: 'Sign in' })
       attribute_match · 0.94
    2. getByText('Sign in')
       text_match · 0.78

  → Applied best candidate
03

Verify

Run your tests again. The patched selectors find the right elements. Your CI is green.

$ npx playwright test

   login.spec.ts (3 tests)
   dashboard.spec.ts (5 tests)
   settings.spec.ts (4 tests)

  11 passed
Repair strategies

Five ways to find the fix

Each strategy runs in order. The first high-confidence match wins. AI is only called when heuristics aren't enough.

attribute_match
Semantic selectors from data-testid, aria-label, and ARIA roles. Highest confidence for well-instrumented apps.
text_match
Finds elements by visible text content. Works when markup changes but labels stay the same.
structural_match
Fuzzy DOM matching via class name overlap and element position. Catches CSS refactors and component restructuring.
anchor_match
Builds relative selectors from stable landmarks — headings, <nav>, <main>, [data-testid] parents.
ai
Sends redacted DOM to Claude or GPT. Every suggestion passes syntax validation and DOM verification before touching your code.
AI repair

AI-powered,
human-controlled

When heuristics aren't enough, pw-doctor asks Claude or GPT to analyze the DOM. But you stay in control.

Consent first
AI is never called without your explicit opt-in. First run prompts for approval. CI requires prior consent on file.
Validated output
Every AI suggestion passes selector syntax validation, then DOM hard-gate verification — must match exactly one visible element.
Audit logged
All AI calls logged to .pw-doctor/audit/ with timing, token counts, and cost. DOM content is never logged — only hashes.
Cost transparent
Token usage and estimated cost shown after every heal run. No surprise bills.
Get started

Up and running in two minutes

# Install
npm install -D pw-doctor

# Set up reporter + gitignore
npx pw-doctor init

# Run tests, then heal failures
npx playwright test
npx pw-doctor heal
init
Set up reporter & config
heal
Repair broken selectors
watch
Auto-repair on file change
diff
Preview without applying
calibrate
Benchmark against a corpus
report
Generate repair history