• Stars
    star
    688
  • Rank 63,506 (Top 2 %)
  • Language
    JavaScript
  • License
    Other
  • Created about 5 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Add the Cypress waiting power to virtually everything 🎉

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 body is retried
cy.getCookie('token') // will not be retried
  .waitUntil(cookie => cookie.value === '<EXPECTED_VALUE>');
  • you cannot put assertions inside checkFunction. There is no way to avoid a test failure if an assertion throws an error. You must manually check what the assertions would check for you. The most common case is checking that an element exists or not, instead of using cy.get('#id').should('exist') you should check that Cypress.$('#id').length is greater than 0. Here you can find a deeper explanation

  • nested cy.waitUntil calls don't respect timeout options. timeout and interval are converted to a number of retries. If the parent cy.waitUntil retries 10 times and the nested one 15 times, then the latter will be run 150 times before giving up, resulting in an extremely long wait. See the discussion for more info

TypeScript

If you use TypeScript you can define the checkFunction returning type too. Take a look at the plugin.spec.ts file to read about the cy.waitUntil signature.

IMPORTANT:

  1. Remember to add cypress-wait-until to the cypress/tsconfig.json file
{
  "compilerOptions": {
    "types": ["cypress", "cypress-wait-until"]
  }
}
  1. If you are encountering "cy.waitUntil is not a function" or "cy.waitUntil is undefined", you might need to specify the support file in your cypress.json for the import to work correctly:
{
  "supportFile": "cypress/support/commands.ts"
}

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 Type Default Description
errorMsg string | function "Timed out retrying" The error message to write. If it's a function, it will receive the last result and the options passed to cy.waitUntil
timeout number 5000 Time to wait for the checkFunction to return a truthy value before throwing an error.
interval number 200 Time to wait between the checkFunction invocations.
description string "waitUntil" The name logged into the Cypress Test Runner.
logger function Cypress.log A custom logger in place of the default Cypress.log. It's useful just for debugging purposes.
log boolean true Enable/disable logging.
customMessage string undefined String logged after the options.description.
verbose boolean false If every single check result must be logged.
customCheckMessage string 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

Plugin log options



Could cy.waitUntil avoid failing the test?

No. cy.waitUntil waits for something that must happen, otherwise the test will fail. Cypress enforces to avoid conditional testing and the plugin agrees with that.

There are cases where conditional testing makes sense but if cy.waitUntil would have this capability everyone will use it to create conditional tests, treating the Cypress feature—because avoiding conditional testing is a feature—as "a bug".

If you need conditional testing you could write your own recursive promise check function (take a look here and here where it is explained how to do that) where you manage your case. After all, cy.waitUntil is just a recursive promise manager 😊

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 package.json configuration setting cypressUploadRecordings to false (or set your own Cypress recording key).

Contributors

Thanks goes to these wonderful people (emoji key):


Stefano Magni

💻 ⚠️ 📖

Tommaso Allevi

💻 ⚠️

brogueady

💻

seeu1

🤔

Sarah Weir

🐛 💻

Lee Alexis

📖

Phil Burrows

🤔 💻 ⚠️

Leo Viezens

📖

Pier-Luc Gendreau

📖

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

More Repositories

1

ui-testing-best-practices

The largest UI testing best practices list (last update: March 2023)
1,631
star
2

cypress-otp

Enter a valid OTP token in your UI tests.
JavaScript
47
star
3

all-my-contributions

A list of all my contributions ❤️
35
star
4

redux-saga-login-react-example

The redux-saga login example with a super-essential UI
JavaScript
32
star
5

working-software-mastering-ui-testing

Working Software conference - the companion repository of the "Mastering UI Testing" talk
JavaScript
21
star
6

figma-to-xstate

🚧 A Figma plugin to convert a Figma prototype to an XState machine.
TypeScript
19
star
7

reactjsday-2019-testing-course

React Testing course created for the Italian ReactJSDay 2019 conference
JavaScript
17
star
8

nprr

(deprecated) nprr: npm run + autocomplete 🚀
HTML
16
star
9

people-list-xstate

A project built for an internal XState Working Group
TypeScript
14
star
10

gatsby-plugin-iubenda-cookie-footer

Gatsby plugin to add the Iubenda's cookie policy banner
JavaScript
11
star
11

cypress-twitch-with-fabio-biondi

JavaScript
10
star
12

gatsby-plugin-preconnect

Gatsby plugin to add a <link rel="preconnect"> for every specified domain
JavaScript
10
star
13

cypress-react-devtools

