HMR
HMR

Reputation: 39250

CypressError: cy.find() failed because this element is detached from the DOM

There are several questions with this error but I seem to get this error while the element is certainly there.

This is the test code:

it.only('changes product attributes and sku', () => {
  cy.visit('/product/hoganrebel-r261-sneaker-6708K62AZC-grey/M0E20000000DX1Y');
  cy.get('[data-test=product-data]')
    .then(($product) => {
      cy.wrap($product)
        .find('[data-test=attribute-select-Size]')
        .select('6');
      cy.url().should('include', 'M0E20000000DX20');

      cy.wrap($product)
        .pause()//here I can see the element but when I step into find it fails
        .find('[data-test=attribute-select-Size]')
        .select('7');
      cy.url().should('include', 'M0E20000000DX22');
    });
});

I install dependencies with npm ci and run the project with yarn start. In another terminal tab I start the test with ./node_modules/cypress/bin/cypress open and then choose "run all specs" (only runs the it.only test). When it pauses I can clearly see the element but when opening the devtools and run document.querySelector('[data-test="attribute-select-Size"]') in the console it says null. Then I right click on the clearly visible element and choose inspect it shows me the element. Then go back to the console and run document.querySelector('[data-test="attribute-select-Size"]') again it gives me the element.

Adding a .wait(5000) before the pause does not solve this, could try to wait for xhr to finish but it has already finished after 5 seconds so that is not likely to be the problem.

This is obviously a bug but I'm not sure how to work around this issue.

Upvotes: 1

Views: 4345

Answers (1)

user14783414
user14783414

Reputation:

Detached elements are usually due to the framework re-writing sections of DOM with the same data selector ([data-test=product-data]) that it had before, but creating a new instance of the element.

When you hold on to a reference with test code like .then(($product) => { cy.wrap($product)..., $product is no longer valid after the re-write (I guess caused by .select('6') but I didn't dig into your app code to verify).

The short answer is repeat the cy.get('[data-test=product-data]') selection, there is no reason to grab a specific reference to that element.

it('changes product attributes and sku', () => {
  cy.visit('/product/hoganrebel-r261-sneaker-6708K62AZC-grey/M0E20000000DX1Y');
  cy.get('[data-test=product-data]')
    .find('[data-test=attribute-select-Size]')
    .select('6');                                 // DOM changes here?
  cy.url().should('include', 'M0E20000000DX20');

  cy.get('[data-test=product-data]')              // fresh DOM query
    .find('[data-test=attribute-select-Size]')
    .select('7');
  cy.url().should('include', 'M0E20000000DX22');
});

Upvotes: 1

Related Questions