When using `Promise.all` to get multiple elements in Cypress, same last element is returned
See original GitHub issue- Operating System: Mac
- Cypress Version: 1.0.3
- Browser Version: built-in
Is this a Feature or Bug?
Bug
Test code
Repo https://github.com/bahmutov/cypress-promise-all-test
Problem
We can get multiple promises resolved in parallel, this code works as expected
it('works with values', () => {
Cypress.Promise.all([
Promise.resolve('a'),
Promise.resolve('b')
]).then(([a, b]) => {
expect(a).to.equal('a')
expect(b).to.equal('b')
})
})
We can even spread results using built-in Bluebird promise spread
it('spreads resolved values', () => {
Cypress.Promise.all([
Promise.resolve('a'),
Promise.resolve('b')
]).spread((a, b) => {
expect(a).to.equal('a')
expect(b).to.equal('b')
})
})
But if any of the promises are Cypress chains of commands, then all values passed into array are the same - the last value. For example this test grabs navigation links from https://example.cypress.io/
First link should be “Commands” and the second link should be “Utilities”
it('grabs element values', () => {
cy.visit('https://example.cypress.io/')
const getNavCommands = () =>
cy.get('ul.nav')
.contains('Commands')
const getNavUtilities = () =>
cy.get('ul.nav')
.contains('Utilities')
// each works by itself
getNavCommands()
.should('be.visible')
getNavUtilities()
.should('be.visible')
// lets get both elements
Cypress.Promise.all([
getNavCommands(),
getNavUtilities()
]).then(([commands, utilities]) => {
console.log('got commands', commands.text())
console.log('got utilities', utilities.text())
// debugger
expect(utilities.text()).to.equal('Utilities')
expect(commands.text()).to.equal('Commands')
})
})
I can see that it really grabbed each link correctly during in the reporter


But the arguments commands
and utilities
are both “Utilities” elements

Also, the assertion is an unhandled promise itself - it fails but the test is green

only console shows the unresolved promise message

The tests are in https://github.com/bahmutov/cypress-promise-all-test
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:35 (8 by maintainers)
Summing up several solutions:
Note that @brian-mann’s solution isn’t correct due to how late-chaining of
.then
callbacks currently works in cypress, as can be tested below:❌
@bahmutov’s solution is correct, but disadvantage is you need to pass callbacks instead of commands directly. ✔️
Another solution is this, where you can pass commands directly:
✔️
(edit 19-03-23 → rewritten to fix issues)
but note, you can’t pass anotherFixed. You can now nest as you like:cy.all()
as an argument tocy.all()
(but that’s an edge case which you won’t do anyway).Yet another solution, definitely not recommended, is to wrap the commands into bluebird promise which (unlike native promise) somehow correctly resolves with the value yielded by cy command:
✔️
⚠️ Also, cypress will complain about you mixing promises and cy commands.
But beware: unlike the previous solutions, you can’t nest those, for some reason:
❌
@qoc-dkg you cannot race commands at the same time, and you’re not actually achieving anything here to be honest. If you want to aggregate an accumulation of command results you’d do something like this. Otherwise there’s nothing special - commands will run in serial and you don’t have to do anything to ensure they are awaited correctly.