Playwright Fundamentals
Playwright is a cross-browser end-to-end testing framework from Microsoft that automates Chromium, Firefox and WebKit through a single API. Tests run in real browsers with automatic waiting, isolated contexts and a built-in test runner.
What is this?
Playwright is a Node.js library and test runner that drives real Chromium, Firefox and WebKit browsers via a single API. Every test runs in a fresh, isolated browser context so state never leaks between tests. The framework handles browser lifecycle, parallelism, retries and reporting out of the box.
Why do you need it?
- One API covers three browser engines, so the same test validates Chrome, Edge, Firefox and Safari-like behavior without per-browser forks.
- Auto-waiting is built in: Playwright retries every action until the element is actionable, eliminating the sleep-and-hope pattern of older tools.
- Isolated browser contexts give every test a clean origin, cookies and storage, which makes tests independent and parallel-safe.
- Network interception, geolocation, timezone, tracing and video recording are first-class features — no third-party plugins required.
- The runner produces rich reports (HTML, JSON, JUnit) that plug directly into CI dashboards and failure triage.
Mental model
A QA tester running through a checklist in a real browser
A Playwright test script
The tester opens a browser, clicks through the app and writes down what they saw. Playwright does the same at machine speed — and it keeps a video, trace and screenshot of everything it did.
How it works
- The @playwright/test runner loads spec files, each of which declares one or more test() cases.
- For every test the runner launches a browser instance and creates a fresh context and page that are injected as fixture arguments.
- Actions such as page.click and page.fill wait for the element to be stable, visible and enabled before acting (actionability).
- Assertions from expect() poll the DOM in the background until the condition holds or a timeout expires.
- The runner collects results, traces, screenshots and videos, then renders an HTML report and exits with a non-zero code on failure.
Lifecycle of a single Playwright test run.
Key commands
npm init playwright@latestScaffold a Playwright project with example tests, config and a GitHub Actions workflow.
? Where to put your end-to-end tests? ...\n? Add a GitHub Actions workflow? (y/N)
npx playwright installDownload the browser binaries declared in the project so tests can launch them.
Downloading Chromium 120.0.6099.28 (playwright build v1083)...
npx playwright testRun every test in headless mode across the configured browser projects.
3 passed (2.1s)\n playwright-intro.spec.ts:5:1 › loads the home page 1 passed
npx playwright test --headedRun the tests with visible browser windows so you can watch the automation.
npx playwright test --debugLaunch the inspector and pause on the first action, with a time-travel UI.
npx playwright show-reportServe the last HTML report locally for a visual breakdown of pass/fail runs.
Examples
A minimal end-to-end smoke test
import { test, expect } from "@playwright/test"; test("loads the home page and shows the search bar", async ({ page }) => { await page.goto("https://example.com"); await expect(page).toHaveTitle("Example Domain"); const heading = page.getByRole("heading", { level: 1 }); await expect(heading).toHaveText("Example Domain");});test() receives a page fixture that Playwright creates and destroys for each test. page.goto navigates to the URL, and expect(page).toHaveTitle plus the heading assertion retry automatically until the condition is met. No explicit waits are needed because Playwright auto-waits.
In production
- Smoke tests run against the production URL after every deploy to catch critical regressions in seconds.
- A cross-browser matrix (Chromium, Firefox, WebKit) validates the same user journey across engines in CI.
- Playwright drives scheduled account-health and checkout flows to confirm end-to-end transactions still complete.
- Traces and videos attached to failed CI runs let engineers diagnose flaky tests without reproducing locally.
Best practices
- Keep every test independent — never rely on ordering or state created by an earlier test.
- Use web-first assertions like toHaveText instead of waiting on the clock with page.waitForTimeout.
- Configure retries: 0 locally for speed, 2–3 in CI to absorb transient flakiness.
- Group related checks into one test() that walks a user journey rather than a thousand one-liners.
- Store test users and secrets in env vars or a .env file loaded by the runner, never in the test source.
Common mistakes
- Inserting page.waitForTimeout(3000) as a 'stability fix' — it slows the suite and masks real wait problems.
- Sharing the same page across tests, which reintroduces state leakage and order dependence.
- Asserting on page.content() or raw HTML strings instead of using locator-based web-first assertions.
- Running the full suite locally with retries enabled, which hides flakiness that should be fixed.
Common issues
Error: browserType.launch: Executable doesn't exist at .../chromium-1124/chrome-win/chrome.exeThe browser binaries were never downloaded for the installed Playwright version.
Run npx playwright install (add --with-deps on Linux) to fetch the matching browsers.
Failed to launch: The browser is already running (port 0)A leftover chromium process or anti-virus is interfering with process launch.
Kill stray processes with pkill -f chrome, reboot if needed, and add the browser path to your AV exclusions.
npx playwright test: command not found@playwright/test is not installed in the current project.
Run npm init playwright@latest or npm i -D @playwright/test, then verify with npx playwright --version.
Debugging tips
- Re-run a single failing test with npx playwright test <file> --repeat-each 3 to expose flakiness.
- Use npx playwright test --debug to step action-by-action in the inspector.
- Open the trace from the HTML report after a failure to replay every network call and snapshot.
- Run headed with npx playwright test --headed to watch exactly where automation gets stuck.
Interview checkpoint
Hands-on lab
- Scaffold a Playwright project with the official init command
- Install the browser binaries
- Write a first navigation and title assertion test
- Run the test headed, then read the HTML report
Your First Playwright Test Run
25 min · beginner
Quick quiz
Which fixture does Playwright inject into every test by default?
Playwright tests must be run one at a time because they share browser state.
Which command starts the local HTML report viewer after a test run?
Cheat sheet
npx playwright testRun all tests headlessnpx playwright test <file>Run one spec filenpx playwright test --headedShow browser windowsnpx playwright test --debugOpen inspector, pause on actionnpx playwright test -g 'smoke'Filter by test titlenpx playwright show-reportOpen last HTML report