Cypress - Working with XHR
Cypress - Working with Network Requests (XHR/Fetch)
Section titled “Cypress - Working with Network Requests (XHR/Fetch)”Modern web applications heavily rely on network requests (like XHR - XMLHttpRequest, or Fetch API calls) to communicate with servers, fetching data or submitting information without a full page reload. These requests are crucial for dynamic content and user interactions.
Cypress provides powerful tools to manage and test these network requests. You can spy on requests, assert their properties, and even stub or mock responses. This allows you to create faster, more reliable tests by controlling external dependencies. You can observe raw network activity in your browser’s Developer Tools (usually under the ‘Network’ tab).
When inspecting a network request in browser developer tools, you’ll typically see details like the request URL, method (GET, POST, etc.), status code (e.g., 200 OK, 404 Not Found), request/response headers (like Content-Type, Authorization), and the response body (e.g., JSON data).
Cypress offers two primary commands for network interactions: cy.intercept() for managing network requests made by your application during tests, and cy.request() for making HTTP requests directly from your test code (e.g., for API testing or test setup).
Managing Application Network Requests with cy.intercept()
Section titled “Managing Application Network Requests with cy.intercept()”cy.intercept() is the modern, versatile command for intercepting and managing HTTP requests and responses made by your application. You can use it to:
- Wait for specific requests to complete before proceeding.
- Assert on request and response data (headers, body, status code).
- Stub responses to test various scenarios (e.g., empty data, error states) without a live backend.
Spying on Requests and Asserting
Section titled “Spying on Requests and Asserting”You can intercept a request, alias it, wait for it, and then make assertions:
describe('Network Interception Test', () => { it('should fetch user data and verify response', () => { // Intercept GET requests to '/api/users' cy.intercept('GET', '/api/users').as('getUsers');
cy.visit('/dashboard'); // Action that triggers the API call
// Wait for the aliased request and assert its response cy.wait('@getUsers').then((interception) => { expect(interception.response.statusCode).to.eq(200); expect(interception.response.body).to.be.an('array').and.not.be.empty; // Further assertions on response body or headers }); });});Stubbing Responses
Section titled “Stubbing Responses”Stubbing allows you to define a mock response for a request, making tests deterministic and independent of backend state:
describe('Network Stubbing Test', () => { it('should display message when no data is returned', () => { // Stub GET requests to '/api/items' to return an empty array cy.intercept('GET', '/api/items', { statusCode: 200, body: [] }).as('getItems');
cy.visit('/items-list');
cy.wait('@getItems'); cy.contains('No items found.').should('be.visible'); });
it('should load data from a fixture', () => { // Stub response using a fixture file (e.g., cypress/fixtures/products.json) cy.intercept('GET', '/api/products', { fixture: 'products.json' }).as('getProducts');
cy.visit('/products'); cy.wait('@getProducts'); // Assert that the UI reflects data from products.json cy.get('.product-item').should('have.length.greaterThan', 0); });});For comprehensive examples and advanced cy.intercept() usage (like modifying responses dynamically), refer to the official Cypress documentation on Network Requests.
Making HTTP Requests Directly with cy.request()
Section titled “Making HTTP Requests Directly with cy.request()”cy.request() is used when your test script needs to make an HTTP request directly to a server, outside of your application’s UI interactions. This is common for:
- Seeding data or cleaning up state before/after a test.
- Testing your API endpoints directly.
- Fetching external data needed for your test logic.
Here’s an example of using cy.request() to fetch data and assert its properties:
describe('Direct API Request Test', () => { it('should fetch comments from a public API', () => { cy.request('GET', 'https://jsonplaceholder.cypress.io/comments').as('commentsReq');
cy.get('@commentsReq').should((response) => { expect(response.status).to.eq(200); expect(response.body).to.be.an('array').and.to.have.length.of.at.least(100); expect(response).to.have.property('headers'); expect(response.headers).to.have.property('content-type').and.include('application/json'); }); });});cy.request() automatically handles cookies and can be configured with various options for method, URL, body, headers, and authentication. It’s a powerful tool for interacting with APIs as part of your testing strategy.