Asynchronous Nature in Cypress


Cypress is built on node.js server and it works with Javascript programming language. Anything which is dependent on node.js is asynchronous in nature and so Cypress commands work in that mode.

When we have a group of test steps in a test case, all the steps start executing in parallel without waiting for the previous step to complete. In a synchronous execution, each test step runs in sequence and we move to the next step only if the previous step execution is done.

Thus in asynchronous execution like Cypress, each test step is independent to each other even though the test steps are designed in a sequential order. In short, in an asynchronous mode each step does not take into account the result or state of the previous step execution and simply runs every steps.

Cypress has come up with a wrapper which makes sure that test execution of its commands happen in sequence in which they are developed. Thus these commands are executed all at once but they are queued. However if a Javascript command works along with a Cypress command, it remains asynchronous.

Example

Now let us execute a Cypress code −

// test suite
describe('Tutorialspoint Test', function () {
   // test case
   it('Test Case1', function (){
      // test step to launch a URL
      cy.visit("https://www.tutorialspoint.com/index.htm");
      // enter test in the edit box
      cy.get('#gs_50d > tbody > tr > td'). should('have.length',2);
      // locate element with get and find method
      cy.get('#gs_50d > tbody > tr > td'). find('input')
      //enter test in the edit box
      .type('Cypress');
      console.log('Tutorialspoint');
   });
});

On triggering the above code for execution, if we open the browser console, we will find Tutorialspoint printed on it even before the browser is loaded. This confirms the fact that console.log test step did not wait for other test steps and prints immediately in console.

Thus we see that since console.log is a Javascript command it doesn't queue itself like a Cypress compound and carries on with its execution. Cypress executes its steps serially with the help of promise handling.

A promise is a programming language that determines the state of a Cypress command. There are three types of promise states as listed below −

  • Resolved − This is the state if the test step executes without failure.

  • Pending − This is the state if the test step execution result is being awaited.

  • Rejected − This is the state if the test step executes with failure.

The following command in Cypress gets executed only after the previous command or promise response is resolved. We can implement promise in our Cypress code with the help of then() method.

Example

The code below describes the promise implemented in Javascript for each Cypress compound. This implementation makes a code dirty and lengthy.

// test suite
describe('Tutorialspoint Test', function () {
   // test case
   it('Test Case1', function (){
      return cy.visit('https://www.tutorialspoint.com/index.htm')
      .then(() => {
         return cy.get('.product');
      })
      .then(($element) => {
         return cy.click($element);
      })
   })
})

Cypress handles promises internally and resolves them with the help of wrappers and we can implement our code without taking into account the promise states. Thus the code readability increases to a large extent.

The above code in Cypress without promise.

// test suite
describe('Tutorialspoint Test', function () {
   // test case
   it('Test Case1', function (){
      cy.visit('https://www.tutorialspoint.com/index.htm')
      cy.get('.product').click();
   })
})

Thus Cypress takes into account that the next step in a test case shall execute only if the prior command or promise is in resolved state.

Updated on: 05-Aug-2020

309 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements