Reputation: 411
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
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
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
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