Boon
Boon

Reputation: 411

wait for Cypress each() function to finish

I am calling a function populateArray which picks elements on the page using children() function. I want to store the attribute values into an using each() function. Here is what I am doing

static populateArray(){
let arr = []

 cy.xpath(NODE_PREVIEW_PANEL).children(NODE_TYPE)
                 .each((element, index, list) => arr.push(cy.wrap(element).invoke('attr', 'data-testid')))
}

The problem is when I call this function by assigning it to a variable

actualArray = ArticlePage.populateArray()

its not waiting for underlying each() function to complete fully. It just pick partial values and proceeds. I want actualArray to have values only after populateArray is fully resolved.

Upvotes: 5

Views: 5466

Answers (3)

Rosen Mihaylov
Rosen Mihaylov

Reputation: 1427

Since .each() can be chained - you can chain a .then and just type the code you need to execute after the .each() process is done:


static populateArray(){
    let arr = []

    cy.xpath(NODE_PREVIEW_PANEL).children(NODE_TYPE)
        .each((element, index, list) => arr.push(arr.push(element.attr('data-testid')))
            .then(list => {
                cy.wrap(arr).as('actualArray')
            })
}

And in test code

populateArray()
cy.get('@actualArray')
    .then(actualArray => {
        //code that needs the array data
    })

Upvotes: 3

Rosen Mihaylov
Rosen Mihaylov

Reputation: 1427

Another answer using custom commands

Cypress.Commands.add("populateArray", (parentSelector, childSelector, arrayAllias) => {
    let arr = []

    cy.xpath(parentSelector).children(childSelector)
        .each((element, index, list) => arr.push(element.attr('data-testid')))
        .then(()=>{
            cy.wrap(arr).as(arrayAllias)
        })
})

And in test code

cy.populateArray(NODE_PREVIEW_PANEL, NODE_TYPE, 'actualArray')
cy.get('@actualArray')
    .then(actualArray => {
        //code that needs the array data
    })

Upvotes: 0

user8745435
user8745435

Reputation:

How about using Cypress.Promise? From the docs

Cypress is promise aware so if you return a promise from inside of commands like .then(), Cypress will not continue until those promises resolve

const populateArray = () => {
  return new Cypress.Promise((resolve, reject) => {
    let arr = []
    cy.xpath('//ul')
      .children('li')
      .each(element => arr.push(element.attr('data-testid'))) // NOTE different push
      .then(() => {
        return resolve(arr)
      })
  })
}

Call with await (test must be async),

it('gets the array', async () => {

  const actualArray = await ArticlePage.populateArray();
  expect(actualArray).to.deep.equal(['1', '2', '3']);  // whatever is in 'data-testid'

})

Upvotes: 4

Related Questions