async getArtifact(passContext) {
    const session = passContext.driver.defaultSession;

    /** @type {Map<string, LH.Crdp.CSS.CSSStyleSheetHeader>} */
    const stylesheets = new Map();
    /** @param {LH.Crdp.CSS.StyleSheetAddedEvent} sheet */
    const onStylesheetAdded = sheet => stylesheets.set(sheet.header.styleSheetId, sheet.header);
    session.on('CSS.styleSheetAdded', onStylesheetAdded);

    await Promise.all([
      session.sendCommand('DOMSnapshot.enable'),
      session.sendCommand('DOM.enable'),
      session.sendCommand('CSS.enable'),
    ]);

    // Get the computed font-size style of every node.
    const snapshot = await session.sendCommand('DOMSnapshot.captureSnapshot', {
      computedStyles: ['font-size', 'visibility'],
    });

    const {
      totalTextLength,
      failingTextLength,
      failingNodes,
    } = this.findFailingNodes(snapshot);
    const {
      analyzedFailingNodesData,
      analyzedFailingTextLength,
    } = await FontSize.fetchFailingNodeSourceRules(session, failingNodes);

    session.off('CSS.styleSheetAdded', onStylesheetAdded);

    // For the nodes whose computed style we could attribute to a stylesheet, assign
    // the stylsheet to the data.
    analyzedFailingNodesData
      .filter(data => data.cssRule?.styleSheetId)
      // @ts-expect-error - guaranteed to exist from the filter immediately above
      .forEach(data => (data.cssRule.stylesheet = stylesheets.get(data.cssRule.styleSheetId)));

    await Promise.all([
      session.sendCommand('DOMSnapshot.disable'),
      session.sendCommand('DOM.disable'),
      session.sendCommand('CSS.disable'),
    ]);

    return {
      analyzedFailingNodesData,
      analyzedFailingTextLength,
      failingTextLength,
      totalTextLength,
    };
  }
@param {LH.Gatherer.Context} passContext
@return {Promise<LH.Artifacts.FontSize>} font-size analysis