100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Testing

Intercepting Network Requests with cy.intercept()

Learn how cy.intercept() lets Cypress observe, wait on, and control the XHR and fetch traffic your application sends during a test run.

Network & FixturesIntermediate9 min readJul 10, 2026
Analogies

What cy.intercept() Does

cy.intercept() is Cypress's mechanism for spying on and managing HTTP requests that pass through the browser's networking layer, whether they were made with XMLHttpRequest or the fetch API. It sits between your application and the network, letting you observe requests as they happen, assert on their contents, and optionally short-circuit them with a stubbed response instead of letting them hit a real server. This single command replaces the older cy.route() API from Cypress 4 and earlier, and unifies XHR and fetch handling under one consistent interface.

🏏

Cricket analogy: It works like a third umpire reviewing every delivery bowled in a match, quietly recording each ball (request) so that, whether it was a legitimate wicket by Bumrah or a no-ball, the record can be checked or overturned later.

Basic Syntax and Request Matching

The command takes a method and URL matcher, followed by either a static response, a dynamic handler function, or nothing at all if you only want to spy. The URL argument can be an exact string, a glob pattern like '**/api/users/*', or a regular expression, and Cypress matches outgoing requests against these patterns using minimatch semantics for strings. You can also pass a RouteMatcher object to match on method, URL, headers, query parameters, or the request body simultaneously, which is essential when an endpoint is hit multiple times with different payloads in the same test.

🏏

Cricket analogy: Matching a request by method and URL is like a fielding captain setting a trap for a specific batter and shot: only deliveries bowled short and wide on off-stump (GET requests to a specific URL) draw the planned response.

javascript
// Spy on a request without changing its response
cy.intercept('GET', '/api/users').as('getUsers');

// Stub a response with a static fixture
cy.intercept('GET', '/api/products', { fixture: 'products.json' }).as('getProducts');

// Match with a RouteMatcher object and respond dynamically
cy.intercept(
  {
    method: 'POST',
    url: '/api/orders',
    headers: { 'x-client-version': '2.0' }
  },
  (req) => {
    req.reply({
      statusCode: 201,
      body: { orderId: 'ord_123', status: 'created' }
    });
  }
).as('createOrder');

cy.visit('/dashboard');
cy.wait('@getUsers').its('response.statusCode').should('eq', 200);

Aliasing and Modifying Requests

Chaining .as() onto an intercept creates an alias you can reference later with cy.wait('@alias') or cy.get('@alias'), which is how most assertions on network traffic are structured in a Cypress test. Inside the handler function, the req object exposes properties like req.url, req.headers, req.body, and req.query that can be asserted on directly, and you can mutate req.headers or req.body before calling req.continue() to forward a modified version of the original request to the real server rather than stubbing a response outright.

🏏

Cricket analogy: Aliasing a request is like a scorer tagging a specific over as 'the over Bumrah bowled the wicket ball in' so commentators can instantly recall and replay that exact moment later in the broadcast.

req.continue() lets a request proceed to the real network after you've inspected or modified it, which is different from req.reply(), which fully stubs the response and never contacts the server. Use continue() when you want to assert on real backend behavior while still tweaking headers, and reply() when you want complete control and speed by avoiding the network entirely.

cy.intercept() must be set up before the action that triggers the request, typically before cy.visit() or the click that fires the XHR. If you call intercept() after the request has already started, Cypress will not retroactively catch it, and cy.wait('@alias') will time out waiting for a request that already completed unobserved.

  • cy.intercept() unifies interception of both XHR and fetch requests under one API, replacing the legacy cy.route().
  • It accepts a method/URL matcher or a RouteMatcher object that can filter on headers, query, and body.
  • Chaining .as() creates an alias for use with cy.wait('@alias') and cy.get('@alias') later in the test.
  • req.reply() fully stubs a response and skips the network; req.continue() lets the real request proceed after inspection or modification.
  • Intercepts must be registered before the triggering action, since Cypress cannot catch requests retroactively.
  • The req object exposes url, method, headers, query, and body for direct assertions inside the handler.

Practice what you learned

Was this page helpful?

Topics covered

#Testing#CypressStudyNotes#TestingQA#InterceptingNetworkRequestsWithCyIntercept#Intercepting#Network#Requests#Intercept#Networking#StudyNotes#SkillVeris