Как указывало jonrsharpe , в HTML нельзя использовать несколько элементов с одинаковым атрибутом id
.
При этом DOM достаточно умен и может восстанавливаться и работать даже с некорректным HTML. Дублирующие элементы - id
не должны вызывать особых проблем.
Если вы, например, попробуйте сделать document.querySelectorAll('#wrapper')
, он должен вернуть список из 2 элементов (в вашем случае).
Проблема в том, что Cypress использует jQuery для запроса DOM вместо использования собственных методов DOM, и я предполагаю, что jQuery не такой умный (или более педантичный).
При этом я не могу воспроизвести эту ошибку при запуске:
// succeeds
cy.get('div#wrapper').should('have.length', 2)
Только при прямом запросе #wrapper
(без предшествующего div
):
// fails
cy.get('#wrapper').should('have.length', 2)
Я считаю, что это связано с тем, что jQuery использует эвристику преждевременного выхода, когда строка селектора (#wrapper
) содержит только один идентификатор (и именно поэтому div#wrapper
возвращает оба элемента).
Кроме того, ваше решение в комментариях (cy.get('#pages') .find('div#wrapper') .should(($div) => { expect($div).to.have.length(2) })
), хотя и работает, не идеально, потому что оно не будет повторяться. Позвольте мне продемонстрировать:
В следующем коде 2-й #wrapper
появится в DOM только через 1 сек.
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);
});
});
});
Таким образом, вы должны пойти с решением, аналогичным B
или C
.