Back to blog
    Playwright
    Best Practices
    Test Automation

    10 Playwright Best Practices That Actually Matter in 2026

    Battle-tested Playwright best practices: locators, fixtures, parallelism, test data, auth, retries, and the rules that keep large suites fast and reliable.

    · 10 min read

    Playwright is forgiving — you can write bad tests and they will mostly pass. The teams whose suites stay green at 1,000+ tests follow a small number of disciplined rules. Here are the ten that matter most in 2026.

    1. Use role-based locators, not CSS

    Prefer `page.getByRole('button', { name: 'Save' })` over `page.locator('.btn-primary')`. Role locators are stable across CSS refactors and double as accessibility checks. CSS locators rot the moment a designer renames a class.

    2. Embrace web-first assertions

    Use `await expect(locator).toBeVisible()`, not `expect(await locator.isVisible()).toBe(true)`. The former auto-waits up to your timeout; the latter is a snapshot in time and is the #1 source of flakiness.

    3. Never use sleep()

    `page.waitForTimeout(1000)` is a code smell. Wait for the actual signal — a network response, an element appearing, a URL change. Playwright's waiting primitives cover every realistic case.

    4. Use fixtures for setup, not beforeEach

    Custom fixtures are per-test, declarative, and self-cleaning. `beforeEach` is global and stateful. Migrate over time and your tests get smaller and clearer.

    5. Centralize test data

    Hardcoded credentials and inline JSON fixtures rot. Store the values your suite depends on — logins, IDs, payloads — in a hosted catalog like TestAssets and pull them at runtime via REST API. One source of truth across automation and manual QA.

    6. Log in once, not in every test

    Use `globalSetup` and `storageState` to authenticate once and reuse the session. Tests that exercise the actual login flow are fine — but every other test should start already logged in.

    7. Run in parallel from day one

    Set `workers: 4` (or higher) in your config and build for isolation from the start. Each test should set up the state it needs, not depend on other tests. Retrofitting parallel-safety later is painful.

    8. Quarantine flaky tests within 24 hours

    When a test goes flaky, mark it `test.fixme` or move it to a quarantine project, file a ticket, and unblock the main suite. Letting a flaky test stay green-ish destroys trust in the entire suite.

    9. Use trace viewer in CI

    Configure `trace: 'on-first-retry'` in your CI config. When a test fails, the trace file gives you a frame-by-frame replay of what the browser did, what the network looked like, and what the DOM was at every step. Debugging time drops 10x.

    10. Keep the suite small and ruthless

    An E2E suite of 50 tests that everyone trusts is worth more than 500 tests that nobody runs. Aggressively delete tests that no longer earn their place.

    Frequently asked questions

    We use essential cookies for core functionality and optional cookies to improve your experience. Learn more about our privacy policy