I’m struggling with waiting for async functions to finish. In particular, I found these two methods to wait for completion of an async function before the test continues but don’t know the difference (if there is one):
cy.then(() => myAsyncFunction())
cy.wrap(null).then(() => myAsyncFunction())
My goal is to wait for two async functions in the beforeEach()
block before the actual tests start:
beforeEach(() => {
myAsyncFunction1() // This function has to be completed before the next one starts
myAsyncFunction2() // This function has to be completed before the test continues
// Only when myAsyncFunction2() has completed the actual tests should start
});
I tried to Google for the difference and took a look in the documentation for Cypress but sadly didn’t find an answer for how this behaves.
2
Answers
There are a few differences between
cy.then()
andcy.wrap(null).then()
:cy.then()
– This is used to wait for the result of the previous Cypress command before continuing. Since there is no previous command inbeforeEach()
,cy.then()
will not work.cy.wrap(null).then()
– This works by wrapping a null value and chaining a.then()
onto it. This allows you to execute async code before the tests run.Retries – Only commands chained after a Cypress command (like
cy.get()
) will be automatically retried on failure.cy.wrap(null).then()
will not be retried.Yielding –
cy.then()
yields the result of the previous command, whilecy.wrap(null).then()
always yields null.There is no difference between the two calls.
cy.then()
is an undocumented shorter form ofcy.wrap(something).then()
.cy.then()
will not wait for asynchronous functions to finish in the way you are asking.If you want
myAsyncFunction2()
to wait formyAsyncFunction1()
, you would use normal javascript patterns – but it depends entirely on what is inside those functions.cy.then()
is useful to wait for the command queue to finish, particularly when the commands modify a closure variable.Cypress prefers not to use closure variables, since many people have trouble understanding why the value isn’t updated in sequence. Instead they provide an
alias
feature to handle asynchronous variables.Please read Variables and aliases for more info.
Waiting for the asynchronous functions
As long as
myAsyncFunction*()
returns a promise, you just need to return that promise frombeforeEach()
.Cypress always waits for returned promises to complete before moving to the next command.