Cypress: cy.get().contains() does not accept new DOM elements

Created on 23 Oct 2018  路  8Comments  路  Source: cypress-io/cypress

Current behavior:

When cy.get().contains() is called, .contains() will only wait for the DOM elements that existed during cy.get(). Newly created DOM elements will not be checked against .contains().

Desired behavior:

  • cy.get() should accept new DOM elements while .contains() has not finished.
    I expect it to work like cy.get().should('contain', '...');.

  • Also the documentation misses the hint of this significant behavior difference.

Steps to reproduce:

HTML

<div class="myDiv">Div1</div>
<div class="myDiv">Div2</div>
<div class="replaceMe">Div3</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
    setTimeout(() => {
        $("div.replaceMe").replaceWith('<div class="myDiv">Expectation</div>');
    }, 4000);
</script>

Cypress Test

describe('test', () => {
    it('should work', () => {
        cy.visit('http://localhost:8080/cy.html');
        cy.get('.myDiv').contains('Expectation');
    });
});

Result:
image

3锔忊儯 proposal 馃挕 unexpected behavior

Most helpful comment

cy.contains('.myDiv','Expectation') works as expected and succeeds.

I still see the current behavior as an issue, especially because .get().contains() works fine in most cases where there is only one result for the .get()

As soon as there is a list of generated items, .get().contains() is no longer working as expected and race conditions occur. Also the reason is not obvious.

All 8 comments

I read some time ago a post concerning this, and the author encouraged the use of cy.contains('element', 'text') for cases like yours.

Can you try with cy.contains('.myDiv','Expectation')?

cy.contains('.myDiv','Expectation') works as expected and succeeds.

I still see the current behavior as an issue, especially because .get().contains() works fine in most cases where there is only one result for the .get()

As soon as there is a list of generated items, .get().contains() is no longer working as expected and race conditions occur. Also the reason is not obvious.

Yep I know, I got to know it through this post... Maybe it is good that this behavior gets documented somewhere in the Docs.

for me it is quiet confusing that it works with .should but not with .contains ...

think the cypress docu is not right.. if u take a look at the .should command, it is described as it works "will continue to retry its specified assertions until it times out" ( https://docs.cypress.io/api/commands/should.html#Timeouts ) ...

also .contains is described simular ".contains() can time out waiting for the element(s) to exist in the DOM." (https://docs.cypress.io/api/commands/contains.html#Timeouts) which works as expected, when it is NOT chained to other commands.. which is imo very critical...

That's how .contains (and by that coin .find, .eq, and .its) work though. It's not the most obvious detail in the docs but once you run into this gotcha once it makes sense I think.

I'm coming across this problem a lot in a SPA when the data isn't ready yet. It means we can't use .eq reliably and have to resort to using :nth-child selectors.

Just came across this - very weird how it doesn't retry with get->contains, but it does if you use contains on its own or get->should contain

Just for the record - this behavior is documented here: https://docs.cypress.io/guides/core-concepts/retry-ability.html

Was this page helpful?
0 / 5 - 0 ratings