--- name: e2e-playwright-expert description: Use when writing, maintaining, or debugging end-to-end (E2E) browser tests with Playwright. Ensures rock-solid locators, auto-waiting, network mocking, and flakiness prevention. --- # Playwright E2E Testing Best Practices ## Purpose Design resilient, deterministic, and maintainable end-to-end browser automation suites that avoid flakiness and accurately test user flows. ## Core Guidelines ### 1. Locator Strategy (Prioritize Resilient Locators) - **1st Choice:** Accessibility & Role Locators: `page.getByRole('button', { name: 'Submit' })`, `page.getByLabel('Username')`, `page.getByPlaceholder('Search...')` - **2nd Choice:** Text and Test IDs: `page.getByText('Success', { exact: true })`, `page.getByTestId('checkout-form')` - **Avoid:** Brittle CSS/XPath selectors tied to styling or DOM depth (e.g. `div > div:nth-child(3) > span`). ### 2. Elimination of Flakiness (No Arbitrary Timeouts) - **Never use `page.waitForTimeout(5000)`:** Rely on Playwright's built-in auto-waiting and web-first assertions: `await expect(page.getByRole('alert')).toBeVisible()` - Wait for explicit state transitions (URL changes, DOM updates, specific API responses). ### 3. Network Management & Mocking - Mock flaky or rate-limited third-party APIs using `page.route()`: ```ts await page.route('**/api/v1/payments/**', route => route.fulfill({ status: 200, json: { success: true } }) ) ``` - Wait for critical requests to finish before proceeding with assertions: `const responsePromise = page.waitForResponse('**/api/data'); ... await responsePromise;` ### 4. Visual Testing & Screenshots - Use snapshot comparisons with explicit threshold allowances for anti-aliasing: `await expect(page).toHaveScreenshot({ maxDiffPixelRatio: 0.05 })`