async function navigationGather(page, requestor, options = {}) {
  const {flags = {}, config} = options;
  log.setLevel(flags.logLevel || 'error');

  const {resolvedConfig} = await initializeConfig('navigation', config, flags);
  const computedCache = new Map();

  const isCallback = typeof requestor === 'function';

  const runnerOptions = {resolvedConfig, computedCache};

  const gatherFn = async () => {
    const normalizedRequestor = isCallback ? requestor : UrlUtils.normalizeUrl(requestor);

    /** @type {LH.Puppeteer.Browser|undefined} */
    let lhBrowser = undefined;
    /** @type {LH.Puppeteer.Page|undefined} */
    let lhPage = undefined;

    // For navigation mode, we shouldn't connect to a browser in audit mode,
    // therefore we connect to the browser in the gatherFn callback.
    if (!page) {
      const {hostname = DEFAULT_HOSTNAME, port = DEFAULT_PORT} = flags;
      lhBrowser = await puppeteer.connect({browserURL: `http://${hostname}:${port}`, defaultViewport: null});
      lhPage = await lhBrowser.newPage();
      page = lhPage;
    }

    const driver = new Driver(page);
    const context = {
      driver,
      lhBrowser,
      lhPage,
      page,
      resolvedConfig,
      requestor: normalizedRequestor,
      computedCache,
    };
    const {baseArtifacts} = await _setup(context);

    const artifacts = await _navigation({...context, baseArtifacts});

    await _cleanup(context);

    return finalizeArtifacts(baseArtifacts, artifacts);
  };
  const artifacts = await Runner.gather(gatherFn, runnerOptions);
  return {artifacts, runnerOptions};
}
@param {LH.Puppeteer.Page|undefined} page
@param {LH.NavigationRequestor|undefined} requestor
@param {{config?: LH.Config, flags?: LH.Flags}} [options]
@return {Promise<LH.Gatherer.GatherResult>}