βΆPlaywright vs Cypress β which should I use?
Playwright: true parallelization, multi-tab/multi-origin support, shadow DOM, faster execution, enterprise-grade (Microsoft-backed). Cypress: developer experience, single-browser at a time, slower with large test suites, stuck at v13. Use Playwright for new projects, especially teams needing scale and reliability. Use Cypress if your team already invested and team velocity matters more than performance.
βΆHow do I avoid flaky tests in Playwright?
Playwright's auto-waiting eliminates most flakiness: actions wait for element stability (display, opacity, position), network idle, etc. Use locators (getByRole, getByText) instead of CSS selectors β they're resilient. Avoid manual wait() calls. If a test flakes: check for race conditions (e.g., data loading after navigation), use fixtures for setup/teardown, and run with `--retries=1` in CI. The Trace Viewer shows exactly what failed β use it.
βΆWhat is the Page Object Model and why does Playwright need it?
POM encapsulates selectors and actions in reusable page classes. Example: `class LoginPage { fill(email, password) { β¦ } }`. Reduces maintenance when UI changes β update the class, not 100 tests. Playwright doesn't force POM like Cypress does, but it's essential for scale. Implement as: fixtures for page objects, methods for actions, getters for locators.
βΆHow do I run Playwright tests in CI/CD?
Use GitHub Actions: `npm install -g @playwright/test && npx playwright install && npm run test:e2e`. Parallelize with shards: `--shard=1/4 --shard=2/4` etc. For artifacts: upload Trace Viewer output with `actions/upload-artifact@v3`. Docker: use `mcr.microsoft.com/playwright:v1.x-focal` for pre-installed browsers. Key: parallelization is Playwright's strength β use it.
βΆHow do I test visual regression with Playwright?
Use `expect(page).toHaveScreenshot()` for native snapshot testing, or integrate Percy for visual diffs. Native screenshots are good for component tests; Percy for E2E on live sites. Store baselines in git. Update with `--update-snapshots` when design changes are intentional. Consider region-specific snapshots for responsive layouts.
βΆCan Playwright mock network requests and APIs?
Yes, use `page.route()` to intercept HTTP requests. Example: `await page.route('**/api/users', route => { route.abort('blockedbyclient') })`. Useful for: testing error states, controlling response delays, testing without backend. For API testing directly: `APIRequestContext` allows raw HTTP calls without a browser. BDD-friendly approach: mock external APIs, test UI logic in isolation.
βΆHow do I handle authentication in Playwright tests?
Two approaches: (1) Use cookies/localStorage from a logged-in session (fast, brittle if auth changes), store in `.auth` via `context.addCookies()`. (2) Log in via UI before each test using a fixture/hook (slow, mimics real user flow). Best: storage-based for most tests + 1-2 E2E login tests. Use BrowserContext isolation to parallelize authenticated tests.