Mastering Network Interception in Cypress: A Detailed Guide

Published: (December 24, 2025 at 11:30 PM EST)
8 min read
Source: Dev.to

Source: Dev.to

Introduction

In today’s highly competitive landscape of software testing, efficient handling of network requests is the key to ensuring seamless functionality of web applications. The modern end‑to‑end testing framework Cypress provides strong features for intercepting and testing network requests, making it a game‑changer for test automation.

This blog delves into the world of network interception with Cypress. From the basics of API request handling to advanced stubbing techniques and validation of responses, the guide covers everything you need to know. It illustrates how Cypress equips testers with the ability to simulate edge cases, debug complex interactions, and obtain higher test coverage. By the end of this post, you’ll have a comprehensive understanding of how to incorporate network interception into your Cypress test‑automation strategy, enhancing both test reliability and efficiency.

The blog is tailored for testers and developers looking to elevate their automation skills, offering step‑by‑step instructions, practical examples, and insights into best practices for network testing.


What is Network Request Interception?

Network request interception in the context of automation testing refers to the process of monitoring, modifying, or completely stubbing HTTP requests and responses between the client and server during a test session. This functionality is pivotal for testing scenarios that depend on APIs or web services, ensuring that the application handles all possible conditions—such as successful responses, server errors, and delayed responses.

For instance

  • Intercepting an API call for fetching user data and simulating a response with dummy data can validate how the application handles different scenarios without reliance on backend availability.
  • Testing an edge case where the server sends a 500 error allows validation of fallback mechanisms or error messages in the UI.

Network interception illustration


Why is Network Interception Crucial in Automation Testing?

  • Isolate Application Behaviour – Test frontend logic without relying on live backend servers, which might be unstable or unavailable.
  • Simulate Edge Cases – Easily simulate scenarios like slow network responses, server errors, or unexpected payloads.
  • Improve Test Reliability – Reduce flakiness by controlling external dependencies, making tests more stable and repeatable.
  • Validate API Contracts – Ensure the application sends the correct requests and processes responses as expected.
  • Debugging Made Easy – Intercept requests and responses to gain visibility into what the application is communicating with the server.

Benefits of Using Cypress for API Interception

Cypress simplifies network interception with its powerful cy.intercept command, offering several advantages over traditional testing tools.

Ease of Use

Cypress provides a declarative and readable syntax for intercepting and modifying network requests.

Cypress intercept example

Example – Intercept any GET request to /api/users and serve a predefined JSON response from the users.json fixture file.

// cypress/e2e/intercept-users.spec.js
cy.intercept('GET', '/api/users', { fixture: 'users.json' }).as('getUsers');
cy.visit('/users');
cy.wait('@getUsers').its('response.statusCode').should('eq', 200);

Real‑Time Debugging

Cypress’s built‑in test runner shows intercepted requests and their details in real time, allowing for quick validation and troubleshooting.

No Middleware Required

Unlike some tools that need a proxy server or additional middleware, Cypress integrates natively, saving setup time.

Simulating Complex Scenarios

With cy.intercept, you can mock API responses dynamically to test complex workflows like pagination or authentication.

Example – Simulating Pagination

Pagination mock example

// Mock first page
cy.intercept('GET', '/api/items?page=1', { fixture: 'items-page-1.json' }).as('page1');
// Mock second page
cy.intercept('GET', '/api/items?page=2', { fixture: 'items-page-2.json' }).as('page2');

Comprehensive Assertions

Cypress allows assertions on requests, payloads, headers, and responses.

Example – Validating Request Payload

Payload validation example

cy.intercept('POST', '/api/login', (req) => {
  expect(req.body).to.have.property('username', 'testuser');
  expect(req.body).to.have.property('password');
  req.reply({ fixture: 'login-success.json' });
}).as('login');

Simplified Test Maintenance

Features like fixtures and aliases let you organize test data and intercepts for reuse across multiple tests, keeping your suite DRY and easy to maintain.

By using network request interception with Cypress, you gain full control over your application’s external dependencies, enabling robust and comprehensive automation tests that validate both UI and API layers. It’s an essential skill for modern test‑automation practitioners.


