import type { DieFn, NextFn } from '../pipe/Pipe'; import { Pipeline } from './Pipeline'; import { Step } from './Step'; import type { TestLogs } from './TestLogs'; // This module needs tests const sequence = (steps: Step[]): Step => Step.raw((value, next, die, initLogs: TestLogs) => { Pipeline.async(value, steps, next, die, initLogs); }); const repeat = (amount: number, step: Step): Step[] => { const steps: Step[] = []; for (let i = 0; i < amount; i++) { steps.push(step); } return steps; }; const sequenceRepeat = (amount: number, step: Step): Step => { const steps = repeat(amount, step); return sequence(steps); }; // TODO deprecate? This function is weird and we don't seem to use it. const repeatUntil = (label: string, repeatStep: Step, successStep: Step, numAttempts: number): Step => Step.raw((value: T, next: NextFn, die: DieFn, logs: TestLogs) => { const again = (num: number) => { if (num <= 0) { die(label + '\nRan out of attempts', logs); } else { repeatStep.runStep(value, () => { // Any fancy setting of log here? Or ignore previous attempts? successStep.runStep(value, next, () => { again(num - 1); }, logs); }, die, logs); } }; again(numAttempts); }); const waitForPredicate = (label: string, interval: number, amount: number, predicate: () => boolean): Step => Step.async((next, die) => { if (predicate()) { // Must use a setTimeout here otherwise FontSizeTest gets 'too much recursion' on Firefox setTimeout(() => { next(); }); return; } let counter = 0; const timer = setInterval(() => { counter += interval; try { if (predicate()) { clearInterval(timer); next(); return; } } catch (err) { clearInterval(timer); die(err); return; } if (counter > amount) { clearInterval(timer); die('Waited for ' + label + ' for ' + amount + '(' + counter + '/' + interval + ') ms. Predicate condition failed.'); } }, interval); }); export { sequence, repeatUntil, waitForPredicate, repeat, sequenceRepeat };