Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cy.contains() reruns previous commands when re-querying an alias #7413

Closed
kokovtsev opened this issue May 19, 2020 · 4 comments
Closed

cy.contains() reruns previous commands when re-querying an alias #7413

kokovtsev opened this issue May 19, 2020 · 4 comments
Labels
pkg/driver This is due to an issue in the packages/driver directory type: bug

Comments

@kokovtsev
Copy link

kokovtsev commented May 19, 2020

Current behavior:

Preconditions:

  • an element is located using cy.contains() invoked off the cy object and saved as @alias
  • the element is recreated by the application under test

If the test tries to retrieve the element using cy.get('@alias'), the whole chain is executed again as expected (starting with cy.contains()). The cy.contains() works fine and finds the element in the whole document.

However, if there were some querying commands before cy.contains(), they seem to interfere with the alias querying procedure. For instance, the alias query fails if the query command preceding to contains does not succeed. Please see the reproduction example for more clarity

Desired behavior:

When invoked off the cy object, the contains command should not depend in any way on the precedent command.

Test code to reproduce

Reproduction repo:
https://github.com/kokovtsev/cypress-repro-cy.contains/blob/master/cypress/integration/examples/contains.spec.js

Application under test:
https://codesandbox.io/s/gracious-newton-q4913?file=/src/App.js

Versions

Windows 10 x64, Cypress 4.5.0, Electron 80/Chrome 81/Firefox 76

See also

Might be related to:

@jennifer-shehane
Copy link
Member

jennifer-shehane commented May 20, 2020

I can recreate this with the code below. It seems it's just not recognizing the .contains() as a parent command and always attempting to travel up to the previous command when trying to retrieve the alias. This results in some weird behavior.

spec.js

it('cy.contains()', () => {
  cy.visit('index.html');
  
  // removing this line changes the behavior of the test
  cy.get('h1')
  cy.contains('Current').as('counter')
  cy.get('@counter').should('match', 'div')

  // this causes the <div> to be recreated and also removes H1
  cy.contains('button', 'Update DOM').click()

  // fails trying to get 'h1'
  cy.get('@counter').should('contain', 'Current 1')
})

index.html

<html>
<body>
  <h1 id="h1">Hello</h1>
  <div id="div">Current</div>
  <button id="button">Update DOM</button>
</body>
<script>
  document.getElementById('button').onclick = () => {
    const newText = document.createTextNode('Current')
    const newDiv = document.createElement('div').appendChild(newText)
    
    document.getElementById('div').remove()
    document.body.appendChild(newDiv)
    document.getElementById('h1').remove()
  }
</script>
</html>

With cy.get('h1') command

The alias tries to retrieve the h1 element (the previous command to the defined alias), so the test fails because it's been removed.

Screen Shot 2020-05-20 at 1 46 41 PM

Without cy.get('h1') command

It reruns the cy.visit() command (the previous command) - wow.

Screen Shot 2020-06-17 at 3 11 35 PM

@jennifer-shehane jennifer-shehane added the pkg/driver This is due to an issue in the packages/driver directory label May 20, 2020
@cypress-bot cypress-bot bot added the stage: ready for work The issue is reproducible and in scope label May 20, 2020
@jennifer-shehane jennifer-shehane changed the title cy.contains() uses wrong subject when re-querying an alias cy.contains() reruns previous commands when re-querying an alias May 20, 2020
@Gibstick
Copy link

Gibstick commented May 5, 2021

We ran into the same issue and our test is structurally identical to the one in #7413 (comment). This might be obvious to others but a quick workaround is to do cy.root().contains(...), which should be functionally equivalent (I hope).

@BlueWinds
Copy link
Contributor

We ran into the same issue and our test is structurally identical to the one in #7413 (comment). This might be obvious to others but a quick workaround is to do cy.root().contains(...), which should be functionally equivalent (I hope).

Good workaround, yeah.

I'm going to close this issue, since the resolution to #7306 (coming out in Cypress 12) is basically redoing how commands chain together, and the internal logic around re-querying the DOM is pretty different. See my comments in that issue for a more complete explanation of the changes coming in Cypress 12 in this regard.

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Dec 6, 2022

Released in 12.0.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v12.0.0, please open a new issue.

@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators Dec 6, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
pkg/driver This is due to an issue in the packages/driver directory type: bug
Projects
None yet
Development

No branches or pull requests

4 participants