UNPKG

cypress-recurse

Version:

A way to re-run Cypress commands until a predicate function returns true

208 lines (194 loc) 5.33 kB
/// <reference types="cypress" /> /** * Data about the current iteration passed to the user log function. */ interface LogData<T> { /** * The value produced by the current iteration */ value: T /** * The current iteration successfully passed the predicate check */ successful: boolean /** * Current iteration */ iteration: number /** * Remaining number of iterations allowed */ limit: number /** * Elapsed number of milliseconds */ elapsed: number /** * Human elapsed duration, like "2 seconds" */ elapsedDuration: string } export type LogOption<T> = | boolean | string | ((arg: T, data: LogData<T>) => void) interface PostFunctionOptions<T> { /** * Current iteration */ iteration: number /** * The value produced by the last iteration */ value: T /** * The remaining number of iterations */ limit: number /** * The current reduced value, if any */ reduced: any /** * Time since the recursion started, ms */ elapsed: number /** * Human-readable elapsed duration, like "5 seconds" */ elapsedDuration: string /** * Result of the predicate function, * is false for all but the last values */ success: boolean } type PostFunction<T> = ( opts: PostFunctionOptions<T>, ) => void | Cypress.Chainable interface RecurseOptions<T> { /** * The max number of iterations */ limit: number /** * In milliseconds */ timeout: number /** * Log to Command Log, could be true|false, * a message to be printed once at the end, * or a custom function * @example * // disable logging all attempts * cy.recurse(..., ..., { log: false }) * @example * // log just the message on success * cy.recurse(..., ..., { log: 'Done!' }) * @example * // log the successful value and iteration count * cy.recurse(..., ..., { log: (value, data) => { }) */ log: LogOption<T> /** * Between iterations, milliseconds */ delay: number /** * Function that can run additional Cypress commands after each iteration */ post?: PostFunction<T> /** * A synchronous function that receives the current value * and can return true to immediately throw an error. * You can return an error message to throw. * @example * // fail fast if the value is 42, use default error message * failFast: (value) => value === 42 * @example * // fail fast if the value is 42, use custom error message * failFast: (value) => value === 42 && 'Value cannot be 42' * @example * // fail fast and use the value in the error message * failFast: (value) => value > 10 && `Value ${value} cannot be larger than 10` */ failFast?: (value: T) => boolean | string /** * Call "post" with the last value during recursion, * default is false */ postLastValue?: boolean /** * Error message to display when timed out or max limit reached */ error?: string /** * Internal: tracks the timestamp of the very first iteration */ started?: number /** Internal: the current iteration count */ iteration?: number /** Internal: print the current options to Command Log */ debugLog?: boolean // options for accumulator /** Starting value for the accumulator */ reduceFrom: any /** * Update the accumulator with the given value, * synchronous function */ reduce(accumulator: any, item: T): any /** Include the last value in the accumulator */ reduceLastValue: boolean /** * What to yield to the next command, usually it is * the last value, but sometimes can be the accumulator. * If you need both, pass "both" and "reduce" will * yield an object with {value, reduced} properties */ yield: 'value' | 'reduced' | 'both' /** * When recursion ends, if the predicate is still false, * continue without failing the test */ doNotFail: boolean } /** * Recursively calls the given command until the predicate is true. * @param commandsFn Function running Cypress commands * @param checkFn Predicate that should return true to finish * @param options Options for maximum timeout, logging, etc */ export function recurse<T>( commandsFn: () => Cypress.Chainable<Promise<T>>, checkFn: ( x: T, reducedValue?: any, ) => boolean | void | Chai.Assertion, options?: Partial<RecurseOptions<T>>, ): Cypress.Chainable<T> export function recurse<T>( commandsFn: () => Cypress.Chainable<T>, checkFn: ( x: T, reducedValue?: any, ) => boolean | void | Chai.Assertion, options?: Partial<RecurseOptions<T>>, ): Cypress.Chainable<T> export const RecurseDefaults: RecurseOptions<any> export function each<T>( commandsFn: (x: T) => Cypress.Chainable<Promise<T>>, checkFn?: (x: T) => boolean | void | Chai.Assertion, ): Cypress.Chainable<T[]> export function each<T>( commandsFn: (x: T) => Cypress.Chainable<T>, checkFn?: (x: T) => boolean | void | Chai.Assertion, ): Cypress.Chainable<T> export function each( commandsFn: (x: any) => any | Cypress.Chainable<any>, checkFn?: (x: any) => boolean | void | Chai.Assertion, ): any | Cypress.Chainable<any | void | null> export function each( commandsFn: (x: any) => any, checkFn?: (x: any) => boolean | void | Chai.Assertion, ): Cypress.Chainable<any | void | null>