timestamp: getTimestamp()

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()) {