Claude-skill-registry e2e-playwright-diagnosis
Diagnose and resolve E2E test failures in Playwright. This skill should be used when E2E tests fail and need investigation, when Playwright test errors require root cause analysis, or when test failures need to be reproduced in the browser for debugging. Orchestrates MCP tools (Playwright, Chrome DevTools, Serena) and delegates code fixes to specialized agents.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/e2e-playwright-diagnosis" ~/.claude/skills/majiayu000-claude-skill-registry-e2e-playwright-diagnosis && rm -rf "$T"
skills/data/e2e-playwright-diagnosis/SKILL.mdE2E Playwright Diagnosis
Overview
This skill provides a systematic procedure for diagnosing and resolving E2E test failures in Playwright. It orchestrates multiple MCP tools (Playwright, Chrome DevTools, Serena) and delegates code corrections to specialized agents, ensuring all tests pass based on actual application behavior.
When to Use
- E2E test failure messages are received
- Playwright tests need root cause analysis
- Test failures require browser reproduction for debugging
- Multiple tests in a file are failing and need systematic resolution
Workflow Decision Tree
Error Message Received │ ▼ ┌───────────────────┐ │ 1. Analyze Error │ │ Extract info │ └─────────┬─────────┘ │ ▼ ┌───────────────────┐ │ 2. Locate Test │ │ Read test file │ └─────────┬─────────┘ │ ▼ ┌───────────────────┐ │ 3. Prepare Env │ │ rm .next │ │ rebuild │ └─────────┬─────────┘ │ ▼ ┌───────────────────────────────┐ │ 4. Reproduce in Browser │ │ MCP Playwright + │ │ MCP Chrome DevTools │ └─────────┬─────────────────────┘ │ ▼ Test passes? / \ Yes No │ │ ▼ ▼ ┌─────────┐ ┌─────────────────┐ │ Run all │ │ Collect info │ │ tests │ │ via MCP Serena │ └────┬────┘ └────────┬────────┘ │ │ ▼ ▼ All pass? ┌─────────────────┐ / \ │ Delegate fix to │ Yes No │ context-manager │ │ │ │ → frontend-dev │ ▼ ▼ └────────┬────────┘ ┌────┐ ┌─────┐ │ │Done│ │Align│ ▼ │ │ │tests│ ┌─────────────────┐ └────┘ │to │ │ Validate fix │ │code │ │ Loop until pass │ └─────┘ └─────────────────┘
Detailed Procedure
Step 1: Analyze Initial Failure
- Receive the E2E test error message
- Analyze the complete error content
- Extract relevant information:
- Error type
- Stack trace
- Test file name
- Failed test name
Step 2: Identify Problematic Test
- Locate the E2E test file mentioned in the error
- Open the test file
- Identify the specific test that failed
- Read:
- The title (describe / test)
- The test body
- Infer which application behavior the test attempts to validate
Step 3: Prepare Environment
- Remove the
folder from the project:.nextrm -rf apps/gateway-financeiro/.next - Execute complete project rebuild to generate a new
folder:.nextnpm run build --workspace=apps/gateway-financeiro
Step 4: Reproduce Test in Browser
- Use MCP Playwright to execute the test in the browser
- Simultaneously use MCP Chrome DevTools to:
- Observe the DOM
- Monitor console errors
- Track network requests
- Execute only the test that failed
MCP Playwright tools to use:
- Navigate to test URLmcp__playwright__browser_navigate
- Capture accessibility snapshotmcp__playwright__browser_snapshot
- Interact with elementsmcp__playwright__browser_click
- Fill form fieldsmcp__playwright__browser_type
MCP Chrome DevTools tools to use:
- Capture DOM statemcp__chrome-devtools__take_snapshot
- Check for errorsmcp__chrome-devtools__list_console_messages
- Monitor API callsmcp__chrome-devtools__list_network_requests
Step 5: Evaluate Isolated Test Result
-
If the test passes in the browser:
- Read all other E2E tests present in the same file
- Execute all tests from that file, still via Playwright in the browser
- If tests pass isolated but fail in suite → Check for data isolation issues:
- Verify unique identifiers are generated per test, not per describe block
- Check backend logs for 409 Conflict or "already exists" errors
- Look for shared state between tests (cookies, localStorage, database records)
-
If all tests in the file pass:
- Invoke the
agentcontext-manager - Through it, invoke the
agent to:frontend-nextjs-developer- Adjust E2E tests to faithfully reflect the behavior already implemented in the code
- Consider the code as the source of truth
- Finalize the process
- Invoke the
Step 6: When Test Cannot Be Reproduced in Browser
- If Playwright + Chrome DevTools cannot reproduce the error in the browser:
- Use MCP Serena to navigate the project
- Collect maximum possible information:
- Execution logs
- Server logs
- Playwright logs
- Execute only non-committable commands:
- Project rebuild
- Docker container rebuild
- Log inspection
- Do not alter any code or test files
MCP Serena tools to use:
- Search for error patterns in logsmcp__serena__search_for_pattern
- Locate relevant code symbolsmcp__serena__find_symbol
- Understand file structuremcp__serena__get_symbols_overview
Step 7: Delegate Code Correction
- Invoke the
agent via Task tool:context-managersubagent_type: "context-manager" - Through it, invoke the
agentfrontend-nextjs-developer - Provide the agent with:
- Error context
- Collected logs
- Expected behavior
- Await response confirming the code bug was fixed
Step 8: Validate Correction After Code Change
-
After fix confirmation:
- Remove the
folder again.next - Execute project rebuild
- Execute only one test from the affected file
- Remove the
-
If the test passes:
- Execute the remaining tests from the same file
-
If the test does not pass:
- Use again:
- MCP Playwright
- MCP Chrome DevTools
- Execute the test in the browser
- Collect new information
- Use again:
Step 9: Validation Loop
- Repeat steps 21 to 23 until:
- All tests in the file pass successfully
- No remaining E2E failures related to the original error
Termination Condition
- Terminate the process only when:
- All E2E tests in the affected file are passing
- Test behavior is aligned with the actual application behavior
Important Notes
- Code is the source of truth: If the application behaves correctly but tests fail, adjust the tests
- Do not modify code during investigation: Only collect information until Step 7
- Always rebuild after changes: The
folder must be regenerated after any code change.next - Use browser reproduction first: Visual debugging often reveals issues faster than log analysis
- Delegate appropriately: Code fixes go to
, not handled directly by this skillfrontend-nextjs-developer
Quick Troubleshooting Checklist
When tests fail, check these common issues first:
- Backend validation errors (400) → Check API logs for "Bad Request" - often timeout masks schema mismatch (e.g., enum values, unexpected fields)
- Manual testing works, tests fail → Test in browser first; if app works, issue is in tests or contracts, not code
- Timeout on form submit → Check global timeout
(30s minimum); verify backend accepts request schemaplaywright.config.ts - Strict mode violation → Multiple elements match selector; add
or scope to container (e.g.,.first()
)dialog.locator() - Stale locators after re-render → Use inline
selectors instead of storing references; re-query DOM after state changes.nth() - Dropdown not opening/selecting → Add
afterwaitForTimeout(500)
; use.click()
for async datawaitForLoadState('networkidle') - Build cache stale →
, then restart Docker containers (rm -rf .next && npm run build
)docker restart administramos-gateway-financeiro - Redirect loops → Middleware must use
notrequest.headers.get('host')
(localhost vs public domain)request.nextUrl.href - Missing JS chunks (404) → Rebuild Next.js and restart container; browser may cache old build references
- Element not found → Use
to see actual DOM; shadcn components often use portals (render outside parent)browser_snapshot - Timeout on element interaction (manual test works, logs show success) → Selector uses
but element text is dynamic (e.g., "Loading...", "Select option"). Use.filter({ hasText: /pattern/ })
to match accessible name from label, not visible textgetByRole('role', { name: 'Label' }) - 409 Conflict when creating records (passes isolated, fails in suite) → Unique identifier generated once at describe level, causing duplicate keys when multiple tests create records. Generate unique ID inside each test function that creates data:
E2E-${Date.now()}`;`. Discovery: Backend logs show "already exists" or duplicate key errorconst uniqueId = \ - Submit button clicked but form not submitted (no navigation, no errors) → Form validation not complete before submit, or button briefly disabled. Add
after filling last field, verify button not disabled before clicking:waitForTimeout(500)
. Discovery: Screenshot shows filled form, button present but no action occurredawait expect(button).not.toBeDisabled()