Production-grade Playwright TypeScript patterns — framework architecture, authentication, CI/CD, flaky test prevention, accessibility, and 13 documented anti-patterns.
Every pattern sourced from official Playwright documentation or clearly labelled as an architectural decision.
POM vs Script decision guide, split locator/action pattern, ADR-style justification, and folder structure.
Fixture lifecycle, test vs worker scope, auth fixtures, and the official { scope: 'worker' } tuple syntax.
Priority order — getByRole → getByLabel → getByTestId → CSS → XPath. Filtering, chaining, and testIdAttribute.
Three auth strategies with a decision tree, storageState TTL, setup projects, and multi-role testing.
Full playwright.config.ts reference — CI-aware settings, retries, reporters, timeouts, and env variable layering.
HTML reporter, Trace Viewer, Allure setup, and environment metadata for CI artifact uploads.
GitHub Actions matrix strategy, Azure Pipelines with JUnit reporter, sharding, secrets, and artifact upload.
Root cause taxonomy, expect.poll, waitForFunction, and a step-by-step trace debugging workflow.
axe-core integration, WCAG 2.1 tag filtering, keyboard navigation testing, and focus management.
13 documented before/after examples — waitForTimeout, XPath abuse, shared state, over-abstraction, and more.
All three target SauceDemo and cover the same test scenarios — compare them to understand the full spectrum of Playwright architecture options.
Single-class POM — locators and actions in one file
Split locator/action pattern with Allure reporting
Plain helper functions — no page object classes
Clone and run the recommended framework in under two minutes.
# Clone and enter the recommended framework git clone https://github.com/ZeeaanNawazHarall/\ playwright-best-practices.git cd playwright-best-practices/examples/simple-pom-framework # Install dependencies and browser npm install npx playwright install chromium # Copy public SauceDemo credentials and run cp .env.example .env npm test
export default defineConfig({ // Fail build if test.only left in source forbidOnly: !!process.env.CI, // Retry twice on CI, never locally retries: process.env.CI ? 2 : 0, // Single worker on CI, auto locally workers: process.env.CI ? 1 : undefined, use: { trace: 'on-first-retry', screenshot: 'only-on-failure', video: 'retain-on-failure', }, });
These run through every section of this repo.
Authentication belongs in fixtures. Tests should start already authenticated. → Authentication docs
getByRole() → getByLabel() → getByTestId() → CSS → XPath (last resort).
→ Locators docs
Hard waits are flaky by definition. Use web-first assertions — they poll automatically until the condition is met. → Flaky tests docs
Tests sharing state fail randomly under parallelism. Each test should own its data and navigation. → Fixtures docs
Retries, timeouts, and reporter config scattered across test files become invisible and hard to change. → Configuration docs
axe-core finds rule violations automatically. It cannot verify reading order, screen reader announcements, or real keyboard usability. → Accessibility docs