Skip to content

Re-query elements that are found 'detached' from the DOM #7306

@jennifer-shehane

Description

@jennifer-shehane

Current status

Update 12/06/2022: This work as been complete and will be released in Cypress v12 today.

This is currently in progress. See #7306 (comment), #7306 (comment) and #7306 (comment) for a brief description of the plan and updates on current status.

Current behavior:

Currently when Cypress queries an element that was passed from a parent element (say in .get(), .click() or .find()), if the element at some point becomes detached from the DOM, we throw an error:

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

<element>

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

The previous command that ran was:

  cy.get()

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

Screen Shot 2020-11-02 at 10 27 54 AM

Desired behavior:

Really users just want to re-query the DOM for the previously found element and click on the new element. Because it's more often than not that the framework underneath has created a completely new DOM element and inserted it into the DOM.

The proposal is to re-query the previously found element and continue the command with any newfound elements. Perhaps this could be an option passed to the command to allow this or not.

Reproducible Example

Provided in #9032

index.html

<form>
    <select onchange="document.forms[0].submit()">
        <option value="1">First</option>
    </select>
    <input />
</form>

spec.js

it('this will fail but should not', () => {
    cy.visit('index.html')
    cy.get("select").select("First")
    // adding any wait time will make it pass
    // cy.wait(0)
    cy.get("input").type("Hallo")
})

Related issues

Metadata

Metadata

Assignees

Labels

EpicRequires breaking up into smaller issuespkg/driverThis is due to an issue in the packages/driver directorytype: featureNew feature that does not currently existv12.0.0 🐛

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions