Skip to content
SDETRole
SDETRole

Cypress interview question

How do you use cy.intercept to wait on, spy on and stub network requests?

intermediate 2–5 yrs #cy-intercept#network#stubbing#fixtures

Short answer

Register cy.intercept before the action that triggers the request, alias it, then cy.wait('@alias') to synchronise and assert on the request and response. Pass a response or fixture to stub it, or use a handler with req.reply / req.continue to modify traffic. Keep some tests unstubbed end to end.

Answer

cy.intercept() lets Cypress observe and control HTTP traffic between the app and the server. It covers three jobs: waiting, spying and stubbing.

1. Waiting on real requests

Register the intercept before the action that fires the request, give it an alias and wait on it. This replaces arbitrary cy.wait(3000) calls.

it('searches products', () => {
  cy.intercept('GET', '/api/products*').as('search');
  cy.visit('/products');
  cy.get('[data-cy=search]').type('lamp{enter}');

  cy.wait('@search').then(({ request, response }) => {
    expect(request.url).to.include('q=lamp');
    expect(response.statusCode).to.eq(200);
  });
  cy.get('[data-cy=product-card]').should('have.length.greaterThan', 0);
});

If you intercept after clicking, a fast request may already have completed and cy.wait('@search') will time out.

2. Spying

The same aliased intercept doubles as a spy: assert the request body sent by the front end, headers, or that a call happened a specific number of times with cy.get('@search.all').should('have.length', 1).

3. Stubbing responses

// Static response from a fixture file (cypress/fixtures/products-empty.json)
cy.intercept('GET', '/api/products*', { fixture: 'products-empty.json' }).as('search');

// Inline response, useful for error states
cy.intercept('POST', '/api/checkout', {
  statusCode: 503,
  body: { error: 'Service unavailable' },
}).as('checkout');
cy.get('[data-cy=pay]').click();
cy.wait('@checkout');
cy.contains('[role=alert]', 'try again').should('be.visible');

Dynamic handlers

A function handler gives full control: modify the outgoing request, pass it through and modify the response, or reply conditionally.

cy.intercept('GET', '/api/profile', (req) => {
  req.headers['x-feature-flag'] = 'new-profile';
  req.continue((res) => {
    res.body.plan = 'premium';    // force a state that is hard to set up for real
  });
});

cy.intercept('GET', '/api/slow-report', (req) => {
  req.reply({ delay: 2000, fixture: 'report.json' }); // test loading spinners
});

cy.intercept('GET', '/api/feed', { forceNetworkError: true }); // offline behaviour

Matching details

  • URL matching accepts glob patterns, regular expressions or a RouteMatcher object ({ method, pathname, query }).
  • When several intercepts match, the most recently defined one is applied first, so a test-level stub can override a beforeEach default.
  • Intercepts are cleared between tests automatically.

When not to stub

Stubbing makes UI tests fast and deterministic and lets you reach states like 500 errors or empty lists. The risk is drift: your fixtures say the API returns items, the real API now returns results, and every stubbed test still passes. I keep a small set of unstubbed end-to-end journeys against a real backend, and keep fixtures honest with API contract tests or schema checks.

What interviewers look for

  • Ordering: intercept first, action second, wait third.
  • Using aliases to synchronise rather than fixed waits.
  • Knowing static stubs vs handlers, and simulating errors, delays and network failures.
  • Awareness that heavy stubbing needs a strategy against drift.

A strong answer covers

  • Define the intercept before the triggering action
  • Alias and cy.wait('@alias') instead of fixed waits
  • Stub with fixtures or static responses (statusCode, body)
  • Use handlers (req.reply, req.continue) to modify or simulate errors/delays
  • Balance: stubbed tests plus some real end-to-end
Practise answering under time pressure

Type to search across SDETRole.

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