A Complete Guide To Improve Your End-to-end Tests With Cypress Intercept

Anyone familiar with automated software testing must have Cypress holding up a huge space in his/her knowledge base. This open-source test automation framework is so popular that even the other renowned test automation tools like Preflight in the market find it quite important to keep their tools capable of generating cypress test codes.

However, here our topic of discussion is cypress intercept, a modern cypress method that enables engineers to monitor all network traffic and not just XHR requests. Previously, the cy.server() and cy.route() methods were used to handle XHR requests within the browser for patterns such as mocking responses, smart waiting, and aborting requests.

Cypress intercept was released in November 2020 in Cypress 6.0.0 version. This powerful method makes Cypress equally capable like Puppeteer and Playwright for its ability to manipulate requests within the browser.

In this article, we will explore the power of the cypress intercept method through examples of request interceptions, mocks, and assertions using a DemoQA Bookstore application as a base.

How To Get Started With It?

As every new JavaScript project, initialize it using NPM.

npm init

Once you have a package.json file, you can start to load cypress.

npm install --save-dev cypress

Once Cypress is installed, finish the total installation process by running it with NPM.

npx cypress open

When a cypress directory is created, it means its installation is finished. To verify if it is properly installed, run the following command -

npx cypress --version

Different Functionalities of Cypress Intercept

As we previously mentioned, the cy.intercept() method can complete a wide range of tasks. So, let’s check out the most important ones.

Interception

When a user is using a software, every task is completed through a long way which further consists of multiple steps. While performing those steps, numerous network requests are made.

Now, you can use a great portion of those requests to perform different actions such as setting up a test state or waiting for a response to finish before checking for an element. Engineers often use request interception to perform these tasks.

So, what does a request interception stand for?

Intercepting a network request using Cypress sets up something that is called a spy. It can be utilized to perform tasks like monitoring network traffic based on a URL or through a URL match. Besides that, you can expand spies upon stub responses or even make assertions against request or response body objects.

Now, coming to our example, to fetch all books within the storefront, the DemoQA Bookstore application makes an API call to a books endpoint. So, let’s see how that API call is intercepted to set up a spy.

That request is selected to fetch the necessary information to begin crafting a spy such as the request URL. Here the request URL is https://www.demoqa.com/Bookstore/v1/Books.

An alias should be set for the request for better visibility within the test runner. Aliased requests that also contain the name of the alias are noted especially.

describe('Bookstore Application', () => {
  beforeEach('Login', () => {
    cy.authenticate(user);
  });
 
  specify('As a user, I should be able to add a book to my profile', () => {
    cy.intercept('https://www.demoqa.com/BookStore/v1/Books').as('booksRequest');
   
    cy.visit('https://www.demoqa.com/books');
  });
});

The above code will allow you to run your test to check if the spy properly monitors network traffic to the books endpoint. That spy will also enable you to manipulate the request for test setup and assertions.

Stubbing Responses

A stub is a kind of preset response to a request. You can use stubs to build test state within an end-to-end test by simulating data that may or may not have any direct effect on the test. For our book store example, the books endpoint returns a JSON object of data that has all the books listed within the books table.

Stubbing responses to the request needs you to find answers to some crucial questions such as what will happen if this request takes a long time to load? Or, what will be the next steps if the table shows an error statement until the request has finished?

Writing end-to-end tests makes it super important to curate your testing environment so that the chances of creating flaky tests are reduced. For example, to deal with the problem of a table that returns an error statement until a request has been fulfilled, two highly effective options can be -

  • Waiting for the request to finish.
  • Stubbing the data.

In such a case, if the table data does not have a direct impact on the test, the better option is to stub the data. And, the same can be done with the books endpoint because the table data has nothing to do with the overall user journey. Here the prime goal is that a user becomes able to add a book to their profile. So, as long as there remains at least one table entry, there will be no issue in your user’s journey.

If a stub is a preset response to a request, then the test needs a response object to be built ahead of running the test. To do that, you can copy a good response object and trim it down to a better manageable state. This means you are taking the response to the books endpoint and removing all entries except one.

{
    "books": [
        {
            "isbn": "9781449337711",
            "title": "Designing Evolvable Web APIs with ASP.NET",
            "subTitle": "Harnessing the Power of the Web",
            "author": "Glenn Block et al.",
            "publish_date": "2020-06-04T09:12:43.000Z",
            "publisher": "O'Reilly Media",
            "pages": 238,
            "description": "Design and build Web APIs for a broad range of clients--including browsers and mobile devices--that can adapt to change over time. This practical, hands-on guide takes you through the theory and tools you need to build evolvable HTTP services with Microsoft",
            "website": "http://chimera.labs.oreilly.com/books/1234000001708/index.html"
        }
    ]
}

The table data can be stubbed by providing a fixture to the intercepted request. It will get the response body replaced by whatever data is found within the fixture file.

const book = {
  title: 'Designing Evolvable Web APIs with ASP.NET',
  ISBN: '9781449337711',
};