A working React+Redux app to easily (but MANUALLY) verify if the React devtools are working with the Cypress-controlled browser.
JavaScript
9
star
14

whatsapp-messages-batch

An easy way to write WhatsApp messages in advance and batch 'em all
JavaScript
8
star
15

frontend-testing-on-steroids-v2

Front-end Testing on Steroids (v2) - companion repo
JavaScript
8
star
16

gatsby-plugin-perfume.js

[DEPRECATED] Gatsby plugin to embed Perfume.js
JavaScript
5
star
17

cypress-protobuf

Encode a fixture with Protocol Buffers
JavaScript
5
star
18

javascript-testing-practical-approach-2021-course

Javascript Testing, a Practical Approach
JavaScript
4
star
19

url-content-changes-checker

A Node.js script to read and compare a remote resource body
JavaScript
4
star
20

react-crypto-compare

A simple cryptocurrencies converter component based on https://min-api.cryptocompare.com
JavaScript
4
star
21

reactjsday-2018-workshop

All the commits made during the 2018 ReactJSDay workshop
JavaScript
4
star
22

frontend-testing-on-steroids

Front-end Testing on Steroids - companion repo
JavaScript
4
star
23

javascript-testing-practical-approach-2021-course-v3

Javascript Testing, a Practical Approach (v3)
JavaScript
4
star
24

increase-by-1

A VSCode extension for replacing a series of selection with a sequence of numbers
JavaScript
4
star
25

gatsby-plugin-preload-link-crossorigin

[DEPRECATED] Gatsby plugin to add the crossorigin attribute to every <link rel="preload"> tag
JavaScript
3
star
26

frontend-testing-on-steroids-with-cypress-2021-course

Front-end testing on steroids with Cypress
JavaScript
3
star
27

typescript-is-type

A Typescript-safe runtime type check function
TypeScript
3
star
28

npm-run-programmatically-example

JavaScript
2
star
29

storybook-knobs-redux-example

An example to control the Redux state with storybook-knobs
JavaScript
2
star
30

javascript-testing-practical-approach-2024-course-v4

Javascript Testing, a Practical Approach (v4)
JavaScript
2
star
31

bitcoin-address-soft-regex-validation

A single-function package to perform soft (no checksum) bitcoin address (Base58 and Bech32) validation
JavaScript
2
star
32

educative-cypress-course

React Testing course, Educative version
JavaScript
1
star
33

frontend-testing-on-steroids-ticino-software-craft

JavaScript
1
star
34

common-state-managers-approach

Created with CodeSandbox
TypeScript
1
star
35

gas-scripts

Scripts related my own documents
JavaScript
1
star
36

hasura-conventional-commit

I need to play with some GH actions to test out a possible easy way to enforce conventional commit for the Hasura monorepo
1
star
37

cypress-mousemove-issue

The simplest code to show a strange mouse-related Cypress behaviour
HTML
1
star
38

cypress-wait-timeout

Cypress Wait Until #139 issue
JavaScript
1
star
39

cypress-detect-dom-changes

DOM changes detection with Cypress
JavaScript
1
star
40

multiplatform-images-photoshop-extension

A basic extension for Photoshop that resize all the given images to lot of different resolutions, useful for multiplatform development when you have to support lot of device screens
ActionScript
1
star
41

interviews

A non-exhaustive list of the interviews I did
1
star
42

create-react-library-typescript-cypress

The changes I applied to create-react-library (with Typescript option) to support React unit testing with Cypress
JavaScript
1
star
43

wait-until-click-xhr

Helping a friend with cypress-wait-until
JavaScript
1
star
44

npm-run-all-npm-run-bug

Repository to exploit a bug (?) between npm.run() and npm-run-all.
JavaScript
1
star
45

recoil-apis

Re-implementing basic Recoil API. Play with it on CodeSandbox or read about it in the blog post.
TypeScript
1
star
46

ol-map-in-popup-trough-react

The git diff showing how we worked around the problems we faced when rendering an OL map in a popup.
TypeScript
1
star
47

git-log-prettified

A prettified version of Git log
1
star
48

feti-workshop-e2e-testing-with-puppeteer

The reference repo of a workshop for FETI about browser automation (both for E2E testing and for web scraping) with Puppeteer. Workshop level: basic.
JavaScript
1
star
49

blueprint-templates

Some templates of mines
TypeScript
1
star
50

cafe-meetup-e2e-testing-with-puppeteer

The reference repo of a meetup for CaFE about browser automation (both for E2E testing and for web scraping) with Puppeteer. Talk level: basic.
JavaScript
1
star