I am testing a virtual dropdown list, my code is like this:
while (!cy.contains('.ant-select-item',/^Cypress$/)) {
cy.get('.ant-select-dropdown').trigger('wheel', {deltaX:0,deltaY:100});
}
It keeps wheeling down until finds a specific element. However, this code does not work, when contains does not find the specific element, it fails the test instead of return false.
How to make the while loop work?
You can use jQuery, Cypress.$ instead.
while (!Cypress.$('.ant-select-item:contains('Cypress').length) {
cy.get('.ant-select-dropdown').trigger('wheel', {deltaX:0,deltaY:100});
}
One thing - :contains() will match partially, so this is no good if more than one item has the string.
Long version - Cypress.$('.ant-select-item:contains('Cypress') gets a list of matching elements. If none found, it does not fail but the length of the list is 0. Since 0 is falsy, the loop continues.
The loop idea is only good if the dropdown does actually contain the value somewhere, otherwise it spins forever.
While loops generally don't work with Cypress, it would be safer to use a repeating (recursive) function
function findItem(item, loop = 0) {
if (loop === 10) throw 'Too many attempts'
cy.get('.ant-select-item')
.invoke('text')
.then(textsOfCurrentList => {
if (!textsOfCurrentList.contains(item)) {
// wheel down and try next
cy.get('.ant-select-dropdown').trigger('wheel', {deltaX:0,deltaY:100})
findItem(item, ++loop)
} else {
return
}
})
})
findItem('Cypress')
Or with package cypress-recurse
recurse(
() => cy.get('.ant-select-item').invoke('text'),
(textsOfCurrentList) => {
const found = textsOfCurrentList.contains(item)
if (!found) {
cy.get('.ant-select-dropdown').trigger('wheel', {deltaX:0,deltaY:100})
}
return found // true means finish, false means repeat
},
{
log: true,
limit: 10, // max number of iterations
timeout: 30000, // time limit in ms
},
)
A good background info avoid-while-loops-in-cypress