Skip to content

Latest commit

History

History
181 lines (133 loc) 路 10.1 KB

README.md

File metadata and controls

181 lines (133 loc) 路 10.1 KB

cypress-wait-until

Add the Cypress waiting power to virtually everything 馃帀

Build Status Build Cron Renovate enabled Cypress Dashboard NPM downloads
Commitizen friendly FOSSA Status semantic-release License: MIT TypeScript Open Source Saturday

Use this plugin to wait for everything not expected by Cypress wait.

Installation

npm i -D cypress-wait-until
# or
yarn add -D cypress-wait-until

Usage

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>');

TypeScript

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"]
    }
  }
}

Arguments

  • 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.


Why did we write it?

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 鉂わ笍

Open Source Saturday

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 鉂わ笍

Contributing

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).

Contributors

Thanks goes to these wonderful people (emoji key):

Stefano Magni
Stefano Magni

馃捇 鈿狅笍 馃摉
Tommaso Allevi
Tommaso Allevi

馃捇 鈿狅笍
brogueady
brogueady

馃捇

This project follows the all-contributors specification. Contributions of any kind welcome!