How to let Cypress contains return boolean instead of failing the test

Viewed 787

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?

2 Answers

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

Related