Three tools. Three ways to drive a browser.

Selenium, Cypress, and Playwright each talk to the browser differently. Read the process boundary in each lane. Selenium and Playwright sit outside the browser and drive it over a wire protocol. Cypress lives inside the browser. That one difference forecasts real Safari, any language, auto-wait, and grid scale before you read another word.

Selenium vs Cypress vs Playwright, chosen by how each drives the browser

There is no universally best browser automation tool. There is a best fit for how your team works, and the fastest way to find it is to look at how each tool physically drives the browser. This guide makes that one fact the spine, then derives every trade-off from it, and hands you a vendor-neutral picker that will tell a solo JS team to skip the grid.

This is tool selection, not test strategy#

First, a boundary the ranking pages never draw. This guide answers which tool to adopt. It does not answer what to test, how deep your pyramid should sit, or which flows deserve coverage. Those are test-strategy questions, and they matter more than the tool. However, they are a separate decision, and blurring the two is why most comparison pages leave you no clean answer.

The one fact behind Selenium vs Cypress vs Playwright: how each drives the browser#

Here is the spine of the whole comparison. Each tool talks to the browser in one specific way, and that one choice sets every downstream trade-off. Two of the three sit outside the browser and drive it over a wire protocol. One lives inside the browser. Because that boundary is fixed by design, you can forecast a tool's answer to a brand-new question from the drive mechanism alone.

Three drive mechanisms side by side: Selenium out-of-process over W3C WebDriver or BiDi, Cypress as an in-process resident inside one browser event loop, and Playwright out-of-process over CDP to a patched browser buildThe load-bearing picture. Selenium and Playwright drive the browser from a separate process over a wire protocol, so they reach any real browser and any language. Cypress runs inside the browser event loop, which buys deep insight into the app but caps it at one origin and one tab.

Notice what the boundary predicts. Because Selenium and Playwright run in a separate process, they can attach to any real browser and, for Selenium, speak from any language. Because Cypress runs in the page, it sees the application from the inside, yet it inherits the browser's same-origin and single-tab rules. That single distinction drives the three sections below.

Selenium: out-of-process over the W3C WebDriver protocol, and BiDi in version 4#

Selenium sends commands from your test process to a browser driver over the W3C WebDriver protocol. The driver then controls a real browser. Because the wire protocol is a public standard, any language with a client can drive it, and any real browser with a driver can be a target. That is where Selenium's two signature strengths come from directly.

First, the language reach. Python, Java, C#, JavaScript, and Ruby all speak WebDriver, so the tool never dictates your stack. Second, the browser matrix. A remote Grid runs Chrome, Firefox, Edge, and real Safari as nodes, so the matrix is the widest of the three. The honest cost is the flip side of the same fact. Because the driver acts on its own clock, WebDriver does not auto-wait, so you add explicit waits. Selenium 4 adds WebDriver BiDi to narrow that gap, which we return to later.

Cypress: a resident inside the browser event loop#

Cypress does not drive the browser from outside. Instead, your spec code runs inside the browser event loop, next to the application. Because the test and the app share one loop, Cypress sees every command, network call, and DOM change from the inside. That is exactly why its time-travel debugging and automatic waiting are best in class. It is watching the app from within, not guessing from across a wire.

The limits come from the same residency, so they are structural, not bugs. Because the runner lives in one browser context, it is JavaScript and TypeScript only. Because it lives in one origin by default, a cross-origin step needs cy.origin. Because it lives in one tab, it cannot drive two browsers at once, and a second tab needs a plugin. None of that is fixable with a flag, because it is the architecture.

Playwright: out-of-process over CDP and patched browser builds#

Playwright also sits outside the browser, but it speaks a different protocol. It drives patched builds of Chromium, Firefox, and WebKit out-of-process, mostly over the Chrome DevTools Protocol. Because it ships and controls its own browser builds, it can wait on the right signals automatically and intercept network traffic cleanly. Therefore auto-waiting and request control are built in, not bolted on.

The out-of-process design also unlocks scale and language reach. Because the runner is separate from the browser, Playwright shards runs across machines with a first-class parallelism model, and it offers official clients in JavaScript, Python, Java, and C#. The honest caveat is age. Playwright is the newest of the three and moves fast, so expect more churn between releases than the older tools carry.

From drive mechanism to the trade-off you feel in CI#

Now read the spine as a table. Each row starts from the architectural fact and ends at the consequence you actually feel in a pipeline. Because the cause sits next to the effect, you can extend the logic to a question the table does not list. That is the whole point of leading with architecture.

