async getArtifact(context) {
    const session = context.driver.defaultSession;
    const executionContext = context.driver.executionContext;
    const settings = context.settings;
    const lighthouseControlsEmulation = !settings.screenEmulation.disabled;

    // Make a copy so we don't modify the config settings.
    /** @type {{width: number, height: number, deviceScaleFactor: number, mobile: boolean}} */
    const deviceMetrics = {...settings.screenEmulation};

    try {
      if (!settings.usePassiveGathering) {
        // In case some other program is controlling emulation, remember what the device looks like now and reset after gatherer is done.
        // If we're gathering with mobile screenEmulation on (overlay scrollbars, etc), continue to use that for this screenshot.
        if (!lighthouseControlsEmulation) {
          const observedDeviceMetrics = await executionContext.evaluate(getObservedDeviceMetrics, {
            args: [],
            useIsolation: true,
            deps: [kebabCaseToCamelCase],
          });
          deviceMetrics.height = observedDeviceMetrics.height;
          deviceMetrics.width = observedDeviceMetrics.width;
          deviceMetrics.deviceScaleFactor = observedDeviceMetrics.deviceScaleFactor;
          // If screen emulation is disabled, use formFactor to determine if we are on mobile.
          deviceMetrics.mobile = settings.formFactor === 'mobile';
        }

        await this._resizeViewport(context, deviceMetrics);
      }

      // Issue both commands at once, to reduce the chance that the page changes between capturing
      // a screenshot and resolving the nodes. https://github.com/GoogleChrome/lighthouse/pull/14763
      const [screenshot, nodes] =
        await Promise.all([this._takeScreenshot(context), this._resolveNodes(context)]);
      return {
        screenshot,
        nodes,
      };
    } finally {
      if (!settings.usePassiveGathering) {
        // Revert resized page.
        if (lighthouseControlsEmulation) {
          await emulation.emulate(session, settings);
        } else {
          // Best effort to reset emulation to what it was.
          // https://github.com/GoogleChrome/lighthouse/pull/10716#discussion_r428970681
          // TODO: seems like this would be brittle. Should at least work for devtools, but what
          // about scripted puppeteer usages? Better to introduce a "setEmulation" callback
          // in the LH runner api, which for ex. puppeteer consumers would setup puppeteer emulation,
          // and then just call that to reset?
          // https://github.com/GoogleChrome/lighthouse/issues/11122
          await session.sendCommand('Emulation.setDeviceMetricsOverride', {
            mobile: deviceMetrics.mobile,
            deviceScaleFactor: deviceMetrics.deviceScaleFactor,
            height: deviceMetrics.height,
            width: 0, // Leave width unchanged
          });
        }
      }
    }
  }
@param {LH.Gatherer.Context} context
@return {Promise<LH.Artifacts['FullPageScreenshot']>}