describe('Bookstore Application', () => {
  beforeEach('Login', () => {
    cy.authenticate(user);
  });
 
  specify('As a user, I should be able to add a book to my profile', () => {
    cy.intercept('https://www.demoqa.com/BookStore/v1/Books', { fixture: 'books.json' }).as(
      'booksRequest'
    );
   
    cy.visit('https://www.demoqa.com/books');
    cy.wait('@booksRequest');
   
    cy.contains('a', book.title).should('be.visible');
  });

});

The table will now be populated by a single entry titled “Designing Evolvable Web APIs with ASP.NET”, and you can assert against it before taking your next action.

Asserting The Response

Asserting the response to the fetch request allows you to ensure that the communication between the back end and the front end is behaving as expected. So, once you are done with stubbing the data, you can proceed toward asserting the response.

const book = {
  title: 'Designing Evolvable Web APIs with ASP.NET',
  ISBN: '9781449337711',
};

describe('Bookstore Application', () => {
  beforeEach('Login', () => {
    cy.authenticate(user);
  });
 
  specify('As a user, I should be able to add a book to my profile', () => {
    cy.intercept('GET', `${Cypress.config('baseUrl')}/BookStore/v1/Books`, ($req) => {
      $req.reply(($res) => {
        $res.send({ fixture: 'books.json' });

        expect($res.statusCode).to.equal(200);
        expect($res.statusMessage).to.equal('OK');
      });
    }).as('booksRequest');
   
    cy.visit('https://www.demoqa.com/books');
    cy.wait('@booksRequest');
   
    cy.contains('a', book.title).should('be.visible');
  });
});

This code captures the request ($req), then captures the response ($res) and sends it a stub containing fixture data. While separating the intercepted URL from the fixture by a comma is a symbolic version of the method, asserting the response is the longer version.

Besides sending a fixture, there are two assertions -

  • Assert status is 200
  • Assert message is “OK”

This fulfills the objective of asserting the response. You can verify that despite having stubbed data, the communication between the back end and the front end is working perfectly. When those assertions occur as the status and message have not been mocked, they can be used to capture API failures.

Completing The Test

Now, as the data has been stubbed and the response has been asserted, you can move on with completing the test.

The ideal user journey should be like the following -

  • When a book becomes visible within the listing, the user should select the book.
  • That selection will redirect to the individual book page.
  • The necessary data (e.g. title, subtitle, ISBN) about the book will be visible on the book page.
  • There should also be a button on the page for adding the book to the user’s book collection.
  • When a user adds a book of his/her liking to their collection, the book title should appear on the user’s profile page.

To test this user journey with better accuracy, the test should select the stubbed book and then assert the response that the correct book page is being visited. That can be done by checking against a supplied ISBN and title.

The final steps should be clicking on the “Add To Your Collection” button, visiting the user’s profile, and then you can assert that the selected book title is visible within the user’s book collection.

const book = {
 title: 'Designing Evolvable Web APIs with ASP.NET',
  ISBN: '9781449337711',
};

describe('Bookstore Application', () => {
  before('Login', () => {
    cy.authenticate(user);
  });
 
  after('Delete the book', () => {
    cy.deleteBook(book.ISBN);
  });
 
  specify('As a user, I should be able to add a book to my profile', () => {
    cy.intercept('GET', `${Cypress.config('baseUrl')}/BookStore/v1/Books`, ($req) => {
      $req.reply(($res) => {
        $res.send({ fixture: 'books.json' });

        expect($res.statusCode).to.equal(200);
        expect($res.statusMessage).to.equal('OK');
      });
    }).as('booksRequest');

    cy.visit('https://www.demoqa.com/books');
    cy.wait('@booksRequest');

    cy.contains('a', book.title).should('be.visible').click();

    cy.url().should('contain', book.ISBN);
    cy.get('.profile-wrapper').within(() => {
      for (const [key, value] of Object.entries(book)) {
        cy.get(`#${key}-wrapper`).should('contain', value);
      }
    });

    cy.get('.text-right').within(() => {
      cy.get('#addNewRecordButton').click();
    });

    cy.visit('https://www.demoqa.com/profile');

    cy.contains('.rt-tr-group', book.title).should('be.visible');
  });
});

Conclusion

Cypress intercept can be stated as the next-generation solution for building spies, stubbing data, and overall improvement in end-to-end tests through various steps. This article gives you an in-depth idea about how you can spy network requests to monitor network traffic within your application.

There are numerous more efficient ways to make the best use of the cypress intercept method, and we will surely publish more articles in the future to cover them. Also, we already have multiple informative articles on various important tech topics on our blog page. So, we highly recommend you check them out.

Now, after such a detailed discussion on Cypress, you must have figured out how important it is to automate your tests, and the most efficient way to do that is by using advanced AI-based test automation tools like Preflight. You will be stunned to see how this simple browser extension overpowers most other heavy testing tools and fulfills all your testing needs within seconds. And, the best part is that you can get a glimpse of that magical testing experience for free.

We also have our high-performance Cypress test recorder that allows you to generate Cypress codes for your tests within a few moments.

To know more about our products and services, feel free to reach out to us anytime, or visit our amazing website.

Source of Example: https://javascript.plainenglish.io/improve-your-end-to-end-tests-with-cypress-intercept-2c68156d9495