CypressError: Timed out retrying: cy.click() failed because this element is detached from the DOM [closed]
Asked Answered
M

6

23

The dropdown basically takes long to get load itself once the back end response is received. If I put a wait of around 8 seconds, then it works. But, don't want to hard code the wait here. Any idea as what might be going wrong? I couldn't identify the css as well.

cy.get('input').last().type(`{selectall}${value}`);
        cy.get('mat-option > span').then(option => {
            if (option.get(0).textContent === 'Loading...') {
                cy.wait(5000);
            }
        });   

cy.containsCaseInsensitive(value, 'mat-option').first().scrollIntoView().debug().click();

The error log -

CypressError: Timed out retrying: cy.click() failed because this element is detached from the DOM.

<mat-option _ngcontent-gcj-c21="" class="mat-option ng-star-inserted" role="option" ng-reflect-value="[object Object]" tabindex="0" id="mat-option-104" aria-disabled="false" style="">...</mat-option>

Cypress requires elements be attached in the DOM to interact with them.

The previous command that ran was:

  > cy.debug()

This DOM element likely became detached somewhere between the previous and current command.

Common situations why this happens:
  - Your JS framework re-rendered asynchronously
  - Your app code reacted to an event firing and removed the element

You typically need to re-query for the element or add 'guards' which delay Cypress from running new commands.

https://on.cypress.io/element-has-detached-from-dom
Modica answered 13/11, 2019 at 8:59 Comment(0)
P
16

I faced same problem but you can solve it by

cy.get('.mySelector').should('be.visible').click({force:true});
Plaything answered 11/1, 2022 at 12:49 Comment(0)
G
6

I did face same issue keeping cypress to wait for some time till page is loaded solved the issue of detached element

example

cy.wait(3000)
cy.get(growth.tpsl_input_sessionName).clear().type(sessionName);
Gest answered 29/5, 2021 at 10:26 Comment(1)
cy.wait did fix it for me, but I didn't need to the long wait, even cy.wait(0) did the trick for meHanan
T
4

In order to wait for a network response, you can alias network requests and wait on them.

Check out the documentation for Cypress here: https://docs.cypress.io/guides/guides/network-requests.html#Flake

cy.route('/search*', [{ item: 'Book 1' }, { item: 'Book 2' }]).as('getSearch')

// our autocomplete field is throttled
// meaning it only makes a request after
// 500ms from the last keyPress
cy.get('#autocomplete').type('Book')

// wait for the request + response
// thus insulating us from the
// throttled request
cy.wait('@getSearch')

More examples are available in the documentation by following the link above.

Toname answered 13/7, 2020 at 9:47 Comment(0)
B
3

Maybe a late answer but can be useful for others with the same issue,sometimes using the Cypress jQuery wrapper can be a good idea.

Cypress.$('.mySelector').trigger('click');
Bircher answered 24/11, 2020 at 12:17 Comment(1)
Can we use xpath selector inside $(), I am unable to use xpath. Is jquery accepts only css selectors?Marciano
P
0

You may try in this way

cy.get('input').last().type(`{selectall}${value}`);
        cy.get('mat-option > span').then(option => {
            //if (option.get(0).textContent === 'Loading...') {
                //cy.wait(5000);
            //}

            cy.containsCaseInsensitive(value, 'mat-option').first().scrollIntoView().debug().click();
        });
Perlis answered 13/11, 2019 at 9:3 Comment(3)
Already tried that. BTW, why did you feel that it will work this way, just curious. Thanks for trying to help. It doesn't load the dropdown so fast, backend query takes time to return values.Modica
Instead of passing number in wait you can pass cy.wait('@getBooks'). please have a look into docs.cypress.io/guides/guides/network-requests.html#WaitingPerlis
its a generic code, it can be a different xhr each time, hence can't use @getBooksModica
T
0

like this worked for me

cy.intercept({method: "GET", url: "your/autocomplete/url**",}).as("getAutocomplete");

cy.get("#input-field-id").type("selectable item", {delay: 20}); cy.wait("@getAutocomplete").its("response.statusCode").should("equal",200); cy.get(".input-dropdown").should("contain", "selectable item").first().click();

Tart answered 4/6 at 8:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.