Exit course
Chapter 4 of 8 Intermediate 5 min read Updated

Cypress Interview Questions

On this page
  1. Junior level
  2. Mid level
  3. Senior level

Cypress questions almost always circle back to one idea: Cypress runs inside the browser, next to your application, and its commands are queued rather than executed immediately. Candidates who understand those two facts can derive most of the answers. Examples target Cypress 16.

Junior level#

How does Cypress's architecture differ from Selenium's?#

Selenium drives the browser from outside, over the WebDriver protocol. Cypress loads your test code into the browser and runs it in the same run loop as the application, while a Node.js process alongside it handles tasks the browser cannot (file system, database seeding, the network proxy layer). That gives Cypress direct access to the DOM, window and the application's objects, and makes its interactive runner very good for debugging.

  • Follow-up: "What are the consequences?" A test controls one browser tab; there is no switching between tabs. Visiting a second origin in one test requires cy.origin(). Languages are JavaScript and TypeScript only.
  • Red flag: "Cypress is built on Selenium." It is not; see Cypress vs Selenium for the detailed differences.

Why can't you write const button = cy.get('button')?#

Cypress commands are enqueued, not executed when the line runs. cy.get() returns a chainable that will yield the element later, not the element itself. You work with yielded values inside .then(), or through aliases:

cy.get('[data-cy=total]').invoke('text').then((text) => {
  const total = Number(text.replace('$', ''));
  expect(total).to.be.greaterThan(0);
});
  • Follow-up: "Is a Cypress chain a Promise? Can you await it?" No. It looks thenable, but mixing async/await with Cypress commands breaks the queue.
  • Red flag: Using cy.wait(5000) to "let the page load".

What is retry-ability?#

Queries such as cy.get(), .find() and .contains(), plus the assertions chained after them, are retried until the assertion passes or the timeout (4 seconds by default) expires. Actions such as .click() are not retried; they run once the preceding query has yielded an actionable element.

cy.get('[data-cy=cart-count]').should('have.text', '3'); // retried
  • Follow-up: "Your .then() callback contains an expect that fails intermittently. Why?" Code inside .then() runs once and is not retried. Move the check into .should() with a callback if it needs to wait.

Mid level#

How do you wait for an API call instead of using fixed waits?#

Intercept it, alias it and wait on the alias:

cy.intercept('POST', '/api/orders').as('createOrder');
cy.get('[data-cy=place-order]').click();
cy.wait('@createOrder').its('response.statusCode').should('eq', 201);

cy.intercept() can also stub the response (cy.intercept('GET', '/api/products', { fixture: 'products.json' })) to test edge cases such as empty lists or 500 errors.

  • Follow-up: "What changed with intercepts in Cypress 16?" In Chrome, Chromium and Edge, Cypress now intercepts on the browser's native network stack and no longer terminates TLS itself. Firefox, WebKit and Electron stay on the older path. Mentioning this shows you read release notes.

How do you avoid logging in through the UI before every test?#

cy.session() caches cookies, localStorage and sessionStorage under an ID and restores them on later calls:

Cypress.Commands.add('login', (email: string) => {
  cy.session(email, () => {
    cy.env(['password']).then(({ password }) => {
      cy.request('POST', '/api/login', { email, password });
    });
  }, {
    validate() {
      cy.request('/api/me').its('status').should('eq', 200);
    },
  });
});

The validate callback makes Cypress rebuild the session if it has expired.

Cypress 16 removed Cypress.env(). What replaces it?#

Two APIs, split by sensitivity. Cypress.expose() returns public, non-secret values synchronously (feature flags, API versions). cy.env(['key']) is asynchronous and only hands the test the secrets it explicitly asks for, so they are not serialised into browser state. Cypress 16 also removed cy.exec() (use cy.task()), requires Node.js 22, 24 or 26 and later, and deprecates Electron as a test browser.

  • Why interviewers ask: it checks whether you have upgraded a real suite recently, and whether you think about secrets leaking into the browser.

How do you handle iframes and new tabs?#

There is no built-in iframe command. Reach into the frame's document and wrap its body:

cy.get('iframe#payment')
  .its('0.contentDocument.body')
  .should('not.be.empty')
  .then(cy.wrap)
  .find('input[name=card]')
  .type('4242424242424242');

For links that open a new tab, assert on the href or remove the target attribute and click, because Cypress cannot follow a second tab.

Senior level#

How do you run a large Cypress suite in parallel?#

Cypress parallelises by spec file, across machines, not inside one process. The official route is Cypress Cloud (cypress run --record --parallel on several CI machines, with the Cloud handing out specs by historic duration). Without Cloud, teams split specs across CI jobs themselves. Either way, many small spec files balance better than a few large ones.

How do you deal with flaky Cypress tests?#

  • Configure test retries (retries: { runMode: 2, openMode: 0 }) so flakiness is visible but does not block merges.

  • Replace every cy.wait(<number>) with an intercepted alias or an assertion.

  • Keep test isolation enabled (testIsolation, the default), so each test starts from a blank page and cleared storage.

  • Seed data through cy.request() or cy.task() rather than through earlier tests.

  • Use the screenshots and videos from cypress run, plus the command log in the runner; the article on debugging Cypress tests has a step-by-step walkthrough.

  • Red flag: Tests that depend on running in a specific order.

When would you pick Cypress over Playwright, or the other way around?#

Cypress: a front-end team that wants component testing and an interactive runner, single-origin apps, JavaScript only. Playwright: multi-tab or multi-user flows, several origins, more languages, built-in sharding. Interviewers want reasons tied to the product, not fandom.