Cypress interview question
How does Cypress's architecture differ from Selenium's?
Short answer
Selenium drives the browser from outside via the WebDriver protocol. Cypress runs test code inside the browser next to the app, with a Node.js process for tasks and network proxying. That gives automatic retries, network control and time-travel debugging, at the cost of multi-tab and cross-origin limits.
Answer
The core difference is where the test code runs.
Selenium: out-of-process control
Your test runs in its own process (Java, Python, C#, JS). Each action is a WebDriver command sent over HTTP to a browser driver, which drives the browser. The test and the app never share memory. That is why Selenium supports many languages and real multi-window scenarios, but every interaction is a network round trip and synchronisation is left to you.
Cypress: in-browser execution
When you run Cypress, it launches a browser and loads the Cypress app, which hosts your application under test in an iframe and runs your spec file in the same browser, in the same JavaScript run loop as the app. Alongside it, a Node.js server process:
- acts as a proxy for all HTTP traffic, which is how
cy.interceptcan observe and stub requests; - runs
cy.taskcode and plugins configured insetupNodeEvents(database seeding, reading files); - manages screenshots, videos and the run.
Because the test sits next to the app, Cypress can:
- retry queries and assertions automatically until they pass or time out, without explicit waits;
- snapshot the DOM at each command so you can time-travel in the runner;
- access
window, the app’s objects andlocalStoragedirectly; - control the network and the clock (
cy.clock) deterministically.
describe('login', () => {
it('shows the dashboard', () => {
cy.intercept('POST', '/api/login').as('login');
cy.visit('/login');
cy.get('[data-cy=email]').type('qa@example.com');
cy.get('[data-cy=password]').type('secret', { log: false });
cy.get('[data-cy=submit]').click();
cy.wait('@login').its('response.statusCode').should('eq', 200);
cy.contains('h1', 'Dashboard').should('be.visible');
});
});
Trade-offs to mention
- Language: JavaScript or TypeScript only.
- Tabs and windows: Cypress controls one tab. You test links that open new tabs by checking the
hrefor removingtarget, not by switching windows. - Origins: a test visiting multiple superdomains needs
cy.origin()for the second origin. - Browsers: Chrome-family, Firefox and Electron are supported; WebKit support is experimental. Selenium covers Safari through safaridriver.
- Events: by default
.click()and.type()are simulated in JavaScript, which is very close to real behaviour but not identical to OS-level input. Selenium’s actions go through the browser’s automation interface.
Choosing
For a JavaScript front-end team that wants fast feedback and great debugging on a single-origin app, Cypress is a strong fit. For multi-language organisations, Safari coverage, or flows spanning many windows and domains, Selenium (or Playwright) is often a better fit. I would base the choice on the app’s constraints and team skills, not on popularity.
What interviewers look for
- The in-browser vs out-of-process distinction, stated clearly.
- Knowing the Node process exists and what it does.
- Balanced trade-offs rather than “Cypress is faster” or “Selenium is outdated”.
A strong answer covers
- Cypress runs test code inside the browser, in the same run loop as the app
- Selenium drives the browser externally via WebDriver protocol and drivers
- Node server process handles proxying, cy.task and file system
- Trade-offs: multi-tab, multiple browsers, cross-origin (cy.origin), language choice