Playwright
End-to-end browser testing with auto-waiting, across Chromium, Firefox and WebKit.
What it is
Playwright is a Node.js library for browser automation that enables reliable end-to-end testing across Chromium, Firefox, and WebKit with a single API. It supports modern web app features like single-page applications and multi-page flows.
Playwright allows you to automate browser interactions for testing purposes, including navigation, clicking, typing, taking screenshots, capturing videos, and handling multiple pages or contexts. It provides APIs for synchronous-like control and automatic waiting.
- Licence
- Apache 2.0
- Maintained by
- Microsoft
- Best known for
- Trace viewer — a time-travel debugger for failed runs
When to use it
The question documentation cannot answer for you — because it cannot recommend something else.
Reach for it when
- Testing real user flows across browsers
- You are tired of flaky tests — auto-waiting removes most arbitrary sleeps
- You need parallel execution, tracing and video on failure
Look elsewhere when
- Unit testing — it is far heavier than Vitest for testing a function
Installation
npm install -D playwrightGetting started
The smallest useful thing you can do with it, and what each part means.
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://example.com');
await browser.close();
})();const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.click('text=Sign in');
await page.fill('#username', 'myUser');
await page.fill('#password', 'myPass');
await page.click('#login');
await browser.close();
})();Advanced usage
Where the library earns its place over a simpler alternative.
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const context = await browser.newContext();
const page1 = await context.newPage();
const page2 = await context.newPage();
await page1.goto('https://example.com');
await page2.goto('https://example.org');
await browser.close();
})();await page.screenshot({ path: 'example.png' });await page.route('**/api/**', route => route.fulfill({ body: JSON.stringify({ data: 'mocked' }) }));const { firefox, webkit } = require('playwright');
// Launch Firefox or WebKit with the same API as ChromiumErrors and fixes
The failures you are most likely to hit, and what actually resolves them.
- TimeoutError
- Increase the timeout or ensure the element exists before interacting.
- Element not found
- Use robust selectors and consider using `page.waitForSelector` to wait for elements.
- Browser launch failed
- Ensure Playwright browsers are installed (`npx playwright install`) and dependencies are met.
Best practices
- Use page locators for stable element selection instead of brittle selectors.
- Leverage automatic waiting to reduce flakiness in tests.
- Run tests in headless mode in CI/CD pipelines for speed.
- Use browser contexts to isolate tests and avoid state sharing.
- Take screenshots or videos for debugging failed tests.
Alternatives
Comparable options, and the reason you would pick one over the other.
Background
Why it exists, and what it was reacting to.
Playwright was created by Microsoft to provide fast, reliable, and cross-browser automation for testing web applications. It aims to overcome the limitations of older tools like Selenium by providing automatic waiting, rich selectors, network interception, and built-in support for modern web features.
