Choosing an end-to-end framework is an architectural decision, not just a tooling preference. This article goes deeper than feature comparison: we look at how each framework talks to the browser, what its protocol layer is, and how that affects stability, speed, and debuggability in production CI.
Selenium: WebDriver protocol
Selenium talks to the browser via the W3C WebDriver protocol — a REST API the browser exposes (chromedriver, geckodriver, etc. translate it). Tests run in a separate process; the driver brokers every command.
Playwright: own protocol + BiDi
Playwright uses its own high-level protocol (later supplemented by W3C BiDi for network interception + console logs). The test runs in Node.js and connects to the browser via CDP (Chrome) or equivalent. Native auto-wait, parallel by default.
Cypress: in-browser proxy
Cypress runs a Node.js server that proxies commands into the browser process. Tests live inside the browser (you can `cy.window()` and access JS state). Strong dev experience; limited to JS/TS and the browsers Cypress ships.
Auto-wait behaviour
- Playwright — waits for elements to be actionable (visible, enabled, stable) before every action. Built-in.
- Cypress — retries assertions until they pass. Actions rely on commands that auto-wait.
- Selenium — does not auto-wait; you must use `WebDriverWait` + expected conditions for stability.