Front-End Testing with Cypress
I had been working with Cypress since June 2018. This blog will be talking about how to write better tests using Cypress.
Static Time Waiting
According to Cypress:
You almost never need to wait for an arbitrary period of time. There are always better ways to express this in Cypress.
So, Let's check the following example.
First, we want to visit the page and verify that page content is loaded:
it('should visit the page and verify the content', function() {
cy.visit('https://react-dgz11u.stackblitz.io/');
cy.get('[data-test="grid-container"]').should('be.visible');
})
When running the test for couple of times. we can notice that our test isn't stable.
So what is happening here:
In the beginning, we visit the page and load its content. After the page is loaded, CCypress moves to execute the next command, which is cy.get.
cy.get
tries to find the element inside the DOM, but it can't find it. So, Cypress keeps checking to find the element within the predefined timeout (Default Commands timeout list). If the element is ready, it moves to the next command; otherwise, Cypress fails when exceeding the timeout value.
Next step in making our test more stable. How? Since we don't have control over stackblitz dev server loading time. We need to verify that the loader is hidden and then we start running our test.
So, we can do the following:
it('should visit the page and verify the content', function() {
cy.visit('https://react-dgz11u.stackblitz.io/');
cy.get('#loader-box', {timeout: 10000}).should('not.be.visible')
cy.get('[data-test="grid-container"]').should('be.visible');
})
The line we added aims to wait for the loader to hide with customized timeout. Now, Cypress is going to keep waiting for the loader to hide for longer time and once the loader is hidden Cypress calls the next line.
But now, we are facing a new issue.
What is happining here is that our checks run before the loader is shown. Currently we are facing a race condition between UI and the Cypress runner. They are out of sync.
We need to make sure that the Loader is shown then we should wait for it to be hidden.
it('should visit the page and verify the content', function() {
cy.visit('https://react-dgz11u.stackblitz.io/');
cy.get('#loader-box').should('be.visible')
cy.get('#loader-box', {timeout: 10000}).should('not.be.visible')
cy.get('[data-test="grid-container"]').should('be.visible');
})