Playwright is Microsoft's open-source end-to-end testing framework. It launched in 2020 as a fresh take on browser automation and has, in five years, become the fastest-growing tool in the QA stack — overtaking Cypress in npm downloads in 2024 and now backing test suites at companies like Microsoft, Adobe, VS Code, and Disney+. If you've used Cypress, almost every concept transfers; the architecture is what's different.
This first lesson is the only one in the course without runnable test code. The rest of chapter 1 gets you installed and writing your first real spec — but understanding why Playwright works the way it does is what stops you fighting the framework later.
Three architectures, three trade-offs
There are three meaningful ways a test framework can drive a browser, and each makes different things easy and hard.
Selenium / WebDriver is the original. Your test process runs in one OS process; the browser runs in another; the WebDriver protocol carries every command between them over HTTP. Click a button → encode the command → send it over HTTP → browser receives → executes → encodes the result → sends it back. Every action pays that round-trip cost, plus you maintain a separate WebDriver binary per browser.
Cypress made the opposite bet. Its runner injects test code straight into the browser as a frame next to your app. Tests and app share one JavaScript event loop. Calling cy.get() doesn't cross any process boundary — but the same architecture imposes hard limits: one browser tab at a time, same-origin only (until cy.origin), no native multi-tab flows, no WebKit/Safari in production.
Playwright chose a third path. It drives the browser through the Chrome DevTools Protocol (and patched equivalents for Firefox and WebKit) from a Node.js process. The test runs outside the browser — like Selenium — but the protocol is faster, richer, and bidirectional. Playwright sees every network request, can intercept any of them, and can drive multiple tabs, multiple origins, and multiple browser contexts simultaneously. No WebDriver binary, no separate driver process — Playwright manages browser builds itself.
Where each one wins
Selenium vs Cypress vs Playwright — architecture and capabilities
Selenium / WebDriver
Drives browsers via the WebDriver HTTP protocol
Network round-trip on every action — slower than DevTools-based tools
Largest browser coverage: Chrome, Firefox, Safari, Edge, IE legacy
Built-in waiting is limited; teams reach for sleep() and explicit waits
Cypress
Test code runs inside the browser as a sibling frame
Same JavaScript event loop as the app — direct DOM access
One tab, mostly same-origin — multi-tab and WebKit are limited
Excellent DX: time travel, command log, hot-reload runner
Playwright
Drives browsers via Chrome DevTools Protocol from Node
Multi-browser, multi-tab, multi-origin natively — no workarounds
Chromium, Firefox, and WebKit (Safari engine) in one suite
Trace viewer: time-travel debugging with full network and DOM history
What Playwright unlocks over Cypress
If you're coming from Cypress, the architectural difference shows up as five concrete capabilities you won't have to fight for:
- Cross-browser at the project level. A single config can run every test against Chromium, Firefox, and WebKit in parallel. WebKit is Safari's rendering engine — the closest thing to actual iOS Safari coverage you can get without a real device.
- Multi-tab and multi-origin flows. Playwright models a
BrowserContext(an isolated profile, like an incognito window) that can have manyPageobjects (tabs). SSO redirects, payment popups, "open in new tab" links — all native, no plugins. - First-class API testing. The
requestfixture is a built-in HTTP client. You can hitPOST /api/usersto seed data, run a UI assertion against it, and chain both in the same test — no separate Postman or supertest layer. - Parallelism by default. Playwright runs files across multiple worker processes from day one. A 200-test suite that runs in 12 minutes serially typically lands at 2-3 minutes with no extra config.
- The trace viewer. Each failed test can save a
trace.zipcontaining every action, every DOM snapshot, every network call, and every console log.npx playwright show-trace trace.zipopens an interactive timeline — you scrub to the failure and see exactly what the page looked like. It's the single best debugging tool in any testing framework today.
What Playwright unlocks over Selenium
If you're coming from Selenium, the wins look different:
- Modern API. Async/await, web-first auto-retrying assertions, typed locators. No more
Thread.sleepor hand-rolledWebDriverWaitchains. - Speed. Direct DevTools protocol vs HTTP commands per action. Suites that took 30 minutes in Selenium often run in 5 minutes in Playwright.
- Zero driver setup. No
chromedriverbinary version mismatches.npx playwright installdownloads pinned, deterministic browser builds Playwright drives directly. - Built-in tooling. Codegen records tests from manual interactions. Inspector lets you step through tests interactively. HTML reporter, trace viewer, video recording, screenshot diff — all in the box, all configured by default.
Where Playwright sits in the language ecosystem
Playwright supports TypeScript and JavaScript first — the test runner (@playwright/test) is TS-native — but the underlying browser-automation library is also officially supported in Python, Java, and C#. The TypeScript flavour is what this course teaches and what the vast majority of the JS-ecosystem QA roles ask for. If your team is on Python with pytest, the same APIs and concepts translate; only the syntax changes.
What Playwright can — and can't — test
Playwright drives anything Chromium, Firefox, or WebKit can render: SPAs, server-rendered pages, web components, iframes, shadow DOM, file uploads, browser extensions (experimentally). It speaks WebSockets, can intercept any network request, and has built-in mobile emulation for hundreds of devices.
It does not test native mobile apps (use Appium or a native framework) or desktop apps (use a tool like WinAppDriver). Multi-window flows that span the operating system — like clicking a deep link from Slack into your app — are also out of scope. For 95% of QA engineering work on web products, none of these matter.
Browser support and licensing
Playwright is MIT-licensed, free, and maintained by Microsoft with active monthly releases. The bundled browser builds are pinned versions of Chromium, Firefox, and WebKit — Microsoft contributes patches upstream so the protocol surface stays consistent. There is no commercial paid tier; Microsoft Playwright Testing (a managed service for parallel cloud runs) exists but is optional.
If you've calibrated on Cypress Cloud or Sauce Labs, the bar to adopt Playwright is lower: the local-and-CI experience is fully featured without any paid add-on. The Playwright tool page on qa.codes has the canonical version-and-feature reference; the Playwright commands cheat sheet is the one-page API reference we'll work through across the next nine chapters.
⚠️ Common mistakes
- Treating Playwright as "Cypress with multiple browsers." It's a different shape. Tests are async/await — every command returns a Promise, every assertion needs
await. Locators are queried fresh every time (no jQuery wrap). Page objects ownLocatorinstances rather than chained selectors. Skim chapter 2 before porting an existing Cypress suite line-for-line. - Picking Playwright purely for speed. Yes, it's faster than Selenium and roughly equal to Cypress. But the real wins are multi-browser, multi-tab, and the trace viewer. If your suite is single-tab and you only ever ship Chromium, the speed delta alone may not justify the migration cost.
- Skipping the trace viewer. New Playwright teams sometimes treat traces as "screenshots, but heavier" and turn them off to save disk. They're the single most leveraged debugging artefact you'll ever produce. Configure
trace: 'on-first-retry'from day one — the cost is tiny, and the first time CI flakes a test you can't reproduce locally, you'll want one.
🎯 Practice task
Get oriented before installing anything. 15-20 minutes.
- Open the Playwright homepage and the Playwright GitHub repository in two tabs. Spend five minutes scanning each — note the version number, the licence, the contributor count, and the release cadence. You're calibrating which framework you're about to commit to.
- Open a real-world Playwright test suite — the Playwright tests in the VS Code repository or any open-source project's
tests/folder. Read one.spec.tsfile end to end without running it. Notice the shape:import { test, expect } from '@playwright/test',test.describe,test.beforeEach,await page.goto,await page.getByRole(...).click(),await expect(...). You're learning the rhythm of a Playwright test before you write one. - Make a one-page note answering these in your own words:
- Why does Playwright not need a separate WebDriver binary?
- What can Playwright test that Cypress can't — and what can Selenium still do that Playwright doesn't?
- When would your team still pick Cypress, and when would Selenium still be the right call?
- Stretch: find a Playwright test that uses
page.route(network mocking) orrequest.post(API testing) in any open-source repo. Read the lines around it and write a one-sentence guess at what it's stubbing or seeding. You'll learn the actual APIs in chapter 4 — for now, just notice that network and API code lives next to UI code in the same test file.
You now have a clear picture of what Playwright is and why teams adopt it. The next lesson installs Playwright with TypeScript and walks you through every file the scaffold creates.