cypress-example-recipes icon indicating copy to clipboard operation
cypress-example-recipes copied to clipboard

Add recipe for getting multiple elements at once

Open bahmutov opened this issue 7 years ago • 3 comments

Either as a pyramid of doom or using a helper function that flattens multiple actions

cy.get(...)
  .then(one => {
      cy.get(...)
        .then(two => {
            // compare one with two for example
        })
   })

Help like in https://github.com/bahmutov/cypress-promise-all-test/blob/master/cypress/integration/example_spec.js

  const all = (...fns) => {
    const results = []


    // maybe handle a case when it is a plain value
    // and just push it directly into the results
    fns.reduce((prev, fn) => {
      fn().then(result => results.push(result))
      return results
    }, results)


    return cy.wrap(results)
  }


  it('wraps multiple cypress commands', () => {
    return all(
      getNavCommands,
      getNavUtilities
    ).spread((commands, utilities) => {
      console.log('got commands', commands.text())
      console.log('got utilities', utilities.text())
    })
  })

bahmutov avatar Nov 14 '17 20:11 bahmutov

Hi there, i'm new to Cypress and Promises. I have a slightly different scenario.

Given adding parameter to the elements/functions, for example,

const getNav = (keyword) =>
    cy.get('ul.nav')
      .contains(keyword)

When passing it to the all() function for example,

all(
      getNav('Commands'),
      getNav('Utilities')
    ),

Then i would get this error:

TypeError: fn is not a function

Can you also provide an example for this? Thank you.

richard-hor-bgl avatar Feb 25 '19 01:02 richard-hor-bgl

@richard-hor-bgl Kind of late to the party but in case:

you need your getNav function to return another function.

const getNav = (keyword) => () =>
    cy.get('ul.nav')
      .contains(keyword)

Does the trick

bergerbo avatar Oct 11 '19 15:10 bergerbo

Additionally here's my simple getAll function that takes an array of elements to call cy.get() with and returns the array of results:

Cypress.Commands.add('getAll', (...elements) => {
  const promise = cy.wrap([], { log: false })

  for (let element of elements) {
    promise.then(arr => cy.get(element).then(got => cy.wrap([...arr, got])))
  }

  return promise
})

Usage :

cy.getAll('@foo', 'div', '.bar').then(([foo, divs, bar]) => {
// do things with foo, divs and bar
})

bergerbo avatar Oct 11 '19 15:10 bergerbo