cy.intercept() lets you observe, modify, or mock any network request the browser makes. This is one of Cypress's most powerful features — you can test loading states, error handling, and edge cases without needing a real backend.
Watching a Request
cy.intercept('GET', '/api/users').as('getUsers')
cy.visit('/users')
cy.wait('@getUsers') // pauses test until request completes
cy.get('table tbody tr').should('have.length.greaterThan', 0)cy.wait('@alias') gives you the actual request and response objects for assertions.
Stubbing a Response
cy.intercept('GET', '/api/products', {
statusCode: 200,
body: [
{ id: 1, name: 'Widget', price: 9.99 },
{ id: 2, name: 'Gadget', price: 24.99 },
],
}).as('getProducts')
cy.visit('/products')
cy.wait('@getProducts')
cy.get('[data-cy="product-name"]').should('have.length', 2)The real API never gets called — Cypress returns your fixture immediately.
Testing Error States
cy.intercept('POST', '/api/login', {
statusCode: 401,
body: { error: 'Invalid credentials' },
}).as('failedLogin')
cy.get('#email').type('user@test.com')
cy.get('#password').type('wrongpass')
cy.get('[data-cy="submit"]').click()
cy.wait('@failedLogin')
cy.get('.error-msg').should('contain', 'Invalid credentials')Without stubbing, reproducing error states requires a real failing API.
Network Intercept Visualiser
Request intercept simulation
Ctrl+Enter
HTML
CSS
JS
Preview
Dynamic Route Matching
// Match any product ID
cy.intercept('GET', '/api/products/*', (req) => {
req.reply({
statusCode: 200,
body: { id: req.url.split('/').pop(), name: 'Mocked Product' },
})
})
// Modify real response
cy.intercept('GET', '/api/user', (req) => {
req.continue((res) => {
res.body.role = 'admin' // inject a field into the real response
})
})Using Fixtures
// cypress/fixtures/products.json
[
{ "id": 1, "name": "Widget" },
{ "id": 2, "name": "Gadget" }
]cy.intercept('GET', '/api/products', { fixture: 'products.json' }).as('getProducts')Fixtures keep test data out of test files and make it easy to share across tests.