Add the Cypress waiting power to virtually everything 🎉
Use this plugin to wait for everything not expected by Cypress wait.
npm i -D cypress-wait-until
# or
yarn add -D cypress-wait-until
cypress-wait-until
extends Cypress' cy
command.
Add this line to your project's cypress/support/commands.js
:
import 'cypress-wait-until';
Then, in your test, you can write
// wait until a cookie is set
cy.waitUntil(() => cy.getCookie('token').then(cookie => Boolean(cookie && cookie.value)));
// wait until a global variable has an expected value
cy.waitUntil(() => cy.window().then(win => win.foo === "bar"));
// sync function works too!
cy.waitUntil(() => true);
// with all the available options
cy.waitUntil(() => cy.window().then(win => win.foo === "bar"), {
errorMsg: 'This is a custom error message', // overrides the default error message
timeout: 2000, // waits up to 2000 ms, default to 5000
interval: 500 // performs the check every 500 ms, default to 200
});
If you return a truthy value, it becomes the subject for the next command. So you can assert about it too
// wait until the Recaptcha token will be added to the dedicated hidden input field...
cy.waitUntil(() => cy.get("input[type=hidden]#recaptchatoken").then($el => $el.val()))
// ... then, check that it's valid string asserting about it
.then(token => expect(token).to.be.a("string").to.have.length.within(1, 1000));
The waitUntil
command could be chained to other commands too. As an example, the following codes are equivalent
cy.waitUntil(() => cy.getCookie('token').then(cookie => cookie.value === '<EXPECTED_VALUE>'));
// is equivalent to
cy.wrap('<EXPECTED_VALUE>')
.waitUntil((subject) => cy.getCookie('token').then(cookie => cookie.value === subject));
Please note: do not expect that the previous command is retried. Only what's inside the checkFunction
code is retried
cy.getCookie('token') // will not be retried
.waitUntil(cookie => cookie.value === '<EXPECTED_VALUE>');
If you use TypeScript you can define the checkFunction
returning type too. Here some examples with all the combinations of promises and chainable functions
cy.waitUntil(() => true);
cy.waitUntil<boolean>(() => true);
cy.waitUntil<string>(() => true); // Error
cy.waitUntil(() => Promise.resolve(true) );
cy.waitUntil<boolean>(() => Promise.resolve(true) );
cy.waitUntil<string>(() => Promise.resolve(true) ); // Error
cy.waitUntil(() => cy.wrap(true) );
cy.waitUntil<boolean>(() => cy.wrap(true) );
cy.waitUntil<string>(() => cy.wrap(true) ); // Error
cy.waitUntil(() => cy.wrap(true).then(result => result) );
cy.waitUntil<boolean>(() => cy.wrap(true).then(result => result) );
cy.waitUntil<string>(() => cy.wrap(true).then(result => result) ); // Error
cy.waitUntil(() => cy.wrap(true).then(result => Promise.resolve(result)) );
cy.waitUntil<boolean>(() => cy.wrap(true).then(result => Promise.resolve(result)) );
cy.waitUntil<string>(() => cy.wrap(true).then(result => Promise.resolve(result)) ); // Error
Please note: do not forget to add cypress-wait-until
to the cypress/tsconfig.json
file
{
"compilerOptions": {
"types": ["cypress", "cypress-wait-until"]
}
}
}
- checkFunction
A function that must return a truthy value when the wait is over.
- options:Object (optional)
Pass in an options object to change the default behavior of cy.waitUntil()
.
Option | Default | Description |
---|---|---|
errorMsg |
"Timed out retrying" |
The error message to write. |
timeout |
5000 |
Time to wait for the checkFunction to return a truthy value before throwing an error. |
interval |
200 |
Time to wait between the checkFunction invocations. |
description |
"waitUntil" |
The name logged into the Cypress Test Runner. |
logger |
Cypress.log |
A custom logger in place of the default Cypress.log. It's useful just for debugging purposes. |
log |
true |
Enable/disable logging. |
customMessage |
undefined |
String logged after the options.description . |
verbose |
false |
If every single check result must be logged. |
customCheckMessage |
undefined |
Like customMessage , but used for every single check. Useless if verbose is not set to true . |
Log options are a lot, take a look at the next screenshot to understand how they are printed
A lot of StackOverflow users had some difficulties in implementing a recursive promise with Cypress
just to repeatedly check for something to happen (see two of the various questions about the topic: How can i wait for each element in a list to update to a certain
text?
And How do I wait until a cookie is
set?).
This plugin is dedicated to them ❤️
This project has been made during one of the Open Source Saturdays, a series of Milan-based events where everyone codes just to spread some Open Source love ❤️
Contributes are welcome, if you need to run the tests through npm test
, you must update the packjage.json configuration setting cypressUploadRecordings
to false
(or set your own Cypress recording key).
Thanks goes to these wonderful people (emoji key):
Stefano Magni 💻 |
Tommaso Allevi 💻 |
brogueady 💻 |
seeu1 🤔 |
Sarah Weir 🐛 💻 |
This project follows the all-contributors specification. Contributions of any kind welcome!