To test a Cypress app as genuinely offline, use Chrome DevTools Protocol commands to emulate browser-wide network loss, assert both the browser’s offline state and the app’s visible fallback, then restore connectivity in test hooks. For a test where only one HTTP request should fail, use cy.intercept() with forceNetworkError: true instead.
Choose browser-wide offline mode or a failed request
These methods exercise different behavior. Browser-wide emulation is the right choice when the app responds to navigator.onLine, offline/online events, or a general loss of connectivity. An intercept is narrower: it makes a matching application request fail without representing the browser as offline.
| Method | Scope | Useful assertions | Important caveat |
|---|---|---|---|
| Chrome DevTools Protocol offline emulation | Browser network state | navigator.onLine, offline indicator, fallback UI, recovery |
Restore network in cleanup; browser/version behavior may vary. |
cy.intercept() with forceNetworkError: true |
A matching HTTP request | Application error UI and the aliased request’s error property |
Cached browser responses may bypass interception; register the route before the request starts. |
Cypress’s detailed offline recipe uses the Chrome Debugger Protocol. It was published November 12, 2020, so verify it against your project’s pinned Cypress and browser versions rather than assuming all combinations behave identically. The recipe names Electron, Chrome, and Edge as compatible at publication and says Firefox cannot run that example. Cypress 16’s current networking guidance distinguishes native interception in Chrome, Chromium, and Edge from the legacy path used by Firefox, WebKit, and Electron; that distinction does not establish identical support for the older offline-automation recipe. See Cypress’s offline-mode recipe and Cypress’s native network interception guide.
Emulate offline network conditions
The example below visits the app online, enables the protocol’s Network domain, sets offline conditions, checks browser and application behavior, and restores connectivity. Replace the example selectors and messages with those in your application. Cypress’s recipe uses the documented latency and throughput parameters shown here; the values are inputs to the emulation, not measurements of a real network.
Recommended Free Tools
#1 Best Overall
describe('offline behavior', () => {
const setOnline = () => {
return Cypress.automation('remote:debugger:protocol', {
command: 'Network.emulateNetworkConditions',
params: {
offline: false,
latency: 0,
downloadThroughput: -1,
uploadThroughput: -1,
},
});
};
const setOffline = () => {
return Cypress.automation('remote:debugger:protocol', {
command: 'Network.emulateNetworkConditions',
params: {
offline: true,
latency: 0,
downloadThroughput: -1,
uploadThroughput: -1,
},
});
};
beforeEach(() => {
// Clear any state left by a prior test before visiting the app.
setOnline();
cy.visit('/');
});
afterEach(() => {
// Do not leave the browser offline if an assertion fails.
setOnline();
return Cypress.automation('remote:debugger:protocol', {
command: 'Network.disable',
params: {},
});
});
it('shows an offline error and recovers when online', () => {
cy.then(() =>
Cypress.automation('remote:debugger:protocol', {
command: 'Network.enable',
params: {},
})
);
cy.then(() => setOffline());
cy.window().its('navigator.onLine').should('be.false');
cy.contains('Offline').should('be.visible');
cy.get('[data-cy=load-users]').click();
cy.contains('Error trying to fetch users').should('be.visible');
cy.then(() => setOnline());
cy.window().its('navigator.onLine').should('be.true');
cy.get('[data-cy=load-users]').click();
cy.get('[data-cy=user-list]').should('be.visible');
});
});
The protocol calls return Promises. Chain them from Cypress commands such as cy.then() so the test waits for the browser state change before checking the page. The sample follows the flow in Cypress’s recipe; adapt app-specific text and selectors, and verify the behavior in your supported browser matrix.
Why the cleanup belongs in hooks
An offline browser may be unable to communicate test status to Cypress. Returning online only at the end of the test body is not enough: an earlier failed assertion can skip that code. Restore online state before each test and in teardown so an interrupted test is less likely to contaminate the next one. The Cypress recipe also disables the Network domain after restoring access.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Fail one application request with cy.intercept()
For a targeted fetch failure, register the intercept before the app sends its request, force a network error, and assert both the user-facing response and the intercepted error:
it('shows an error when the users request fails', () => {
cy.intercept('GET', '/api/users', { forceNetworkError: true }).as('users');
cy.visit('/');
cy.get('[data-cy=load-users]').click();
cy.wait('@users').should('have.property', 'error');
cy.contains('Error trying to fetch users').should('be.visible');
});
Use the real request method and URL pattern from your app. If initialization sends the request immediately, register the route before cy.visit(), as shown. Cypress documents that a browser-cached resource may not reach the network layer and therefore may not trigger an intercept. Also, cy.request() runs from Cypress’s Node process, not the browser; it does not stand in for observing an app-originated browser request. See the cy.intercept() API and network requests guide.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Rank #3
Build reliable offline tests
- Assert behavior, not just transport details. Check the rendered offline message, fallback content, or recovery state as well as
navigator.onLinewhen browser status is part of the feature. - Restore connectivity on every path. Keep setup and teardown cleanup so a failure does not leave the browser offline for a later test.
- Separate whole-browser and single-request cases. Use protocol emulation for status and event behavior; use an intercept for a deliberately failed endpoint.
- Account for timing and cache. Install intercepts before navigation or app initialization when requests can start immediately, and avoid relying on interception of a response served from browser cache.
- Check supported browsers in your CI matrix. The detailed recipe is older than Cypress 16 networking documentation. Validate the protocol command on the Cypress and browser versions you actually pin; gate the test where necessary.
- Assert the user outcome. Cypress 16’s guide recommends testing application behavior, such as rendered errors or response bodies, rather than depending on transport metadata that can vary between networking paths.
Troubleshooting
The test continues to show online
Make sure Network.enable has completed before calling Network.emulateNetworkConditions, and chain both calls through Cypress commands so Promises are awaited. Confirm that the test is running in a browser/version compatible with the protocol recipe.
The next test cannot communicate with Cypress
The previous test may have left the browser offline. Restore network conditions in teardown and before the next visit; do not rely solely on cleanup after the final assertion in the test body.
Rank #4
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
The intercept never matches
Check the method and URL matcher against the actual request. Register the intercept before navigation if app startup makes the request, and consider whether the browser is serving a cached resource that never reaches the intercept layer.
The request fails but the app’s offline indicator does not appear
A forced error for one request is not browser-wide offline emulation. If the UI depends on navigator.onLine or online/offline events, test it with protocol emulation. If it depends on an API failure, assert the request-error fallback instead.
Free tools Windows power users keep installed
One-click scans. No signup required.
Best Value
cy.request() does not reflect the browser’s offline state
cy.request() executes from Cypress’s Node process. Trigger the application action in the browser and observe its request with cy.intercept(), or use browser-wide emulation for offline-state behavior.
Or skip the browser setup
If your goal is to capture what a page looks like rather than test its offline behavior, ScreenshotNeo is a website screenshot API and MCP server. It is not a replacement for Cypress network-state testing. A one-request screenshot call looks like this; see the ScreenshotNeo API documentation for options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts cookie or consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free 1,000 screenshots a month, with no card required.
Frequently Asked Questions
Does Cypress have a built-in offline test recipe?
Yes. Cypress lists an Offline recipe that uses Chrome DevTools Protocol network emulation; its detailed example is dated November 12, 2020.
Can cy.intercept() make the whole browser appear offline?
No. It can force a matching request to fail, but browser-wide offline status and online/offline event behavior require network emulation.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