Architectural fact to the consequence you feel in CI, across Selenium, Cypress, and Playwright
QuestionSeleniumCypressPlaywright
Drive mechanismOut-of-process over WebDriver and BiDiIn-process, inside the event loopOut-of-process over CDP and patched builds
Any language?Yes: Python, Java, C#, JS, RubyNo: JS or TS onlyYes: JS, Python, Java, C#
Real Safari?Yes: safaridriver plus a Grid nodeNo: WebKit engine, experimentalNo: WebKit engine, not a device
Multiple tabs or windows?Yes, via the driverNo, one tab by designYes, contexts and pages
Cross-origin in one test?YesOnly via cy.originYes
Auto-wait by default?No, explicit waits (BiDi narrows it)Yes, built inYes, built in
Parallel across machines?Yes, you provision the GridYes, via its own modelYes, first-class sharding
Ecosystem maturityWidest and most portableFocused, JS-nativeNewer, fast-moving

Try the table on an unlisted question. Suppose you ask whether a tool can hit a login popup on a second domain mid-test. For Cypress the answer follows from residency, because one tab and one origin means no. For Selenium and Playwright the answer follows from running outside the browser, because a separate process can open another context. You did not need a feature list. You needed the drive mechanism.

A worked example: certify one app on three engines for a 600-test suite#

Abstract claims convince nobody, so here is where Selenium vs Cypress vs Playwright stops being theory. Certify a single web app on three rendering engines, which are Chromium, Firefox, and WebKit. The suite holds 600 tests. Across three engines that is 600 by 3, which is 1,800 executions. Watch how each tool declares that matrix, because the difference is the architecture made visible.

playwright.config.ts · ts
// playwright.config.ts — one config, three engines, one shard flag
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',              // the ~600-test suite
  fullyParallel: true,             // parallel worker processes per machine
  projects: [
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
    { name: 'firefox',  use: { ...devices['Desktop Firefox'] } },
    { name: 'webkit',   use: { ...devices['Desktop Safari'] } },
  ],
});

// npx playwright install            # pulls all three engines
// npx playwright test --shard=1/3   # 600 x 3 = 1,800 execs, split 3 ways

Playwright 1.61.1: one config, three projects, one shard flag#

Playwright declares the whole matrix in one place. One config lists three projects, and a single npx playwright install pulls all three engines. The 1,800 executions then split across three machines with --shard=1/3, --shard=2/3, and --shard=3/3. That is roughly 600 executions per machine, and each machine runs parallel workers on top. One language, one command, the whole matrix.

Cypress 15.18.1: Chrome and Firefox, with WebKit still experimental#

Cypress reaches part of the same goal, and it is honest about the gap. Chrome-family and Firefox are fully supported. However, the third engine is WebKit, and Cypress still flags WebKit support as experimental. That engine is not real Safari on a device either. So the three-engine target is only partly reachable here.

Selenium 4.46.0: the only path to genuine remote Safari#

Selenium is the one tool that reaches real Safari for this matrix. A remote Grid runs Chrome, Firefox, Edge, and Safari nodes, and safaridriver drives an actual Safari, in any language you like. The cost is equally plain. You provision and wire the Grid yourself, and you add explicit waits. WebDriver BiDi in version 4 narrows the wait gap, yet it is not the zero-config default the other two ship.

Read the three panels as one takeaway. The same 1,800-execution matrix is one install and one shard flag in Playwright, a partial and experimental third engine in Cypress, and the only route to genuine remote Safari in Selenium. In short, the drive mechanism wrote all three outcomes before you typed a line.

The six axes that actually decide Selenium vs Cypress vs Playwright#

Set your real constraints and the instrument returns a reach-for-X verdict, with the architectural reason attached. It is deliberately neutral. Because no testing-cloud grid is selling you anything here, a solo JavaScript team on modest CI is told to reach for Cypress and skip the grid entirely. Move the six controls and watch the verdict and the scores change.

Set your six real constraints

Required browser and device matrix
Real Safari on a device forecloses the choice on its own.
Team language
Cypress is JavaScript and TypeScript only, by architecture.
CI parallelism and scale
Heavy sharding rewards first-class parallelism.
Flakiness tolerance and auto-wait
Built-in auto-waiting versus explicit WebDriver waits.
Developer experience
Time-travel debugging versus standard tooling.
Ecosystem and lock-in
A mature, portable ecosystem versus newer-tool momentum.
Reach forCypressa resident inside the browser event loop

A JavaScript or TypeScript team on modest CI that never needs real Safari or a second tab. Because Cypress runs inside the browser event loop, you get time-travel debugging and automatic waiting for free. You can skip the grid entirely.

The honest cost: That resident architecture is also the ceiling: same-origin by default (cross-origin needs cy.origin), one browser at a time, and JS or TS only. WebKit support is experimental, not real Safari.

  • Seleniumscore 4
  • Cypressscore 13
  • Playwrightscore 10

