Open In App

How to Wait for all Requests to Finish in Cypress?

Last Updated : 24 Oct, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Cypress is a powerful testing tool designed for end-to-end testing of web applications. It enables developers and testers to write tests that simulate user interactions, ensuring that applications work as expected across different browsers and environments. With its syntax and built-in tools, Cypress streamlines the process of testing web apps, reducing the need for complex setups.

Example: Waiting for All Network Requests to Finish Using cy.intercept() and cy.wait()

In this example, we'll walk through how to wait for all network requests to finish using Cypress's cy.intercept() and cy.wait() commands. This ensures that the page or certain elements are fully loaded before proceeding with assertions or further actions in your test.

Step-by-Step Guide:

1. Intercepting Network Requests: Cypress allows you to intercept network requests by specifying the URL pattern or method using cy.intercept(). This feature enables you to monitor, mock, or control the requests your application sends during tests.

2. Assigning Aliases: Once you've intercepted a request, it's useful to assign it an alias using .as('aliasName'). This alias helps you refer to the request later in the test when you want to wait for it to complete.

3. Waiting for Multiple Requests: Sometimes, you need to wait for multiple network requests to finish before proceeding with assertions or interacting with the page. Cypress makes it easy to wait for multiple requests by using cy.wait() with multiple aliases or an array of aliases.

Example Code Snippet:

networkRequests.cy.js

JavaScript
describe('Wait for All Network Requests Example', () => {
    it('should wait for mocked API requests to complete before proceeding', () => {
      // Mocking the GET request for /api/users
      cy.intercept('GET', '/api/users', {
        statusCode: 200,
        body: [{ name: 'John Doe' }, { name: 'Jane Doe' }]
      }).as('getUsers');
  
      // Mocking the POST request for /api/createUser
      cy.intercept('POST', '/api/createUser', {
        statusCode: 201,
        body: { success: true }
      }).as('createUser');
  
      // Mocking the GET request for /api/posts
      cy.intercept('GET', '/api/posts', {
        statusCode: 200,
        body: [{ title: 'Post 1' }, { title: 'Post 2' }]
      }).as('getPosts');
  
      // Visit the dashboard page
      cy.visit('dashboard.html');
  
      // Wait for all network requests to complete
      cy.wait('@getUsers');
      cy.wait('@createUser');
      cy.wait('@getPosts');
  
      // Validate the DOM after the requests have been completed
      cy.get('.user-list').should('be.visible');
      cy.get('.post-list').should('have.length.greaterThan', 0);
    });
  });
  

Explanation of the Code:

  • cy.intercept(): This function is used to intercept network requests. In this example, we're intercepting a GET request to /api/users, a POST request to /api/createUser, and another GET request to /api/posts. Each request is given an alias (e.g., @getUsers, @createUser, and @getPosts).
  • cy.wait(): This command waits for the network requests specified by the alias to complete before proceeding to the next line of code. In this case, cy.wait('@getUsers') ensures the users API call is complete, and so on for the other requests.
  • Waiting for Multiple Requests: You can either chain multiple cy.wait() commands (as shown) or pass an array of aliases to cy.wait() (commented out), which will wait for all the requests simultaneously.
  • Assertions After Requests: After waiting for the network requests to finish, the test proceeds with assertions. This ensures that the content you're testing against (like .user-list and .post-list) is fully loaded and ready for interaction.

dashboard.html

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Dashboard</title>
  <script>
    document.addEventListener('DOMContentLoaded', function() {
      // Fetch users data from an API (mocked in Cypress)
      fetch('/api/users')
        .then(response => response.json())
        .then(data => {
          const userList = document.getElementById('user-list');
          data.forEach(user => {
            const userItem = document.createElement('li');
            userItem.textContent = user.name;
            userList.appendChild(userItem);
          });
          userList.style.display = 'block'; // Ensure visibility
        });

      // Fetch posts data from an API (mocked in Cypress)
      fetch('/api/posts')
        .then(response => response.json())
        .then(data => {
          const postList = document.getElementById('post-list');
          data.forEach(post => {
            const postItem = document.createElement('li');
            postItem.textContent = post.title;
            postList.appendChild(postItem);
          });
          postList.style.display = 'block'; // Ensure visibility
        });

      // Simulate a createUser POST request (mocked in Cypress)
      fetch('/api/createUser', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ name: 'New User' })
      }).then(response => response.json())
        .then(data => {
          console.log('User created:', data);
        });
    });
  </script>
</head>
<body>
  <h1>Dashboard</h1>

  <h2>Users</h2>
  <ul id="user-list" class="user-list" style="display: none;">
    <!-- Users will be populated here -->
  </ul>

  <h2>Posts</h2>
  <ul id="post-list" class="post-list" style="display: none;">
    <!-- Posts will be populated here -->
  </ul>
</body>
</html>


index.html

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Home</title>
</head>
<body>
  <h1>Welcome to the Home Page</h1>
  <p><a href="./dashboard.html">Go to Dashboard</a></p>
</body>
</html>

Output:

cy
Output

Conclusion

Intercepting network requests using cy.intercept() and assigning aliases to them with .as() is a critical technique in Cypress for ensuring that all necessary API calls are complete before proceeding with assertions or user actions in your tests. By using cy.wait() on these aliases, you can ensure that your test only moves forward after the network interactions are fully resolved, preventing errors caused by incomplete data or loading states.


Next Article

Similar Reads