DEV Community

Cover image for Simulating Internet Outage and Recovery using Cypress
Walmyr
Walmyr

Posted on

Simulating Internet Outage and Recovery using Cypress

Unveiling Cypress's Power: Testing Internet Outages and Recoveries with Precision

Testing an application under various scenarios is crucial to ensure its robustness and user-friendliness.

One common yet challenging scenario is simulating internet outages and recoveries.

In this blog post, we'll explore a Cypress test that replicates this scenario, utilizing the powerful intercept command to manipulate network requests and responses.

This blog post was originated by the following test, from the Cypress Playground repository.

The Test Scenario

The test aims to simulate the internet going "down" and then recovering.

Let's walk through the code step by step to understand how it achieves this:

// Complete Code

it('simulates the internet going "down" then back "up"', () => {
  // Simulating Network Error
  cy.intercept(
    'GET',
    'https://jsonplaceholder.typicode.com/todos/1',
    { forceNetworkError: true }
  ).as('networkError')

  // Triggering the Request
  cy.contains('button', 'Get TODO').click()

  // Handling the Network Error
  cy.wait('@networkError')
  cy.contains(
    '.error span',
    'Oops, something went wrong. Check your internet connection, refresh the page, and try again.'
  ).should('be.visible')

  // Triggering Recovery
  cy.reload()

  // Simulating Successful Request
  cy.intercept(
    'GET',
    'https://jsonplaceholder.typicode.com/todos/1',
    { middleware: true }
  ).as('getTodo')

  cy.contains('button', 'Get TODO').click()

  cy.wait('@getTodo')
    .its('response.statusCode')
    .should('be.equal', 200)

  // Validating Result
  cy.contains('ul li', 'TODO ID: ').should('be.visible')
  cy.contains('ul li', 'Title: ').should('be.visible')
  cy.contains('ul li', 'Completed: ').should('be.visible')
  cy.contains('ul li', 'User ID: ').should('be.visible')
})
Enter fullscreen mode Exit fullscreen mode

Breaking It Down

Let's break it down, so you can understand each piece of code step-by-step.

1. Simulating Network Error

cy.intercept(
  'GET',
  'https://jsonplaceholder.typicode.com/todos/1',
  { forceNetworkError: true }
).as('networkError')
Enter fullscreen mode Exit fullscreen mode

In this section, we use the cy.intercept command to intercept any GET request to the specified URL (https://jsonplaceholder.typicode.com/todos/1). The interception is configured to force a network error (forceNetworkError: true). The interception is named 'networkError' using the as command, allowing us to wait for it later.

2. Triggering the Request

cy.contains('button', 'Get TODO').click()
Enter fullscreen mode Exit fullscreen mode

This line simulates a user action by clicking a button with the text 'Get TODO.' This triggers the intercepted GET request, and Cypress will capture the interception labeled as 'networkError.'

3. Handling the Network Error

cy.wait('@networkError')
Enter fullscreen mode Exit fullscreen mode

The cy.wait('@networkError') command pauses the test execution until the intercepted request labeled 'networkError' is completed. This ensures that the test waits for the network error response before proceeding.

cy.contains(
  '.error span',
  'Oops, something went wrong. Check your internet connection, refresh the page, and try again.'
).should('be.visible')
Enter fullscreen mode Exit fullscreen mode

After the network error, the test expects to find a visible element with the specified error message. This asserts that the application responds appropriately to a network error, providing a user-friendly message.

4. Triggering Recovery

cy.reload()
Enter fullscreen mode Exit fullscreen mode

This line reloads the page, simulating a user's attempt to recover from the network error.

5. Simulating Successful Request

cy.intercept(
  'GET',
  'https://jsonplaceholder.typicode.com/todos/1',
  { middleware: true }
).as('getTodo')
Enter fullscreen mode Exit fullscreen mode

Here, we intercept the same GET request, but this time, we simulate a successful response ({ middleware: true }). The interception is named 'getTodo'.

For more details about the middleware property, I recommend reading about the interception lifecycle, directly from the Cypress official docs.

cy.contains('button', 'Get TODO').click()
Enter fullscreen mode Exit fullscreen mode

Another user action triggers the successful request interception.

cy.wait('@getTodo')
  .its('response.statusCode')
  .should('be.equal', 200)
Enter fullscreen mode Exit fullscreen mode

The test waits for the 'getTodo' interception and asserts that the response status code is 200, confirming the successful recovery.

6. Validating Result

The subsequent lines validate the presence of specific elements on the page, ensuring that the application displays the expected data after the recovery.

cy.contains('ul li', 'TODO ID: ').should('be.visible')
cy.contains('ul li', 'Title: ').should('be.visible')
cy.contains('ul li', 'Completed: ').should('be.visible')
cy.contains('ul li', 'User ID: ').should('be.visible')
Enter fullscreen mode Exit fullscreen mode

These assertions check for the visibility of elements indicating that the application has successfully fetched and displayed the TODO details.

Conclusion

This Cypress test provides a comprehensive simulation of internet outage and recovery, allowing testers and developers to evaluate how an application responds to network errors.

Realistic scenarios, powered by Cypress commands like intercept, enable effective validation of application behavior under challenging conditions.

Finally, ensuring meaningful feedback and maintaining robustness are critical aspects of delivering a seamless user experience, even in the face of potential network issues.


Did you like the content? Leave a comment.


Would you like to learn Cypress in a hands-on course?

I introduce you to my newest course, 🌲 Cypress, from Zero to the Cloud ☁️.

I hope you like it, and happy testing!

Top comments (0)