Skip to content
SDETRole
SDETRole

Cypress interview question

How do you diagnose and fix flaky Cypress tests?

advanced 5+ yrs #flaky-tests#retry-ability#debugging#ci

Short answer

Reproduce and classify the failure, then fix the cause: understand which commands retry (queries and assertions) and which don't (actions, .then), avoid detached-DOM errors by re-querying after re-renders, synchronise on network aliases not cy.wait(ms), isolate data, and use test retries only as a signal, not a cure.

Answer

Flakiness is a symptom; my job is to find which category it belongs to and fix the cause. My process:

1. Reproduce and gather evidence

  • Run the spec repeatedly in headless CI-like conditions (cypress run --spec ... --browser chrome), in a loop or with a burn-in job.
  • Collect screenshots, videos and the command log. Cypress Cloud’s flake detection, or my own reports, show which tests pass on retry.
  • Check whether it fails only in CI (resources, timing, data) or also locally.

2. Classify the failure

Timing and retry-ability misunderstandings

Cypress retries queries (cy.get, .find, .contains) together with the assertions that follow them. It does not retry actions (.click, .type) or .then() callbacks. A common flaky pattern:

// Flaky: .then() runs once, possibly before the list has updated
cy.get('[data-cy=row]').then(($rows) => {
  expect($rows).to.have.length(5);
});

// Stable: the query and assertion retry together until timeout
cy.get('[data-cy=row]').should('have.length', 5);

Detached DOM

“Element is detached from the DOM” means Cypress held a reference to an element that the framework then re-rendered. Since Cypress 12, queries re-run automatically through the chain, but actions end that protection. Chaining further off an action is the usual culprit:

// Risky: the element yielded by .type() may be replaced on re-render
cy.get('[data-cy=search]').type('lamp').parent().find('button').click();

// Better: split after actions and re-query
cy.get('[data-cy=search]').type('lamp');
cy.get('[data-cy=search-submit]').click();

Also assert on the state that indicates rendering is complete (a spinner gone, a count updated) before acting.

Network races

Tests that act before data arrives, or assert before the save completes. The fix is to intercept and wait on the alias, not cy.wait(2000):

cy.intercept('PUT', '/api/profile').as('save');
cy.get('[data-cy=save]').click();
cy.wait('@save').its('response.statusCode').should('eq', 200);
cy.contains('Saved').should('be.visible');

Data and order dependence

Tests sharing a user or relying on records created by another spec. Fix with per-test data created through cy.request or cy.task, unique identifiers, and cy.session for login.

Environment

Animations, third-party scripts, under-resourced CI containers (Chrome crashing with out-of-memory), or time-dependent logic. Stub third parties, use cy.clock() for time, and give CI agents adequate memory and shared memory for browsers.

3. Use retries carefully

// cypress.config.js
const { defineConfig } = require('cypress');

module.exports = defineConfig({
  retries: { runMode: 2, openMode: 0 },
  e2e: { baseUrl: 'http://localhost:3000' },
});

Retries reduce noise in CI, but a test that only passes on retry is still flaky, and might be flagging a real race condition in the product. I track pass-on-retry rates, quarantine persistent offenders with an owner and a deadline, and fix the root cause rather than raising timeouts.

What interviewers look for

  • A systematic process: reproduce, classify, fix, verify.
  • Precise understanding of what retries and what doesn’t.
  • Treating retries as a detection mechanism, and considering that the flake could be a product bug.

Common mistakes

  • Increasing defaultCommandTimeout globally.
  • Sprinkling cy.wait(ms) and { force: true } to make failures disappear.

A strong answer covers

  • Retry-ability: queries and assertions retry, actions and .then do not
  • Detached DOM: re-query after re-render, split chains after actions
  • Synchronise on app state/network aliases instead of fixed waits
  • Data isolation and environment causes (shared data, CI resources)
  • Test retries/burn-in as detection, not a fix
Practise answering under time pressure

Type to search across SDETRole.

Full-text search by Pagefind · runs in your browser Open search page →