in src/core/runner.ts [113:218]
timestamp: getTimestamp(),
data: buffer.toString('base64'),
};
await writeFile(
join(this.#screenshotPath, fileName),
JSON.stringify(screenshot)
);
log(`Runner: captured screenshot for (${step.name})`);
} catch (_) {
// Screenshot may fail sometimes, log and continue.
log(`Runner: failed to capture screenshot for (${step.name})`);
}
}
_addHook(type: HookType, callback: HooksCallback) {
this.#hooks[type].push(callback);
}
/**
* @deprecated Since version Please do not rely on the internal methods.
* Alias _addHook for backwards compatibility
*/
addHook(type: HookType, callback: HooksCallback) {
this._addHook(type, callback);
}
private buildHookArgs() {
return {
env: this.config.environment,
params: this.config.params,
info: this as RunnerInfo,
};
}
_updateMonitor(config: MonitorConfig) {
if (!this.#monitor) {
this.#monitor = new Monitor(config);
return;
}
this.#monitor.update(config);
}
/**
* @deprecated Since version Please do not rely on the internal methods.
* Alias _addJourney for backwards compatibility
*/
updateMonitor(config: MonitorConfig) {
this._updateMonitor(config);
}
_addJourney(journey: Journey) {
this.#journeys.push(journey);
this.#currentJourney = journey;
}
/**
* @deprecated Since version 1.17.0. Please do not rely on the internal methods.
* Alias _addJourney for backwards compatibility
*/
addJourney(journey: Journey) {
this._addJourney(journey);
}
private setReporter(options: RunOptions) {
/**
* Set up the corresponding reporter and fallback
* to default reporter if not provided
*/
const { reporter, outfd, dryRun } = options;
const Reporter =
typeof reporter === 'function'
? reporter
: reporters[reporter] || reporters['default'];
this.#reporter = new Reporter({ fd: outfd, dryRun });
}
async #runBeforeAllHook(args: HooksArgs) {
log(`Runner: beforeAll hooks`);
await runParallel(this.#hooks.beforeAll, args);
}
async #runAfterAllHook(args: HooksArgs) {
log(`Runner: afterAll hooks`);
await runParallel(this.#hooks.afterAll, args);
}
async #runBeforeHook(journey: Journey, args: HooksArgs) {
log(`Runner: before hooks for (${journey.name})`);
await runParallel(journey._getHook('before'), args);
}
async #runAfterHook(journey: Journey, args: HooksArgs) {
log(`Runner: after hooks for (${journey.name})`);
await runParallel(journey._getHook('after'), args);
}
async #runStep(step: Step, options: RunOptions): Promise<StepResult> {
log(`Runner: start step (${step.name})`);
const { metrics, screenshots, filmstrips, trace } = options;
/**
* URL needs to be the first navigation request of any step
* Listening for request solves the case where `about:blank` would be
* reported for failed navigations
*/
const captureUrl = req => {
if (!step.url && req.isNavigationRequest()) {