Cypress Test Runner has built-in retry-ability that is so sweet. Instead of hard-coding waits into your tests, all you need is figure out how to query something and how to follow with an assertion. The test will keep querying until the assertion passes.
Do you need to detect when a new property gets added to an object? Wrap the object and assert that the new property is preset.
1 | // an object without a property |
Notice how the test continues after 500ms - when the property gets added and assertion should('have.property', 'id')
finally passes.
What if you want to detect when the property has a specific value and is not just present on an object? Sure, just add the value you expect to see to the assertion.
1 | // an object with an id |
Notice in the video below how the wrapped object shows "{id: initial}" in the assertion and then switches to "{id: abc123}" - because the object is "live" - Cypress re-evaluates the assertion over and over until it passes or times out.
What about adding and deleting a property on the window
object? Let's do this! Let's add a property and delete property.
1 | // asynchronously add and delete a property |
Notice in the above example that we have to use 2 cy.window()
commands, with a single assertion each. You cannot attach both assertions to a single cy.window()
. To understand why, notice what the Command Log shows. So here is the test with single command and 2 assertions:
1 | cy.window() |
The test finishes suspiciously quickly - in just 1 second, while the asynchronous code executes in 2 seconds. So we know something is wrong, and look at the assertions; it gives you a clue.
The second assertion tries to assert that a string "here" does not have property "customProp". Of course it does not, so it immediately passes, and the test completes.
Assertion should('have.property')
is one of those few assertions that change the subject. In essence, it asserts that window
has property customProp
and then yields window.customProp
to the next assertion, fooling you into false confidence.
The solution is to grab the window
again and run the second assertion on it.
1 | cy.window().should('have.property', 'customProp') |
So how does this relate to detecting when the page reloads? If there is no other external effect after reloading the page: no url change, no DOM change, etc, then you should property assertions. Here is an example page that reloads in response to a click
1 | <body> |
Here is my test - and this detects when the page reloads just fine.
1 | it('reloads', () => { |
See also
- Cypress retry-ability guide
- Cypress assertions page