The Basics of cy.intercept in Cypress

Introduction to cy.intercept

cy.intercept is a Cypress command that allows you to intercept and modify HTTP requests and responses. It supersedes the older cy.route API and provides a more powerful, flexible interface.

Syntax Overview

cy.intercept([method], url, [routeHandler])
ParameterTypeDescription
methodString (optional)HTTP method to match (GET, POST, PUT, DELETE, …). If omitted, any method matches.
urlString, RegExp, or ObjectURL pattern to match. Supports glob patterns (**/api/**) or regular expressions.
routeHandlerObject or Function (optional)Defines how to respond or modify the request. Can be a static stub, a fixture, or a function that receives the request object.

Simple Example – Stubbing a GET Request

// Stub a GET request to /api/todos and return a fixture
cy.intercept('GET', '/api/todos', { fixture: 'todos.json' }).as('getTodos');

Dynamic Response Example

cy.intercept('POST', '/api/login', (req) => {
  // Inspect the request payload
  expect(req.body).to.have.property('username');

  // Dynamically decide the response
  if (req.body.username === 'admin') {
    req.reply({ statusCode: 200, body: { token: 'abc123' } });
  } else {
    req.reply({ statusCode: 401, body: { error: 'Invalid credentials' } });
  }
}).as('login');

Using Aliases for Waiting

cy.wait('@login').its('response.statusCode').should('eq', 200);

Matching with Wildcards

// Match any GET request under /api/users/*
cy.intercept('GET', '/api/users/**', { fixture: 'user.json' });

Modifying Outgoing Requests

cy.intercept('GET', '/api/products', (req) => {
  // Add a custom header before the request is sent
  req.headers['x-test-header'] = 'cypress';
  req.continue(); // Continue with the (now modified) request
});

Key Tips

  1. Place intercepts before the action that triggers the request.
  2. Use as() to create an alias – this makes it easy to cy.wait() and assert on the request/response.
  3. Leverage fixtures for reusable static data.
  4. Combine with cy.wait() to avoid flaky tests caused by race conditions.

Putting It All Together – A Sample Test

describe('User Dashboard – Network Interception', () => {
  beforeEach(() => {
    // Stub the user list API
    cy.intercept('GET', '/api/users', { fixture: 'users.json' }).as('getUsers');

    // Stub a delayed response to test loading state
    cy.intercept('GET', '/api/notifications', (req) => {
      req.reply((res) => {
        // Simulate a 2‑second network delay
        setTimeout(() => {
          res.send({ fixture: 'notifications.json' });
        }, 2000);
      });
    }).as('getNotifications');

    cy.visit('/dashboard');
  });

  it('displays the user list from fixture', () => {
    cy.wait('@getUsers');
    cy.get('[data-cy=user-row]').should('have.length', 5); // assuming 5 users in fixture
  });

  it('shows loading spinner while notifications are delayed', () => {
    cy.get('[data-cy=notifications-spinner]').should('be.visible');
    cy.wait('@getNotifications');
    cy.get('[data-cy=notifications-spinner]').should('not.exist');
    cy.get('[data-cy=notification]').should('have.length.at.least', 1);
  });
});

Final Thoughts

Network request interception with Cypress gives you full control over the external interactions of your application, enabling you to:

  • Write deterministic, fast, and reliable tests.
  • Simulate hard‑to‑reproduce edge cases.
  • Validate both UI behavior and API contracts in a single test flow.

Mastering cy.intercept is a cornerstone skill for any modern test‑automation engineer. Happy testing!

Introduction

Cypress 6.0 introduced the cy.intercept command, offering enhanced functionality and better control over network traffic during tests.

This powerful feature can:

  • Monitor outgoing and incoming HTTP requests.
  • Stub and mock responses.
  • Validate payloads, headers, and response structures.
  • Simulate edge cases such as timeouts, server errors, or invalid data.

Key Differences Between cy.route and cy.intercept

cy.route vs cy.intercept comparison

cy.intercept provides unmatched flexibility by allowing detailed request matching, response manipulation, and advanced validations.


Syntax Overview – Basic Usage

The cy.intercept command can accept various arguments depending on the complexity of your requirements.

Basic Syntax

Basic syntax diagram


Examples of cy.intercept Usage

1. Intercepting a GET Request – Monitor & Validate

// Intercept GET /api/users and assign an alias
cy.intercept('GET', '/api/users').as('getUsers');

// Trigger the request in your app (e.g., click a button)
cy.get('button.fetch-users').click();

// Wait for the request and assert response
cy.wait('@getUsers').its('response.statusCode').should('eq', 200);
cy.wait('@getUsers')
  .its('response.body')
  .should('have.length.greaterThan', 0);

Explanation

  • Intercepts requests to /api/users.
  • Assigns an alias @getUsers for easier reference.
  • Validates the status code and response body.

2. Stubbing a Response – Use a JSON Fixture

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

Explanation

Any GET request to /api/products will receive data from the products.json fixture.


3. Dynamic Response Modification

cy.intercept('POST', '/api/login', (req) => {
  // Simulate a login failure
  req.reply({
    statusCode: 401,
    body: { error: 'Invalid credentials' },
  });
}).as('loginFail');

Explanation

Intercepts a POST request to /api/login and overrides the response body dynamically to simulate a login failure.


4. Simulating a Server Error (500)

cy.intercept('GET', '/api/orders', {
  statusCode: 500,
  body: { error: 'Internal Server Error' },
}).as('ordersError');

Explanation

Simulates a 500 error, allowing you to verify the application’s error‑handling mechanisms.


5. Validating Request Payload

cy.intercept('POST', '/api/submit', (req) => {
  // Assert payload structure and values
  expect(req.body).to.have.all.keys('name', 'email', 'message');
  expect(req.body.email).to.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
}).as('submitForm');

Explanation

  • Intercepts a POST request to /api/submit.
  • Validates that the payload contains the expected keys and that the email format is correct.

Best Practices

  • Use Aliases – Assign aliases (as('myAlias')) to intercepted requests for easy reference with cy.wait.
  • Organise Fixtures – Store reusable test data in the cypress/fixtures folder for consistent mock responses.
  • Test Edge Cases – Simulate delays, timeouts, and malformed responses to ensure robustness.
  • Debugging – Leverage Cypress’s Test Runner to inspect intercepted requests and responses in real‑time.

Intercepting GET, POST, PUT, and DELETE Requests

Intercepting various HTTP methods is essential for testing different API interactions within your web application. Cypress makes this straightforward with cy.intercept.

Example: Intercepting a GET Request

Scenario: Test how the application fetches a list of users.

cy.intercept('GET', '/api/users', { fixture: 'users.json' }).as('getUsers');
cy.visit('/users');
cy.wait('@getUsers').its('response.statusCode').should('eq', 200);

Example: Intercepting a POST Request

cy.intercept('POST', '/api/users', (req) => {
  // Validate request payload
  expect(req.body).to.have.property('name');
  // Stub response
  req.reply({ statusCode: 201, body: { id: 123, ...req.body } });
}).as('createUser');

Example: Intercepting a PUT Request

cy.intercept('PUT', '/api/users/*', (req) => {
  // Dynamically modify response
  req.reply({ statusCode: 200, body: { ...req.body, updatedAt: new Date().toISOString() } });
}).as('updateUser');

Example: Intercepting a DELETE Request

cy.intercept('DELETE', '/api/users/*', {
  statusCode: 204,
}).as('deleteUser');

Further Reading

Read the full blog:
https://tinyurl.com/34wb5k66

Back to Blog

Related posts

Read more »

Managing multiple Playwright projects?

Cleaned Markdown markdown !Forem Logohttps://media2.dev.to/dynamic/image/width=65,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s...

Testing in Umami codebase - Part 1.2

Inspired by BulletProof Reacthttps://github.com/alan2207/bulletproof-react/tree/master, I applied its codebase architecture concepts to the Umami codebasehttps:...