Cypress.io — Using async and await
Cypress has a declarative chaining syntax that pipes inputs and outputs. Most of the time, you don’t even need to deal with the values going through the chain.
What’s actually happening in that example is Cypress gets a JQuery-wrapped element matching the selector, clicks that element, then makes an assertion using chai-jquery. You’ll notice you don’t actually see the JQuery-wrapped element in that code. This is called Points-free or Tacit Programming.
But what happens when you need to access a raw value from a chain? Cypress has a method called then
that is similar to a Promise’s then
method:
The example uses then
to unwrap the id
value. Nesting a single level is pretty straight-forward, but multiple levels of nesting can become much harder to understand. Async/await makes it much easier to unwrap values, but Commands are not Promises. Using await
on a Cypress chain will not work as expected.
There have been times I’ve wanted to use async/await in tests. It comes up in the gitter chat and has an issue in github. After trying to work with the Cypress runtime, I’ve gotten it to work as expected. I created a library called cypress-promise that will convert a Cypress chain into a promise. The previous example can be rewritten as follows:
Using async/await removed a nesting level. I’ve been using the cypress-promise library for a few weeks now. It has been working well and handles failures correctly.
I recommend being careful with its use. I use it for non-element values that are used for steps later in a test.