Files
gh-joel611-claude-plugins-p…/skills/test-debugger/resources/debugging-checklist.md
2025-11-30 08:28:25 +08:00

6.1 KiB

Playwright Test Debugging Checklist

Initial Assessment

  • Read the error message carefully
  • Note the failing test name and location
  • Check if test fails consistently or intermittently
  • Identify which browser(s) are failing
  • Check if failure is local only or also in CI

Error Type Identification

Timeout Errors

  • Check if element exists with correct data-testid
  • Verify page has loaded completely
  • Add explicit wait before interaction
  • Check if network requests are pending
  • Increase timeout if operation is legitimately slow

Selector Errors

  • Verify data-testid in HTML matches test code
  • Check if multiple elements have the same testid
  • Ensure element is not in an iframe
  • Confirm element is added to DOM (not removed)
  • Use Playwright Inspector to test selector

Assertion Errors

  • Verify expected value is correct
  • Check if element exists and is visible
  • Add wait before assertion
  • Check if content is populated asynchronously
  • Increase assertion timeout if needed

Navigation Errors

  • Check if URL is correct
  • Verify server is running
  • Check for network issues
  • Ensure proper wait after navigation
  • Look for redirects or authentication requirements

Element Investigation

  • Count elements matching selector (should be 1)

    const count = await page.locator('[data-testid="element"]').count();
    console.log('Element count:', count);
    
  • Check element visibility

    const isVisible = await page.locator('[data-testid="element"]').isVisible();
    console.log('Is visible:', isVisible);
    
  • Check element state

    const isEnabled = await page.locator('[data-testid="element"]').isEnabled();
    console.log('Is enabled:', isEnabled);
    
  • Get element attributes

    const testId = await page.locator('[data-testid="element"]').getAttribute('data-testid');
    console.log('data-testid:', testId);
    

Timing Investigation

  • Add waits before interactions

    await page.locator('[data-testid="element"]').waitFor({ state: 'visible' });
    
  • Wait for page load

    await page.waitForLoadState('domcontentloaded');
    await page.waitForLoadState('networkidle');
    
  • Wait for specific API calls

    await page.waitForResponse('**/api/endpoint');
    
  • Check if animations/transitions are in progress

    await page.waitForTimeout(500); // Only for testing, remove later
    

Interactive Debugging

  • Run test in headed mode

    npx playwright test --headed
    
  • Use debug mode

    npx playwright test --debug
    
  • Add page.pause() in test

    await page.pause(); // Pauses execution for manual inspection
    
  • Enable slow motion

    // In playwright.config.ts
    use: {
      launchOptions: {
        slowMo: 1000, // Slow down by 1 second
      },
    }
    
  • Take screenshots for inspection

    await page.screenshot({ path: 'debug-screenshot.png', fullPage: true });
    

Trace Analysis

  • Enable trace recording

    // In playwright.config.ts
    use: {
      trace: 'on-first-retry',
    }
    
  • Open trace viewer

    npx playwright show-trace trace.zip
    
  • Check trace for:

    • Network requests
    • Console logs
    • Screenshots at each step
    • DOM snapshots
    • Action timeline

Test Isolation Check

  • Run test in isolation (comment out other tests)
  • Check if test passes when run alone
  • Verify no shared state between tests
  • Ensure proper cleanup in afterEach
  • Check for global state mutations

Environment Differences

Local vs CI

  • Run test in headless mode locally

    npx playwright test --headed=false
    
  • Check viewport size matches CI

    await page.setViewportSize({ width: 1920, height: 1080 });
    
  • Compare timeouts (CI may need longer)

  • Check if CI has different environment variables

Browser Differences

  • Test in all configured browsers

    npx playwright test --project=chromium
    npx playwright test --project=firefox
    npx playwright test --project=webkit
    
  • Check for browser-specific issues

  • Verify CSS compatibility

  • Test JavaScript feature support

Common Quick Fixes

Fix #1: Add Explicit Wait

// Before
await page.locator('[data-testid="element"]').click();

// After
await page.locator('[data-testid="element"]').waitFor({ state: 'visible' });
await page.locator('[data-testid="element"]').click();

Fix #2: Wait for Network

// Before
await page.locator('[data-testid="submit"]').click();
await expect(page.locator('[data-testid="result"]')).toBeVisible();

// After
await page.locator('[data-testid="submit"]').click();
await page.waitForLoadState('networkidle');
await expect(page.locator('[data-testid="result"]')).toBeVisible();

Fix #3: Handle Multiple Elements

// Before
await page.locator('[data-testid="item"]').click(); // Error if multiple

// After
await page.locator('[data-testid="item"]').first().click();

Fix #4: Increase Timeout

// Before
await expect(page.locator('[data-testid="slow-element"]')).toBeVisible();

// After
await expect(page.locator('[data-testid="slow-element"]')).toBeVisible({
  timeout: 15000
});

Fix #5: Check Element State

// Before
await page.locator('[data-testid="button"]').click();

// After
await expect(page.locator('[data-testid="button"]')).toBeEnabled();
await page.locator('[data-testid="button"]').click();

Verification

  • Run test 5+ times to verify consistency
  • Test in all browsers
  • Run full test suite to check for regressions
  • Test in CI environment
  • Document the fix for future reference

Prevention

  • Add explicit waits where needed
  • Use only data-testid locators
  • Ensure test isolation
  • Add retry logic in config
  • Review and refactor flaky tests regularly
  • Keep tests simple and focused
  • Maintain good test hygiene (cleanup, fixtures)