Key takeaways
- Playwright is an open-source (Apache-2.0) browser automation and end-to-end testing framework from Microsoft. One API drives Chromium, Firefox and WebKit.
- It is available for TypeScript and JavaScript, Python, .NET and Java.
- Actions wait automatically until the element is ready, and assertions retry, which removes most hand-written sleeps.
- Codegen records a test for you, and the trace viewer replays a failed run step by step.
- Playwright checks that a page works. It does not tell you how the site behaves under traffic, and it is not a load testing tool.
Playwright is a framework for controlling a real browser from code, so you can click through your web app the way a user would and assert that the right things happen. Microsoft develops it, and its documentation (playwright.dev, checked October 2026) describes it as one API to drive Chromium, Firefox and WebKit on Linux, macOS and Windows, headless or headed. This tutorial covers what it does, how to install it, and a first test that runs.
What is Playwright used for?
Teams use it for end-to-end tests: sign in, add an item to the cart, check the confirmation page. The same API also works as a plain automation library for scripts that open pages, take screenshots or read content. The official docs distinguish the two. The library (playwright on npm) launches and controls browsers. The test runner (@playwright/test) adds fixtures, assertions, parallel runs, retries and reporting on top, and the docs recommend it for end-to-end testing in most cases.
It targets web applications. It emulates mobile browsers (for example Chrome on Android and Mobile Safari) through device profiles, but it does not drive native desktop or native mobile apps.
Which languages and browsers does Playwright support?
Playwright is available for TypeScript, Python, .NET and Java, and for JavaScript through Node.js (playwright.dev, October 2026). It drives Chromium, Firefox and WebKit. WebKit is the engine Safari is built on, so a WebKit run is a close stand-in for Safari but is not the Safari application itself.
Playwright downloads its own browser builds, so every machine and CI runner tests the same versions. As of 23 October 2026 the current release of @playwright/test on npm is 1.64.1. The docs list the Node.js versions it supports as the latest 22.x, 24.x or 26.x, and macOS 14 or later, Windows 11 or later, or Debian 12/13 and Ubuntu 22.04/24.04/26.04 on Linux.
How do you install Playwright?
The setup command from the getting started guide is:
npm init playwright@latest
It asks whether to use TypeScript or JavaScript, which folder holds the tests, whether to add a GitHub Actions workflow, and whether to download the browsers. It then creates playwright.config.ts, an example test in tests/example.spec.ts and a package.json. To add Playwright to a project that already exists, or to fetch the browsers again later, use npx playwright install (or name browsers: npx playwright install chromium firefox webkit).
What does a first Playwright test look like?
This test uses the Playwright team’s own demo app, TodoMVC, so it does not depend on a site you do not control. It adds a to-do item and checks the list. It ran as written against @playwright/test 1.64.1 and passed:
const { test, expect } = require('@playwright/test');
test('add a todo item', async ({ page }) => {
await page.goto('https://demo.playwright.dev/todomvc');
await page.getByPlaceholder('What needs to be done?').fill('write the first test');
await page.getByPlaceholder('What needs to be done?').press('Enter');
await expect(page.getByTestId('todo-title')).toHaveText('write the first test');
await expect(page.getByTestId('todo-count')).toContainText('1 item left');
});
Save it as tests/example.spec.js and run npx playwright test. By default the run is headless and parallel across the browsers in your config. Add --headed to watch it, --project=chromium to run one browser, or --ui to open UI Mode. After a run, npx playwright show-report opens the HTML report.
If you only need a script and not a test runner, the library form from the docs works too:
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://demo.playwright.dev/todomvc');
console.log(await page.title());
await browser.close();
})();
Run it with node my-script.js after npm i -D playwright and npx playwright install. It printed React • TodoMVC when run for this article.
How does auto-waiting work?
Before an action such as click() or fill(), Playwright checks that the element is ready. According to the actionability page, a click waits for the element to be visible, stable (not mid-animation), able to receive events at the click point (nothing is covering it) and enabled. fill() checks visible, enabled and editable. Only when those hold does the action run, and if they do not hold before the timeout, the action fails with a timeout error and a log of what it was waiting for.
Assertions such as toBeVisible(), toHaveText() and toHaveURL() are described as web-first: they retry until the condition is met or the timeout passes. Together these remove most of the sleep(2000) calls older scripts need. They do not remove all flakiness: an unstable test environment or a test that depends on shared data still fails randomly. For the older approach, see how explicit and implicit waits work in Selenium WebDriver with Java, and for the causes of random failures in general, flaky tests in software testing.
How do you record a test with codegen?
npx playwright codegen demo.playwright.dev/todomvc opens a browser and an inspector. Your clicks and typing are turned into test code as you go, and a toolbar lets you add assertions for visibility, text or value. According to the codegen docs, it prefers role, text and test-id locators, and refines a locator when several elements match. Treat the output as a first draft: rename things, remove incidental steps and add the assertions that matter.
How do you debug a failed test with the trace viewer?
Set trace: 'on-first-retry' under use in playwright.config, and set retries (the docs suggest 2 on CI, 0 locally). When a test fails and is retried, Playwright records a trace. Open npx playwright show-report, click the trace icon next to the test, and you can step through each action and see the page before and after it, with the log, network requests, console output and errors for that step. To record a trace locally, run npx playwright test --trace on. This is the part that saves time on CI failures, because you inspect the run instead of trying to reproduce it.
A minimal config for the earlier test:
const { defineConfig, devices } = require('@playwright/test');
module.exports = defineConfig({
testDir: './tests',
retries: process.env.CI ? 2 : 0,
use: { trace: 'on-first-retry' },
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
],
});
Can Playwright intercept network requests?
Yes. page.route() lets a test answer a request itself, which is useful for stubbing a slow or unreliable API. This stub returns a fixed JSON body for any request matching the pattern (verified with 1.64.1):
await page.route('**/api/greeting', route =>
route.fulfill({ json: { message: 'hello from the stub' } }));
Is Playwright free, and when should you not use it?
Yes: the playwright and @playwright/test packages are published under the Apache-2.0 license (npm registry, October 2026). It is a poor fit for native desktop or native mobile app testing, since it controls web pages in browsers. Whether it beats another framework depends on your stack and team, so try it on one real flow before you commit. Related tools in this blog: Puppeteer, and a list of cross-browser testing tools.
Can you use Playwright for load testing?
People search for “load testing with Playwright”, so here is the plain answer. Playwright runs a real browser, which is the right thing for a functional check and a heavy thing to multiply: each virtual user would be a full browser. Load tests normally generate traffic at the protocol level (HTTP requests) and keep browser-based checks to a small number of users. Grafana k6, for example, has a browser module for measuring front-end metrics such as Web Vitals inside a k6 test (grafana.com/docs/k6, October 2026).
LoadFocus covers the load side of that split. It runs JMeter and k6 scripts from 25+ cloud regions and shows response time, throughput and percentiles in real time (load testing). It also runs scheduled Lighthouse audits and Core Web Vitals checks from the same regions (page speed monitoring). Playwright tests and LoadFocus tests are separate jobs: the first asks “does this flow work”, the second asks “does it still work, and how fast, when many users arrive”. For always-on checks of a live site, see synthetic monitoring.
Frequently Asked Questions
What does Playwright cover?
Chromium, Firefox and WebKit through a single API, in TypeScript, JavaScript, Python, .NET and Java. That makes cross-browser testing far less work than maintaining a separate setup per browser.
How does it handle flakiness?
Actions wait until the element is visible, stable, enabled and able to receive the event, and assertions retry until they pass or time out. This removes most sleep-based flakiness but not problems in the test data or environment.
What helps when a CI run fails?
The trace viewer. A trace records each step with DOM snapshots, network requests and console output, so you can inspect what happened without reproducing the failure locally.
How do I install Playwright?
Run npm init playwright@latest, answer the prompts, then npx playwright test. Use npx playwright install to download or refresh the browsers.
Is Playwright a load testing tool?
No. It automates a browser to check behaviour. Load tests send many concurrent requests and measure response time and errors, which needs a tool built for that, such as JMeter or k6.
Sources
- Playwright: Installation (October 2026)
- Playwright: Auto-waiting and actionability (October 2026)
- Playwright: Trace viewer (October 2026)
- Playwright: Test generator (October 2026)
- Playwright: Library (October 2026)
- Grafana k6: Browser module (October 2026)