Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wait for element to disappear in cypress?

I have a loading indicator that I need to wait for to disappear before doing my assertions.

I´ve seen some use the following, but it does not seem to work for me and also I don´t want it to be an assertion. cy.get('element, {timeout: 10000}).should('not.exist);

Anyone having any tips?

like image 860
jaikl Avatar asked Dec 07 '18 15:12

jaikl


People also ask

How do you wait for an element in Cypress?

Wait for API response Cypress works great with http requests. If you are waiting for some resources to be loaded in your app, you can intercept a request and then create an alias for it. That alias will then be used with . wait() command.

How do you wait for a spinner to disappear in Cypress?

If you specifically need to wait, you could use the wait() function of cypress before making an assertion, and provide the amount of time to wait before timeout.

How do you know if an element is present or not in Cypress?

Conditionally check whether an element has certain text: get('body'). then(($body) => { // synchronously ask for the body's text // and do something based on whether it includes // another string if ($body. text(). includes('some string')) { // yup found it cy.


3 Answers

If you specifically need to wait, you could use the wait() function of cypress before making an assertion, and provide the amount of time to wait before timeout.

But note, this is an anti-pattern as you can find in the docs:

You almost never need to wait for an arbitrary period of time. There are always better ways to express this in Cypress.

That said, if your loading indicator is bound to some network request, you can wait for them to finish before making an assertion. This could be achieved with something like this example:

// Wait for the route aliased as 'getAccount' to respond
// without changing or stubbing its response
cy.server()
cy.route('/accounts/*').as('getAccount')
cy.visit('/accounts/123')
cy.wait('@getAccount').then((xhr) => {
  // we can now access the low level xhr
  // that contains the request body,
  // response body, status, etc
})

More info about waiting for requests could be found here.

Also, make sure that you really want to use .should('not.exist') and not .should('not.be.visible').

like image 113
Diogo Rocha Avatar answered Oct 08 '22 02:10

Diogo Rocha


IMHO the cleanest way is not to use waits nor timeouts with get, this is kinda an antipattern.

I would recommend to use Cypress waitUntil command and use something like:

 cy.waitUntil(function() {
  return cy.get('element').should('not.exist');
 })

or depending on the app code you can use not.be.visible.

like image 29
voy Avatar answered Oct 08 '22 03:10

voy


Loading spinner implementations often just hide the element rather than removing it from the DOM. Hence, should("not.exist") won't work for them.

cy.get("element").should("not.be.visible") is the right approach in such cases (as Diogo's answer already hinted).

like image 14
Philzen Avatar answered Oct 08 '22 04:10

Philzen