async function _navigation(navigationContext) {
  if (!navigationContext.resolvedConfig.artifacts) {
    throw new Error('No artifacts were defined on the config');
  }

  const artifactState = getEmptyArtifactState();
  const phaseState = {
    url: await navigationContext.driver.url(),
    gatherMode: /** @type {const} */ ('navigation'),
    driver: navigationContext.driver,
    page: navigationContext.page,
    computedCache: navigationContext.computedCache,
    artifactDefinitions: navigationContext.resolvedConfig.artifacts,
    artifactState,
    baseArtifacts: navigationContext.baseArtifacts,
    settings: navigationContext.resolvedConfig.settings,
  };

  const disableAsyncStacks =
    await prepare.enableAsyncStacks(navigationContext.driver.defaultSession);

  await collectPhaseArtifacts({phase: 'startInstrumentation', ...phaseState});
  await collectPhaseArtifacts({phase: 'startSensitiveInstrumentation', ...phaseState});
  const navigateResult = await _navigate(navigationContext);

  // Every required url is initialized to an empty string in `getBaseArtifacts`.
  // If we haven't set all the required urls yet, set them here.
  if (!Object.values(phaseState.baseArtifacts.URL).every(Boolean)) {
    phaseState.baseArtifacts.URL = {
      requestedUrl: navigateResult.requestedUrl,
      mainDocumentUrl: navigateResult.mainDocumentUrl,
      finalDisplayedUrl: await navigationContext.driver.url(),
    };
  }
  phaseState.url = navigateResult.mainDocumentUrl;

  await collectPhaseArtifacts({phase: 'stopSensitiveInstrumentation', ...phaseState});
  await collectPhaseArtifacts({phase: 'stopInstrumentation', ...phaseState});

  // bf-cache-failures can emit `Page.frameNavigated` at the end of the run.
  // This can cause us to issue protocol commands after the target closes.
  // We should disable our `Page.frameNavigated` handlers before that.
  await disableAsyncStacks();

  await _cleanupNavigation(navigationContext);

  return _computeNavigationResult(navigationContext, phaseState, navigateResult);
}
@param {NavigationContext} navigationContext
@return {ReturnType<typeof _computeNavigationResult>}