If element exists wait for it to disappear
Because of the timing aspect it can be tricky to get this test right.
Controlling Triggers
You really need to know what controls the spinner - usually it's a call to API. You can then delay that call (or rather it's response) to "force" the spinner to appear.
To do that, use an intercept
cy.intercept(url-for-api-call,
(req) => {
req.on('response', (res) => res.delay(100)) // enough delay so that spinner appears
}
)
// whatever action triggers the spinner, e.g click a button
cy.getByTestId('loader-spinner') // existence is implied in this command
// if the spinner does not appear
// the test will fail here
cy.getByTestId('loader-spinner').should('not.exist') // gone after delay finishes
Two scenarios
First off, I don't think your two scenario idea is going to help you write the test correctly.
You are trying to conditionally test using try..catch (nice idea, but does not work). The trouble is conditional testing is flaky because of the timing aspect, you get the test working in a fast environment then it starts to break in a slower one (e.g CI).
Better to control the conditions (like delay above) then test page behaviour under that condition.
To test that the spinner isn't appearing, return a stub in the intercept It should be fast enough to prevent the spinner showing.
cy.intercept(url-for-api-call, {stubbed-response-object})
// whatever action triggers the spinner, e.g click a button
cy.getByTestId('loader-spinner').should('not.exist') // never appears
Take a look at When Can The Test Blink?
Wait for element to not have class - and then other element to disappear in Cypress
I Think you miss some steps, because like in this webinar, cypress can see that the element is missing from the page at the moment step 1 is implemented and the loading has not started, so it gives false positive assertion. My solution to such cases is to add more steps to the test, instead of using fixed cy.wait()
-my steps are the following:
cy.get('.add_to_cart_button').click(); // Step 1
cy.get('.overlay').should( 'be.visible' ); // Needed to see that the process is starting
cy.get('.overlay').should( 'not.be.visible' ); // Needed to see that the process has ended
cy.get('.add_to_cart_button').should( 'have.class', 'loading' ); // Needed to see that the process is starting
cy.get('.add_to_cart_button').should( 'not.have.class', 'loading' ); // Needed to see that the process has ended
cy.visit( Cypress.env( 'baseUrl' ) + '/cart' ); // Step 9
Also I recommend using the following lines in the cypress.json file:
"defaultCommandTimeout": 60000,
"requestTimeout": 60000,
"responseTimeout": 60000,
How to wait for element to be visible
You can wait for the element to be visible like so:
// Give this element 10 seconds to appear
cy.get('[data-test=submitIsVisible]', { timeout: 10000 }).should('be.visible');
According to Cypress's Documentation:
DOM
based commands will automatically retry and wait for their corresponding elements to exist before failing.
Cypress offers you many robust ways to query the DOM
, all wrapped with retry-and-timeout logic.
Other ways to wait for an element’s presence in the DOM
is through timeouts
. Cypress commands have a default timeout
of 4 seconds, however, most Cypress commands have customizable timeout
options. Timeouts can be configured globally or on a per-command basis. Check the customizable timeout
options list here.
In some cases, your DOM
element will not be actionable. Cypress gives you a powerful {force:true}
option you can pass to most action commands.
Cypress: Alternative for command 'wait'
My problem is not to wait till the page is successfully loaded, but till the content exist and is available/clickable etc.
With this command a small improvement is noted but is not the solution of my problem.
Cypress.config('defaultCommandTimeout', 50000);
Related Topics
Redirect to Url After Form Submit in React
How to Sort Data in Ascending or Descending Order in Reactjs
Jest Encountered an Unexpected Token: Syntaxerror: Unexpected Token {
How to Add Pm or Am Based on Hour from Input
How to Show a Confirm Message Before Delete
Combine Multiple JavaScript Files into One Js File
Typescript Module Has No Exported Members - React
Expand Div on Click With Smooth Animation
One Time Page Refresh After First Page Load
Mobile Safari Sometimes Does Not Trigger the Click Event
Print Embedded Pdf from Browser With Javascript, Html5, Angularjs
How to Only Remove the "Watch Later" and "Share" Buttons from Youtube Iframe Embed Player
Looping Through a Json Object Containing More Objects and Arrays
React: How to Inject React Component into Body
Disable Click Outside of Bootstrap Modal Area to Close Modal
Javascript Regex Splitting Words in a Comma Separated String