Cypress vs. Selenium: Differences, Pros, and Cons
Compare Cypress and Selenium by architecture, languages, browser support, debugging, and maintenance—and choose the right fit for your test suite.
Cypress and Selenium both automate browser tests, but they fit different workflows. Cypress is a JavaScript- and TypeScript-oriented testing framework with an integrated runner and test code that executes in the browser’s run loop alongside the application. Selenium WebDriver is a browser automation interface with language bindings and browser-specific drivers; teams combine it with their preferred test runner and assertion tools. Choose Cypress when its language and workflow fit your team. Choose Selenium when you need its broader language ecosystem, existing WebDriver infrastructure, or a stack you can compose around your requirements.
Neither tool is universally faster or more reliable. Compare the exact browser and version matrix, test scenarios, CI environment, debugging needs, and ongoing maintenance. The sections below give runnable starting points and a practical selection guide.
1. The core difference: how tests control the browser
Cypress runs test code in the browser’s run loop alongside the application and coordinates with a Node process. That integrated model supports browser-aware test commands, retry behavior, and network interception. It does not mean every test is automatically reliable: test design, application state, selectors, and environment still matter. Cypress documents its architecture and rationale.
Selenium WebDriver controls a browser through a language binding and a browser-specific driver. The test can run on the same machine or communicate remotely through Selenium Server or Grid. WebDriver itself handles browser commands; a separate test framework typically runs tests and assertions. See the Selenium components overview and Selenium project overview.
| Question | Cypress | Selenium WebDriver |
|---|---|---|
| Where does test code run? | In the browser run loop, coordinated with a Node process. | Outside the application, issuing WebDriver commands through a driver. |
| What language is the natural fit? | JavaScript or TypeScript. | Multiple bindings, including Java, Python, C#, Ruby, and JavaScript. |
| Who supplies the test runner? | Cypress includes an integrated runner and common testing capabilities. | You select a language-appropriate runner and assertion library. |
| How is browser control set up? | Cypress launches supported browsers installed in the environment; it does not use the Selenium driver model. | A browser-specific WebDriver implementation handles browser control; Selenium Manager can help manage drivers. |
| How does scaling work? | Cypress describes Cloud features for parallelization, replay, and reporting. | You can use Selenium Grid or other infrastructure to distribute browser sessions. |
2. Runnable examples
Cypress: install and run a basic end-to-end test
Prerequisites: Node.js and npm. In an existing JavaScript project, install Cypress and open its setup flow:
npm install --save-dev cypress
npx cypress open
For a minimal end-to-end setup, create cypress.config.js:
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
baseUrl: 'https://example.com',
supportFile: false
}
})
Save this test as cypress/e2e/home.cy.js:
describe('example home page', () => {
it('loads and shows a heading', () => {
cy.visit('/')
cy.get('h1').should('be.visible')
})
})
Run it headlessly, or open the interactive runner:
npx cypress run
npx cypress open
Cypress retries many queries and assertions while waiting for the expected UI state. Prefer assertions tied to the state you need over fixed sleeps. To choose an installed browser, use npx cypress run --browser chrome; to show the browser during a run, add --headed. The current browser launch documentation lists supported browsers, version constraints, and WebKit’s experimental status.
Selenium WebDriver with Python: install and run a basic test
Prerequisites: Python and a supported browser. Install the Python binding:
python -m pip install selenium
Save as test_example.py. Selenium Manager is used by Selenium bindings to assist with driver management; the browser still needs to be available:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
def test_example_home_page():
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
heading = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.TAG_NAME, "h1"))
)
assert heading.is_displayed()
finally:
driver.quit()
if __name__ == "__main__":
test_example_home_page()
Run the standalone example with python test_example.py. For a suite, put the test in a project using a runner such as pytest, install it with python -m pip install pytest, and run pytest. For other languages, install the official Selenium binding and pair it with a runner suited to that language, such as JUnit for Java or NUnit for .NET. Check the Selenium WebDriver getting started guide for current setup instructions.
3. Pros and trade-offs
Cypress
- Integrated workflow: a runner, assertions, retry behavior, and network interception are available in the Cypress workflow.
- Browser-aware debugging: the runner and its debugging features can make it easier to inspect a failing UI interaction.
- JavaScript and TypeScript fit: browser tests can use the language familiar to a front-end team.
- Constraints to check: test code is JavaScript/TypeScript-oriented, and Cypress is designed around one open browser at a time. Verify whether that fits workflows involving multiple simultaneous browser windows or languages outside its test model.
- Browser matrix: Cypress documents Chrome-family browsers and Firefox, with WebKit support marked experimental. Check exact versions and platform requirements before relying on a browser in CI.
Selenium WebDriver
- Language choice: language bindings support teams using ecosystems such as Java, Python, C#, Ruby, and JavaScript.
- Composable stack: choose a test runner, assertion library, reporting, and execution infrastructure to suit an existing project.
- Browser infrastructure options: direct drivers, remote sessions, and Selenium Grid support a range of execution setups.
- More pieces to integrate: teams own the choices and compatibility of bindings, runners, browser versions, driver setup, waits, and CI infrastructure.
These are workflow trade-offs, not proof that one framework is faster or more stable. The research for this comparison found no neutral, controlled benchmark comparing both tools under the same application, browser, test design, and infrastructure.
4. Browser support and test requirements
Do not decide from a general claim like “cross-browser support.” Make a matrix of the browsers, versions, operating systems, and CI images your users require. Cypress’s current documentation covers Chrome-family browsers, Firefox, and experimental WebKit, with version-specific constraints. Selenium uses browser-specific WebDriver implementations; consult its browser documentation for the browser you plan to automate.
Also check scenarios that are not simply “click a button and assert a result”: multiple tabs, cross-origin flows, downloads, permissions, authentication, native dialogs, and remote execution can affect which tool and supporting libraries you need. Prototype the riskiest required scenario before migrating a large suite.
5. Waiting, network control, and debugging
Asynchronous pages need synchronization with observable conditions. Cypress’s retry-ability and cy.intercept() can reduce boilerplate for common UI and network tests. Selenium suites generally use explicit waits such as WebDriverWait and expected conditions; use the Selenium version and language binding’s current wait APIs. Fixed sleeps in either approach make tests slower when the page is ready early and flaky when it is not ready when the timer ends.
For a failing test, capture enough evidence to reproduce it: the failing assertion, browser and version, environment, relevant network responses, and a screenshot or video if your runner provides one. Cypress documents runner and Cloud debugging features; Selenium’s artifacts depend on the runner and infrastructure you select. Vendor descriptions of their own features are not independent comparative evidence.
6. Choosing between them
| Choose Cypress when… | Choose Selenium when… |
|---|---|
| Your browser tests are primarily JavaScript or TypeScript. | Your tests need a language binding outside Cypress’s JavaScript/TypeScript-oriented model. |
| You want an integrated runner and browser-aware debugging workflow. | You already have WebDriver tests, drivers, or Grid infrastructure worth keeping. |
| Your required browsers and scenarios fit Cypress’s documented support and constraints. | You need to assemble a flexible stack around existing runners or remote browser infrastructure. |
| Your team prefers integrated defaults over selecting each test component. | Your team values choosing and maintaining the components independently. |
For a mixed estate, the tools can coexist. Keep each suite focused on valuable coverage: duplicating every test in both frameworks can add maintenance without adding meaningful confidence. If migrating, start with a small set of critical user journeys, compare behavior and failure diagnostics, and then decide whether broader migration is justified. Cypress’s migration guide includes language, browser setup, and API mapping considerations.
7. Setup, performance, reliability, and cost
Setup and maintenance
Cypress supplies more of the testing workflow in one package. You still need to maintain Node dependencies, application test data, supported browser versions, CI configuration, and test quality. Selenium gives you a language-neutral browser-control model, but the project must select and maintain the matching runner, assertions, browser/driver environment, and any distributed execution components. Selenium Manager is available through bindings for driver management, but does not eliminate the need to manage the broader test stack.
Performance
There is no universal speed winner established by the cited research. Runtime depends on test count and design, browser startup, application and network latency, parallel capacity, retries, and CI resources. Measure your own representative suite with the same application, browser, machine class, and test coverage. Separate browser startup and queue time from the time spent exercising application behavior.
Reliability
Reliability is mostly a property of the complete test system. Use stable selectors, deterministic test data, isolated state, explicit conditions, and clear cleanup. Keep browser and driver versions reproducible in CI. Record retries and investigate flaky tests instead of treating repeated passes as proof that the underlying cause is gone. Pick the framework whose constraints and diagnostics match the failure modes your team needs to handle.
Cost
Both frameworks are open-source projects, but the cost of operating a test suite includes engineering time, CI minutes, browser infrastructure, parallel capacity, and any optional hosted products. Cypress describes Cloud features such as parallelization, replay, and reporting; evaluate the current plan and your expected usage directly before budgeting. Selenium Grid and other execution infrastructure also consume time and compute. Compare the total cost for your actual suite rather than a framework label.
8. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Cypress cannot launch the requested browser. | The browser is not installed, not detected, or outside Cypress’s supported version constraints. | Check npx cypress info, install a supported browser in the environment, and consult the current browser launch matrix. |
| Cypress WebKit run fails or behaves differently. | WebKit support is experimental and has documented limitations. | Check the current known issues and required dependencies; treat WebKit results as experimental validation for your specific scenario. |
| Cypress assertion times out. | The element never reached the expected state, the selector is wrong, or the application did not load as expected. | Inspect the runner and network activity, verify the selector and fixture data, and assert on the actual state transition. Avoid replacing the condition with a longer arbitrary sleep. |
| Selenium reports that a driver cannot be found or started. | Browser installation, permissions, environment, or driver/browser compatibility is wrong. | Confirm the browser exists in the execution environment, update Selenium, check Selenium Manager output, and pin compatible browser images where reproducibility matters. |
| Selenium element lookup fails intermittently. | The lookup happens before the UI is ready, or the locator is unstable. | Use an explicit wait for the required condition and a stable locator. Avoid mixing implicit waits with explicit waits without understanding the resulting behavior. |
| Tests pass locally but fail in CI. | Different browser versions, missing dependencies, timing, viewport, state, or resource limits. | Align local and CI browser versions and configuration; preserve logs and screenshots; verify test data isolation and wait conditions. |
| A test needs a second tab or simultaneous browser sessions. | The scenario exceeds the selected tool’s default workflow or needs remote session orchestration. | For Cypress, verify its single-open-browser constraint and documented alternatives; for Selenium, use window handles or separate sessions and ensure cleanup. |
| Suite runtime or flakiness grows as tests are added. | Shared state, fixed sleeps, repeated setup, or oversubscribed parallel workers may be accumulating. | Measure slow tests, isolate state, replace sleeps with condition-based waits, and tune parallelism against available browser and CI capacity. |
9. ScreenshotNeo for screenshots outside the test suite
Cypress and Selenium are browser automation choices for testing. When the separate task is capturing a webpage image or PDF—for documentation, review, or a visual reference—ScreenshotNeo is an API and MCP server for developers. It is an alternative to try first for that capture task: cookie banners, newsletter popups, and chat widgets are removed before capture, and only clean shots are billed. Its response headers identify page verdict and billing outcome. It does not replace end-to-end test assertions or browser interaction coverage.
Or skip the browser setup:
One GET request returns an image or PDF. See the ScreenshotNeo API documentation for request parameters and response behavior.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-o shot.webp
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://stripe.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));
Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, with no card required.
10. FAQ
Can Cypress replace Selenium?
It can replace some WebDriver suites if the language, browser matrix, and test scenarios fit Cypress. It is not a drop-in replacement: tests and supporting code may need rewriting, especially when they are in Java, Python, C#, or Ruby.
Can a team use both?
Yes. A team can keep existing Selenium coverage and use Cypress for suitable JavaScript/TypeScript workflows. Define which suite owns which coverage so duplicate tests do not create unnecessary upkeep.
Is Cypress WebKit the same as testing Safari?
Cypress documents WebKit as experimental support for Safari’s browser engine. Confirm current constraints and validate the behavior you need; do not assume it is equivalent to a supported Safari browser matrix.
Which one should a beginner learn first?
Start with the framework that matches the language and browser workflow you will use on a real project. Learn explicit synchronization, stable selectors, isolated test data, and failure diagnosis whichever framework you choose.
