Skip to content

Instantly share code, notes, and snippets.

@samtsai
Created April 18, 2022 18:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samtsai/687b117bf6de73a0aa2229b2b69aee1b to your computer and use it in GitHub Desktop.
Save samtsai/687b117bf6de73a0aa2229b2b69aee1b to your computer and use it in GitHub Desktop.
Typed `cy.all([...])` command for Cypress consumers
// @see https://github.com/cypress-io/cypress/issues/915#issuecomment-475862672
// Modified due to changes to `cy.queue` https://github.com/cypress-io/cypress/pull/17448
// Note: this DOES NOT run Promises in parallel like `Promise.all` due to the nature
// of Cypress promise-like objects and command queue. This only makes it convenient to use the same
// API but runs the commands sequentially.
declare namespace Cypress {
type ChainableValue<T> = T extends Cypress.Chainable<infer V> ? V : T
interface cy {
all<T extends Cypress.Chainable[] | []>(
commands: T
): Cypress.Chainable<{ [P in keyof T]: ChainableValue<T[P]> }>
queue: any
}
interface Chainable {
chainerId: string
}
}
const chainStart = Symbol("chainStart")
/**
* @description Returns a single Chainable that resolves when all of the Chainables pass.
* @param {Cypress.Chainable[]} commands - List of Cypress.Chainable to resolve.
* @returns {Cypress.Chainable} Cypress when all Chainables are resolved.
*/
cy.all = function all(commands): Cypress.Chainable {
const _ = Cypress._
// eslint-disable-next-line
const chain = cy.wrap(null, { log: false })
const stopCommand = _.find(cy.queue.get(), {
attributes: { chainerId: chain.chainerId },
})
const startCommand = _.find(cy.queue.get(), {
attributes: { chainerId: commands[0].chainerId },
})
const p = chain.then(() => {
return cy.wrap(
// @see https://lodash.com/docs/4.17.15#lodash
_(commands)
.map(cmd => {
return cmd[chainStart]
? cmd[chainStart].attributes
: _.find(cy.queue.get(), {
attributes: { chainerId: cmd.chainerId },
}).attributes
})
.concat(stopCommand.attributes)
.slice(1)
.flatMap(cmd => {
return cmd.prev.get("subject")
})
.value()
)
})
p[chainStart] = startCommand
return p
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment