Playwright
End-to-end tests in real browsers with accessible locators, auth handled once via saved storage state, network control for deterministic runs, and traces that make CI failures debuggable.
On this page
Playwright drives real Chromium, Firefox and WebKit browsers from tests. When I first picked it up, the hard part wasn’t writing tests. It was authentication. Corporate apps sit behind single sign-on, and an end-to-end test that has to click through an identity provider every run is slow and flaky, and sometimes blocked outright.
Auth: log in once, reuse everywhere
The standard answer now is a setup project that logs in once and saves the browser’s storage state. Every other test starts already authenticated.
// auth.setup.ts: runs once before the suite
import { test as setup } from "@playwright/test";
setup("authenticate", async ({ page }) => {
await page.goto("/login");
await page.getByLabel("Email").fill(process.env.E2E_USER!);
await page.getByLabel("Password").fill(process.env.E2E_PASS!);
await page.getByRole("button", { name: "Sign in" }).click();
await page.context().storageState({ path: "playwright/.auth/user.json" });
});
// playwright.config.ts
projects: [
{ name: "setup", testMatch: /auth\.setup\.ts/ },
{ name: "chromium", use: { storageState: "playwright/.auth/user.json" }, dependencies: ["setup"] },
];
For SSO that resists automation, use a test-only login route or dedicated test users in non-production environments, and keep one smoke test that exercises the real SSO flow. You rarely need to test the identity provider itself on every run.
Habits that keep a suite healthy
- Accessible locators.
getByRoleandgetByLabelare resilient to markup changes and nudge you towards accessible UI. It’s the same philosophy as Testing Library, applied to a real browser. - Control the network when you need determinism.
page.route()can fulfil requests with fixtures, so demo and smoke suites don’t depend on volatile backend data. Keep some tests against the real backend too. - Traces on retry.
--trace on-first-retrycaptures a timeline with DOM snapshots, network and console logs. It turns “flaky in CI” into an actual root cause. - Shard and split. Run smoke tests on every pull request and the full suite on merge, sharded across machines.
- Codegen for a starting point. It’s great for live demos and first drafts. Tidy up the unnecessary steps afterwards.
Component testing too
Playwright can also mount individual components in a real browser, which makes a useful middle ground between jsdom unit tests and full end-to-end journeys. Storybook stories make good fixtures for it (Storybook).
In practice
I championed Playwright for end-to-end testing across several teams in one department. Mocked-state suites ran in pipelines and doubled as reliable environments for client demos and user acceptance testing. The biggest unlock was organisational: agreeing dedicated test users and auth policies for test environments. Once that was sorted, the tests themselves were the easy part. Test against the environment you actually run (SAID: Train for the Production You Actually Run). Where it fits in the bigger picture: React Testing Strategy and A Testing Strategy Teams Actually Adopted.
- #playwright
- #e2e-testing
- #testing
- #ci
↩ Linked from (3)
…all coverage indicators to every merge request, so reviewers could see untested lines immediately. Championed Playwright across departments. I worked through the authentication problem (test users and test-friendly auth…
- MSW (Mock Service Worker)Evergreen
…ment stopped depending on a shared test environment being up. Pairs naturally with React Testing Strategy and Playwright.
- React Testing StrategyEvergreen
…er) | Exercises real data fetching, state and rendering together | | Critical user journeys | End-to-end with Playwright | Proves the deployed thing works |
↪ Links to (4)
Related by topic
- Evergreen
API Modelling
Frontend craft - Growingcase study
Building a Graph Component Library
Frontend craft - Growingcase study
Building a Low-Code BPMN Workflow Platform
Frontend craft - Growing
Bulletproof React
Frontend craft