Cypress Waitings and Execution Order
Learn how Cypress executes and waits for commands.
We'll cover the following
Cypress waitings and execution order
In the previous lesson, we wrote the following initial test:
it("The happy path should work", () => {
cy.visit("/register");
cy.get(".form-control").then($els => {
cy.get($els[0]).type("Tester");
cy.get($els[1]).type("user@realworld.io");
cy.get($els[2]).type("mysupersecretpassword");
cy.get("button").click();
cy.contains("No articles are here").should("be.visible");
});
});
Without noting it, we’ve leveraged some of Cypress’s interesting features.
Automatic waiting
Did you notice that the test seems to have a synchronous flow? Think about what happens between a command and the next one:
cy.visit("/register");
// what does "visit" mean? When is Cypress going to execute the next commands? Is JavaScript ready?
cy.get(".form-control").then($els => {
cy.get($els[0]).type("Tester");
// typing is an asynchronous task, when will the next task start?
cy.get($els[1]).type("user@realworld.io");
cy.get($els[2]).type("mysupersecretpassword");
cy.get("button").click();
// the web app makes an AJAX call, a lot of time passes before the "No articles are here" text becomes visible
cy.contains("No articles are here").should("be.visible");
});
In UI tests, everything is asynchronous: The JavaScript execution is asynchronous, the DOM update is asynchronous, and the actions of the user are asynchronous. A synchronous approach is a failure by definition.
Whereas, most of the existing browser automation tools (like Selenium or Puppeteer) force you to manually manage many asynchronous situations, while Cypress was created with asynchronous UI testing in mind.
Automatic waitings are important because:
-
They allow you to heed no mind to most asynchronous updates.
-
They make the test as fast as possible, avoiding fixed, slow, and brittletest pauses.
Answering the questions added as comments to the above snippet:
-
cy.visit
waits for the window to dispatch theload
event -
The next command is not executed until the typing ends.
-
Cypress retries
cy.contains
,cy.get
, and other commands by default. The commands have customizable timeout and when Cypress is not able to find the requested elements, they are retried until the elements are either added to the page or report an error.
Test Runner interactivity
Test Runner shows you what’s happening in:
-
The front-end application
-
Every executed Cypress command
-
The result of all assertions
As we’ve seen in the previous lesson, Test Runner is also interactive!
TTest Runner allows you to “time travel” through various phases of code and check the state of the front-end before and after the execution of every command. Take a look at the Test Runner documentation to discover more about it.
Test code execution order
Because Cypress command is asynchronous by default, Cypress automatically executes the test code twice:
-
First, Cypress executes the test code to read and queue all the commands it needs to execute.
-
Second, Cypress loads the page and executes, all the commands previously queued, one by one.
Try changing the test code to the following code.
Note: You can see the Cypress UI better by opening the link next to Your app can be found at:
Get hands-on with 1400+ tech skills courses.