sodcalculator

10 Tech How-To

Offline Network Testing in Cypress: Step-by-Step Guide

Guide 10-32005 · Updated · Step by step

Testing how your web app behaves when the network is unavailable is critical for progressive web apps, offline-first features, and any application that should gracefully handle connectivity loss. Cypress makes this easy by letting you intercept and block network requests. This guide shows you how to simulate offline mode, verify your app’s fallback UI, and ensure your app degrades gracefully—all within your Cypress test suite.

What You’ll Need

  • A working Cypress setup (Cypress installed and configured) with a test file ready.
  • An application that has some network-dependent feature (e.g., fetching data from an API, loading images, or syncing).
  • Basic familiarity with Cypress commands and test structure.

Step-by-Step

  1. Create a new test file (or add a test to an existing one) specifically for offline scenarios, e.g., offline.spec.js.
  2. Set up the test to visit your app before simulating offline mode. Use cy.visit('/') to load the page while the network is still available. This ensures the initial app shell (HTML, CSS, JS) is loaded and cached by the browser.
  3. Intercept all network requests using cy.intercept('*', ...) to catch any request that the app makes. This includes XHR, fetch, and even static resource requests if you want to be strict.
  4. Force the requests to fail by providing a response that simulates a network error. Use cy.intercept('*', { forceNetworkError: true }). This tells Cypress to abort the request as if the network is down. Place this after the initial visit and before triggering the action that would normally make a network call.
  5. Trigger the network-dependent action in your app. For example, click a button that loads data, navigate to a route that fetches data, or try to refresh the page.
  6. Assert that the app handles the offline state correctly. Check for the presence of an offline message, a fallback UI, or that the app doesn’t crash. Use cy.contains('You are offline') or cy.get('.offline-indicator').
  7. Test the recovery (optional but recommended). After verifying offline behavior, you can restore the network by removing the interception or using cy.intercept with a normal response, then trigger a retry action and verify that data loads successfully.
  8. Run the test with npx cypress run or via the Cypress Test Runner to see the results.

Common Mistakes

  • Intercepting after the request is already made: Place cy.intercept before the action that triggers the network request, otherwise the request may go through.
  • Using cy.server() and cy.route() (deprecated): These older APIs don’t support forceNetworkError. Always use cy.intercept().
  • Not visiting the page first: If you intercept before the initial page load, the app might not load at all, and you won’t be testing the app’s offline handling but rather the page failing to load.
  • Assuming all requests are blocked: cy.intercept('*') catches most requests, but some (like WebSockets or service worker requests) might not be intercepted. Test thoroughly.
  • Forgetting to restore the network: If you don’t remove the interception, subsequent tests in the same file will also fail. Use cy.intercept with a real response or use cy.clearAllIntercepts() in a beforeEach or afterEach hook.

Tips

  • Use a custom command to encapsulate the offline simulation, e.g., Cypress.Commands.add('simulateOffline', () => cy.intercept('*', { forceNetworkError: true })).
  • Test different types of failures: You can also simulate a server error (500) or a timeout by returning { statusCode: 500 } or using delay: 1000 to simulate a slow network.
  • Combine with service worker testing: If your app uses a service worker, you can test that cached assets are served offline by using cy.intercept to serve cached responses.
  • Keep tests isolated: Use beforeEach to clear intercepts and ensure a clean state for each test.
  • Use cy.clock() to test timeout behavior if your app has a timeout for network requests.

Troubleshooting

  • Test still passes even when offline simulation is active: Verify that the interception is actually matching the request. Add a console.log inside the interception handler or use cy.intercept with a specific URL to confirm. Also, ensure the request is made after the interception is set up.
  • App shows a generic error instead of offline message: Your app might not have a specific offline handler. Check your app’s code to see how it handles network errors and adjust your assertion accordingly.
  • Cypress itself fails to load the page: If you intercept before cy.visit(), the page may not load. Make sure to visit first, then intercept.
  • Interception is not working for some requests: Some requests, like WebSockets, are not intercepted by cy.intercept. For WebSockets, you may need to use a different approach, such as mocking the WebSocket server.
  • Tests are flaky due to timing: Use cy.wait() or cy.intercept with a delay to control timing, but avoid arbitrary waits. Instead, use assertions that wait for the expected UI element to appear.

Frequently Asked Questions

Can I simulate offline mode without intercepting all requests?

Yes, you can intercept specific requests (e.g., cy.intercept('/api/**', { forceNetworkError: true })) to simulate failure for only certain endpoints.

How do I test the app’s behavior when the network is restored?

After simulating offline, you can remove the interception by using cy.intercept again with a normal response, or use cy.clearAllIntercepts() to restore normal network behavior.

Does Cypress support testing service workers offline?

Yes, but you need to handle service worker registration carefully. You can use cy.intercept to serve cached assets, or use a library like cypress-service-worker to control the service worker.

Can I simulate a slow network instead of a complete offline state?

Yes, use cy.intercept(url, (req) => { req.reply((res) => { res.delay = 1000; res.send(); }); }) to add a delay to responses.

Why does my test fail when I use forceNetworkError?

Make sure you are using Cypress version 6.0 or later, as forceNetworkError was introduced in that version. Also, ensure the interception is set up before the request is made.

Is it possible to test offline mode in a real browser?

Cypress runs in a real browser, so the interception simulates network failure at the browser level. However, it does not actually disable the network adapter; it only blocks requests at the Cypress proxy level.

Related

General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.

More in this bed

The whole Tech How-To bed →