The two hard rules are what keep it honest. First, must-have real Safari on a device points to Selenium every time, because out-of-process WebDriver is the only path to it. Second, a polyglot team removes Cypress from the running, because a resident in the browser event loop is JavaScript and TypeScript by construction. Every other axis then nudges the score.

Required browser and device matrix#

This axis forecloses the choice more often than any other. Because real Safari on a device needs safaridriver and a Grid, that requirement points straight to Selenium. Chromium-only work, in contrast, frees you to pick on developer experience instead, since all three cover it well.

Team language#

Language is decided by the drive mechanism, not by preference. Because Cypress runs inside the browser event loop, it is JavaScript and TypeScript only. Selenium and Playwright both run out-of-process, so both are polyglot. A Python or Java team is therefore choosing between those two before any other axis is weighed.

CI parallelism and scale#

Scale rewards the tools built to run outside the browser. Because Playwright shards runs across machines by design, heavy parallel matrices are its home turf. Selenium scales too, yet you provision and maintain the Grid that makes it happen. Cypress parallelizes through its own model, which suits modest suites well.

Flakiness tolerance and auto-wait#

Auto-waiting tracks where the runner sits. Because Cypress and Playwright can watch the app closely, they auto-wait by default, which cuts a common source of flakiness. Selenium historically leaned on explicit waits. However, WebDriver BiDi now streams events that close much of that gap, so the old critique is dated.

Developer experience#

Developer experience is where residency pays off most. Because Cypress lives in the page, its time-travel debugger replays each step with the DOM snapshot attached. Playwright answers with a strong trace viewer and codegen. Selenium is the most manual of the three, which is the trade for its reach.

Ecosystem and lock-in#

Finally, weigh maturity against momentum. Because Selenium is the oldest and standard-based, its ecosystem is the widest and the most portable across languages and vendors. Playwright carries the momentum and ships features fast. Cypress sits between them, focused and JavaScript-native. Pick the trade you can live with for years.

2026 reality check#

Much of the folklore around Selenium vs Cypress vs Playwright is stale, so here is the current state on three points that change the decision. Some limitations get repeated long after they stop being true.

Reach for X when, including the anti-upsell case#

The picker gives a verdict per scenario. These blocks settle Selenium vs Cypress vs Playwright as plain prose instead, and each one names the real weakness, not just the strength. That is the honesty every grid-owned ranking page skips.

Reach for Selenium when you need real Safari, any language, or a mature grid#

Reach for Selenium when the browser matrix or the team language forecloses the others. Because it drives out-of-process over WebDriver, it reaches real Safari through safaridriver and speaks from any language. The weakness is setup. You provision the Grid and add explicit waits, and BiDi only narrows that, so budget for the wiring before you commit.

Reach for Cypress when a JS team wants great DX and never needs Safari or multi-tab#

This is the anti-upsell case, stated plainly. A JavaScript or TypeScript team, on a single-origin app, running modest CI, should reach for Cypress and skip the grid entirely. Because it lives in the event loop, the debugging is superb and the waits are automatic. The weakness is the same residency. No real Safari, one origin by default, and one tab, so if you need any of those, choose elsewhere.

Reach for Playwright when you need parallelism, many languages, and modern auto-wait#

Reach for Playwright when scale and breadth lead the decision. Because it drives patched builds out-of-process over CDP, it shards cleanly across machines, auto-waits by default, and runs from several languages. The weakness is youth. It is the newest tool and it moves fast, so pin versions and expect churn between releases you would not see in Selenium.

When the tool choice is NOT the decision#

Sometimes the tool is not your problem, and swapping it will not help. Before you migrate a suite, rule out the two cases where the driver is a distraction from the real fix.

So keep the order straight. Get the strategy and the test design right first. Then, and only then, use the drive mechanism to pick the runner. In short, Selenium vs Cypress vs Playwright is a real decision, but it is downstream of knowing what you are testing and why.

Weighing a runner for a real suite, or trying to turn a flaky matrix back into a fast one? This pairs naturally with accessibility testing inside your automated suite, and the Atyantik team is happy to talk it through. No pressure and no lock-in.

See Atyantik's approach to scaling and optimizing existing software

Jaykrishna Vijayan

Software Engineer, Atyantik Technologies

Detail-oriented QA Software Engineer experienced in Software Testing and Quality Assurance. Skilled in manual and automated testing, defect tracking, and test case execution using tools like Jira, TFS, Browserstack and Selenium. Committed to ensuring seamless user experiences and maintaining high software standards.

More from Jaykrishna VijayanScale and optimize existing softwareTalk to Atyantik

Keep reading