Playwright vs. Selenium β Definition and Differences
Compare Playwright and Selenium for browser automation: architecture, waiting behaviour, language support, grid infrastructure, and when each is the right choice.
Selenium has driven browsers since 2004 and is a W3C standard; Playwright arrived in 2020 and talks to browsers over their own debugging protocols. The architectural gap between those two facts explains nearly every practical difference β speed, flakiness, and what each can reach inside the browser.
1. What Is Selenium?
Selenium automates browsers through the W3C WebDriver protocol, a standardised HTTP API that each browser vendor implements in its own driver binary.
- Key idea: a vendor-neutral standard, deliberately implemented outside the browser.
- Mechanism: your code β WebDriver HTTP commands β
chromedriver/geckodriverβ browser. - Goal: write once, run against any conforming browser, including real Safari and Edge.
Example of Selenium
driver.get("https://example.com")
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "h1")))
print(driver.find_element(By.CSS_SELECTOR, "h1").text)
The explicit wait is characteristic. Selenium does not wait for you by default, and code that omits it works locally and fails in CI.
2. What Is Playwright?
Playwright drives Chromium, Firefox and WebKit through their native debugging protocols, over a persistent connection, with waiting built into every action.
- Key idea: one API across three engines, with the automation logic inside the tool rather than in your test code.
- Mechanism: a persistent WebSocket to the browser, plus a driver process, with bindings for several languages.
- Goal: eliminate the flakiness class that explicit waiting exists to paper over.
Example of Playwright
page.goto("https://example.com")
print(page.text_content("h1"))
No wait, because text_content waits β for the element to be attached, visible, and stable β before reading.
3. Key Differences Between Playwright and Selenium
| Selenium | Playwright | |
|---|---|---|
| Protocol | W3C WebDriver (HTTP) | CDP / native protocols (WebSocket) |
| Standardised | Yes β W3C | No β vendor-independent but not a standard |
| Browsers | Chrome, Firefox, Safari, Edge, more | Chromium, Firefox, WebKit |
| Real Safari | Yes, via safaridriver |
No β WebKit approximates it |
| Waiting | Explicit, your responsibility | Automatic on actions |
| Speed | Slower β HTTP round trip per command | Faster β persistent connection |
| Languages | Java, Python, C#, Ruby, JS, and more | JS/TS, Python, Java, .NET |
| Network interception | Limited | First-class |
| Parallel isolation | New driver + browser per session | Browser contexts, cheap |
| Test runner | Bring your own | Playwright Test included |
| Ecosystem age | Two decades | Since 2020 |
4. Relationship Between the Two
Playwright did not evolve from Selenium β it came from the Puppeteer lineage and took a deliberately different architectural bet. Selenium chose standardisation and pays for it in performance and capability ceilings; Playwright chose direct protocol access and pays for it by not being a standard.
Example to Illustrate
Consider intercepting a network request to stub an API response.
In Playwright this is a first-class operation: page.route() intercepts, modifies, or fulfils requests directly, because the debugging protocol exposes the network layer.
In Selenium this historically required an external proxy, since WebDriver does not model network interception. Selenium 4 added CDP access for Chromium to close the gap β which is telling, because it means reaching outside the standard to match a capability the standard does not cover.
That is the trade in one example: the standard gives you Safari, and the protocol gives you the network.
5. When to Use Playwright vs. Selenium
Use Selenium when:
- You must test real Safari β this is the decisive case, and Playwright's WebKit is an approximation, not Safari.
- You need a browser Playwright does not support, or an unusual vendor driver.
- Your organisation already runs a Selenium Grid with the operational knowledge to match.
- You work in a language with Selenium bindings and no Playwright ones, such as Ruby or PHP.
- Standards compliance is a procurement or compliance requirement.
Use Playwright when:
- Flakiness from timing is your recurring cost β auto-waiting removes the cause rather than the symptom.
- You want network interception, request stubbing, or HAR replay without an external proxy.
- Test suite wall-clock time matters; the persistent connection is meaningfully faster.
- You want a runner, fixtures, parallelism, tracing and retries without assembling them.
- You are scraping JavaScript-heavy pages and want fewer moving parts.
6. Real-World Examples
- A suite with scattered
sleep()calls is describing a problem Playwright's auto-waiting solves structurally. Migrating usually deletes more code than it adds. - A Safari-specific rendering bug can only be reproduced in Selenium against real Safari.
- CI runtime dominated by browser startup improves under Playwright's contexts, which are far cheaper than new browser sessions.
- A legacy suite of thousands of Selenium tests is rarely worth rewriting wholesale β the migration cost is real and the existing tests work.
- Scraping a client-rendered site is simpler in Playwright, mostly because waiting is handled and network responses are directly readable.
7. Summary
Selenium is the standard: broadest browser coverage, real Safari, the widest language support, and two decades of tooling. Playwright is the faster, more capable driver: auto-waiting, native network interception, cheap isolation, and a test runner included.
For new work without a hard Safari requirement, Playwright removes an entire class of flakiness and is the lower-friction choice. For real Safari coverage, unusual browsers, or an established grid and skill base, Selenium remains correct. The two coexist comfortably β plenty of teams run Playwright for day-to-day work and Selenium for the Safari matrix, and that is a reasonable answer rather than a compromise.