As jonrsharpe pointed out, it's invalid HTML to have multiple elements with identical id
attribute.
That being said, DOM is quite smart and can recover and work even with invalid HTML. Duplicate-id
elements shouldn't cause much trouble.
If you e.g. try doing document.querySelectorAll('#wrapper')
it should return list of 2 elements (in your case).
Problem is, Cypress is using jQuery to query the DOM instead of using native DOM methods and I guess jQuery isn't as smart (or it's more pedantic).
That being said, I can't reproduce that error when running:
// succeeds
cy.get('div#wrapper').should('have.length', 2)
Only when querying #wrapper
directly (without the preceding div
):
// fails
cy.get('#wrapper').should('have.length', 2)
I reckon this is because jQuery uses a heuristic of exiting early when a selector string (#wrapper
) contains only a single id (and that's why div#wrapper
returns both elements).
Also, your solution in comments (cy.get('#pages') .find('div#wrapper') .should(($div) => { expect($div).to.have.length(2) })
), while working, isn't ideal because it won't retry. Let me demonstrate:
In the following code, the 2nd #wrapper
will appear in the DOM only after 1 sec.
describe( 'test', () => {
beforeEach(() => {
cy.document().then( doc => {
doc.body.innerHTML = `
<div id='pages'>
<div id='wrapper'>1</div>
</div>
`;
setTimeout(() => {
doc.body.innerHTML = `
<div id='pages'>
<div id='wrapper'>1</div>
<div id='wrapper'>2</div>
</div>
`;
}, 1000 );
});
});
// will fail
it('solution A', () => {
cy.get('#pages') // <- won't be retried
.find('div#wrapper') // <- only this command will be retried
.should( $div => expect($div).to.have.length(2) );
});
// will pass
it('solution B', () => {
cy.get('#pages #wrapper') // <- will be retried and succeed in 1sec
.should( $div => {
expect($div).to.have.length(2);
});
});
// will pass
it('solution C', () => {
cy.get('#pages')
.should($pages => {
// using native DOM querying
expect($pages[0].querySelectorAll('#wrapper').length).to.eq(2);
});
});
});
Thus, you should go with solution similar to B
or C
.