Repository: GoogleChrome/lighthouse
Pull request #12849 (2021-08-03 17:00:50)

core(emulation): bump chrome versions
nothing special. just been a while since one of these.


Patch:
diff --git a/.github/workflows/smoke.yml b/.github/workflows/smoke.yml
index 87bb4362f..8db90bf53 100644
--- a/.github/workflows/smoke.yml
+++ b/.github/workflows/smoke.yml
@@ -88,6 +88,29 @@ jobs:
     # Fail if any changes were written to source files.
     - run: git diff --exit-code
 
+  smoke-fr:
+    runs-on: ubuntu-latest
+    name: Fraggle Rock
+
+    steps:
+    - name: git clone
+      uses: actions/checkout@v2
+
+    - name: Use Node.js 12.x
+      uses: actions/setup-node@v1
+      with:
+        node-version: 12.x
+
+    - run: yarn install --frozen-lockfile --network-timeout 1000000
+    - run: yarn build-report
+
+    - run: sudo apt-get install xvfb
+    - name: yarn smoke --fraggle-rock
+      run: xvfb-run --auto-servernum yarn smoke --debug --fraggle-rock -j=1 --retries=2 a11y lantern seo-passing seo-failing csp
+
+    # Fail if any changes were written to source files.
+    - run: git diff --exit-code
+
   smoke-bundle:
     runs-on: ubuntu-latest
     name: Bundled Lighthouse
diff --git a/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js b/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js
index 4935e24f1..3b428d994 100644
--- a/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js
+++ b/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js
@@ -114,11 +114,25 @@ class UnusedBytes extends Audit {
       devtoolsLog,
       settings,
     };
-
     const networkRecords = await NetworkRecords.request(devtoolsLog, context);
+
+    // Requesting load simulator requires non-empty network records.
+    // Timespans are not guaranteed to have any network activity.
+    // There are no bytes to be saved if no bytes were downloaded, so mark N/A if empty.
+    if (!networkRecords.length && gatherContext.gatherMode === 'timespan') {
+      return {
+        score: 1,
+        notApplicable: true,
+      };
+    }
+
     const [result, graph, simulator] = await Promise.all([
       this.audit_(artifacts, networkRecords, context),
-      PageDependencyGraph.request({trace, devtoolsLog}, context),
+      // Page dependency graph is only used in navigation mode.
+      // TODO(FR-COMPAT): Use dependency graph in timespan mode.
+      gatherContext.gatherMode === 'navigation' ?
+        PageDependencyGraph.request({trace, devtoolsLog}, context) :
+        null,
       LoadSimulator.request(simulatorOptions, context),
     ]);
 
@@ -200,7 +214,7 @@ class UnusedBytes extends Audit {
 
   /**
    * @param {ByteEfficiencyProduct} result
-   * @param {Node} graph
+   * @param {Node|null} graph
    * @param {Simulator} simulator
    * @param {LH.Artifacts['GatherContext']} gatherContext
    * @return {LH.Audit.Product}
@@ -209,11 +223,16 @@ class UnusedBytes extends Audit {
     const results = result.items.sort((itemA, itemB) => itemB.wastedBytes - itemA.wastedBytes);
 
     const wastedBytes = results.reduce((sum, item) => sum + item.wastedBytes, 0);
-    const wastedMs = gatherContext.gatherMode === 'navigation' ?
-      this.computeWasteWithTTIGraph(results, graph, simulator, {
+
+    let wastedMs;
+    if (gatherContext.gatherMode === 'navigation') {
+      if (!graph) throw Error('Page dependency graph should always be computed in navigation mode');
+      wastedMs = this.computeWasteWithTTIGraph(results, graph, simulator, {
         providedWastedBytesByUrl: result.wastedBytesByUrl,
-      }) :
-      this.computeWastedMsWithThroughput(wastedBytes, simulator);
+      });
+    } else {
+      wastedMs = this.computeWastedMsWithThroughput(wastedBytes, simulator);
+    }
 
     let displayValue = result.displayValue || '';
     if (typeof result.displayValue === 'undefined' && wastedBytes) {
diff --git a/lighthouse-core/audits/network-rtt.js b/lighthouse-core/audits/network-rtt.js
index 7a789776f..3b35357b1 100644
--- a/lighthouse-core/audits/network-rtt.js
+++ b/lighthouse-core/audits/network-rtt.js
@@ -7,6 +7,7 @@
 
 const Audit = require('./audit.js');
 const i18n = require('../lib/i18n/i18n.js');
+const NetworkRecords = require('../computed/network-records.js');
 const NetworkAnalysisComputed = require('../computed/network-analysis.js');
 
 const UIStrings = {
@@ -41,6 +42,14 @@ class NetworkRTT extends Audit {
    */
   static async audit(artifacts, context) {
     const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
+    const records = await NetworkRecords.request(devtoolsLog, context);
+    if (!records.length) {
+      return {
+        score: 1,
+        notApplicable: true,
+      };
+    }
+
     const analysis = await NetworkAnalysisComputed.request(devtoolsLog, context);
 
     /** @type {number} */
diff --git a/lighthouse-core/audits/network-server-latency.js b/lighthouse-core/audits/network-server-latency.js
index 9fac7d8ae..f7a849778 100644
--- a/lighthouse-core/audits/network-server-latency.js
+++ b/lighthouse-core/audits/network-server-latency.js
@@ -7,6 +7,7 @@
 
 const Audit = require('./audit.js');
 const i18n = require('../lib/i18n/i18n.js');
+const NetworkRecords = require('../computed/network-records.js');
 const NetworkAnalysisComputed = require('../computed/network-analysis.js');
 
 const UIStrings = {
@@ -41,6 +42,14 @@ class NetworkServerLatency extends Audit {
    */
   static async audit(artifacts, context) {
     const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
+    const records = await NetworkRecords.request(devtoolsLog, context);
+    if (!records.length) {
+      return {
+        score: 1,
+        notApplicable: true,
+      };
+    }
+
     const analysis = await NetworkAnalysisComputed.request(devtoolsLog, context);
 
     /** @type {number} */
diff --git a/lighthouse-core/config/constants.js b/lighthouse-core/config/constants.js
index 5a31a555c..c2e4aebe8 100644
--- a/lighthouse-core/config/constants.js
+++ b/lighthouse-core/config/constants.js
@@ -82,9 +82,9 @@ const screenEmulationMetrics = {
 };
 
 // eslint-disable-next-line max-len
-const MOTOG4_USERAGENT = 'Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4420.0 Mobile Safari/537.36 Chrome-Lighthouse';
+const MOTOG4_USERAGENT = 'Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse';
 // eslint-disable-next-line max-len
-const DESKTOP_USERAGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4420.0 Safari/537.36 Chrome-Lighthouse';
+const DESKTOP_USERAGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4590.2 Safari/537.36 Chrome-Lighthouse';
 
 const userAgents = {
   mobile: MOTOG4_USERAGENT,
diff --git a/lighthouse-core/fraggle-rock/config/filters.js b/lighthouse-core/fraggle-rock/config/filters.js
index 5af6323fd..657b590ea 100644
--- a/lighthouse-core/fraggle-rock/config/filters.js
+++ b/lighthouse-core/fraggle-rock/config/filters.js
@@ -24,6 +24,10 @@ const baseArtifactKeys = Object.keys(baseArtifactKeySource);
 // Keep these audits unless they are *directly* skipped with `skipAudits`.
 const filterResistantAuditIds = ['full-page-screenshot'];
 
+// Some artifacts are used by the report for additional information.
+// Always run these artifacts even if audits do not request them.
+const filterResistantArtifactIds = ['HostUserAgent', 'HostFormFactor', 'Stacks', 'GatherContext'];
+
 /**
  * Returns the set of audit IDs used in the list of categories.
  * If `onlyCategories` is not set, this function returns the list of all audit IDs across all
@@ -56,9 +60,10 @@ function filterArtifactsByAvailableAudits(artifacts, audits) {
   const artifactsById = new Map(artifacts.map(artifact => [artifact.id, artifact]));
 
   /** @type {Set<string>} */
-  const artifactIdsToKeep = new Set(
-    audits.flatMap(audit => audit.implementation.meta.requiredArtifacts)
-  );
+  const artifactIdsToKeep = new Set([
+    ...filterResistantArtifactIds,
+    ...audits.flatMap(audit => audit.implementation.meta.requiredArtifacts),
+  ]);
 
   // Keep all artifacts in the dependency tree of required artifacts.
   // Iterate through all kept artifacts, adding their dependencies along the way, until the set does not change.
diff --git a/types/smokehouse.d.ts b/types/smokehouse.d.ts
index 4526dd5b0..7b7328dd4 100644
--- a/types/smokehouse.d.ts
+++ b/types/smokehouse.d.ts
@@ -43,11 +43,13 @@
     {expectations: Smokehouse.ExpectedRunnerResult | Array<Smokehouse.ExpectedRunnerResult>}
 
   export type LighthouseRunner =
-    (url: string, configJson?: LH.Config.Json, runnerOptions?: {isDebug?: boolean}) => Promise<{lhr: LH.Result, artifacts: LH.Artifacts, log: string}>;
+    (url: string, configJson?: LH.Config.Json, runnerOptions?: {isDebug?: boolean; useFraggleRock?: boolean}) => Promise<{lhr: LH.Result, artifacts: LH.Artifacts, log: string}>;
 
   export interface SmokehouseOptions {
     /** If true, performs extra logging from the test runs. */
     isDebug?: boolean;
+    /** If true, uses the new Fraggle Rock runner. */
+    useFraggleRock?: boolean;
     /** Manually set the number of jobs to run at once. `1` runs all tests serially. */
     jobs?: number;
     /** The number of times to retry failing tests before accepting. Defaults to 0. */


Test patch:
diff --git a/lighthouse-cli/test/cli/__snapshots__/index-test.js.snap b/lighthouse-cli/test/cli/__snapshots__/index-test.js.snap
index c6956674a..d39e349cc 100644
--- a/lighthouse-cli/test/cli/__snapshots__/index-test.js.snap
+++ b/lighthouse-cli/test/cli/__snapshots__/index-test.js.snap
@@ -1543,7 +1543,7 @@ Object {
     "budgets": null,
     "channel": "cli",
     "disableStorageReset": false,
-    "emulatedUserAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4420.0 Mobile Safari/537.36 Chrome-Lighthouse",
+    "emulatedUserAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse",
     "extraHeaders": null,
     "formFactor": "mobile",
     "gatherMode": false,
@@ -1700,7 +1700,7 @@ Object {
     "budgets": null,
     "channel": "cli",
     "disableStorageReset": false,
-    "emulatedUserAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4420.0 Mobile Safari/537.36 Chrome-Lighthouse",
+    "emulatedUserAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse",
     "extraHeaders": null,
     "formFactor": "mobile",
     "gatherMode": false,
diff --git a/lighthouse-cli/test/cli/index-test.js b/lighthouse-cli/test/cli/index-test.js
index c8051a241..0a7b0f18b 100644
--- a/lighthouse-cli/test/cli/index-test.js
+++ b/lighthouse-cli/test/cli/index-test.js
@@ -111,7 +111,7 @@ describe('CLI Tests', function() {
       /* eslint-disable max-len */
       expect(emulationSettings).toMatchInlineSnapshot(`
         Object {
-          "emulatedUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4420.0 Safari/537.36 Chrome-Lighthouse",
+          "emulatedUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4590.2 Safari/537.36 Chrome-Lighthouse",
           "formFactor": "desktop",
           "screenEmulation": Object {
             "deviceScaleFactor": 1,
diff --git a/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js b/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js
index 4b5c9070b..f33eed2f8 100644
--- a/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js
+++ b/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js
@@ -127,6 +127,11 @@ async function begin() {
         default: false,
         describe: 'Save test artifacts and output verbose logs',
       },
+      'fraggle-rock': {
+        type: 'boolean',
+        default: false,
+        describe: 'Use the new Fraggle Rock runner',
+      },
       'jobs': {
         type: 'number',
         alias: 'j',
@@ -191,7 +196,14 @@ async function begin() {
     }
 
     const prunedTestDefns = pruneExpectedNetworkRequests(testDefns, takeNetworkRequestUrls);
-    const options = {jobs, retries, isDebug: argv.debug, lighthouseRunner, takeNetworkRequestUrls};
+    const options = {
+      jobs,
+      retries,
+      isDebug: argv.debug,
+      useFraggleRock: argv.fraggleRock,
+      lighthouseRunner,
+      takeNetworkRequestUrls,
+    };
 
     isPassing = (await runSmokehouse(prunedTestDefns, options)).success;
   } finally {
diff --git a/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js b/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js
index f00ca6beb..45adee7e0 100644
--- a/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js
+++ b/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js
@@ -27,27 +27,42 @@ const ChildProcessError = require('../lib/child-process-error.js');
  * Launch Chrome and do a full Lighthouse run via the Lighthouse CLI.
  * @param {string} url
  * @param {LH.Config.Json=} configJson
- * @param {{isDebug?: boolean}=} testRunnerOptions
+ * @param {{isDebug?: boolean, useFraggleRock?: boolean}=} testRunnerOptions
  * @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts, log: string}>}
  */
 async function runLighthouse(url, configJson, testRunnerOptions = {}) {
   const tmpPath = await fs.mkdtemp(`${os.tmpdir()}/smokehouse-`);
 
   const {isDebug} = testRunnerOptions;
-  return internalRun(url, tmpPath, configJson, isDebug)
+  return internalRun(url, tmpPath, configJson, testRunnerOptions)
     // Wait for internalRun() before removing scratch directory.
     .finally(() => !isDebug && fs.rmdir(tmpPath, {recursive: true}));
 }
 
+/**
+ * @param {LH.Config.Json=} configJson
+ * @return {LH.Config.Json|undefined}
+ */
+function convertToFraggleRockConfig(configJson) {
+  if (!configJson) return configJson;
+  if (!configJson.passes) return configJson;
+
+  return {
+    ...configJson,
+    navigations: configJson.passes.map(pass => ({...pass, id: pass.passName})),
+  };
+}
+
 /**
  * Internal runner.
  * @param {string} url
  * @param {string} tmpPath
  * @param {LH.Config.Json=} configJson
- * @param {boolean=} isDebug
+ * @param {{isDebug?: boolean, useFraggleRock?: boolean}=} options
  * @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts, log: string}>}
  */
-async function internalRun(url, tmpPath, configJson, isDebug) {
+async function internalRun(url, tmpPath, configJson, options) {
+  const {isDebug = false, useFraggleRock = false} = options || {};
   const localConsole = new LocalConsole();
 
   const outputPath = `${tmpPath}/smokehouse.report.json`;
@@ -64,6 +79,11 @@ async function internalRun(url, tmpPath, configJson, isDebug) {
     '--port=0',
   ];
 
+  if (useFraggleRock) {
+    args.push('--fraggle-rock');
+    configJson = convertToFraggleRockConfig(configJson);
+  }
+
   // Config can be optionally provided.
   if (configJson) {
     const configPath = `${tmpPath}/config.json`;
diff --git a/lighthouse-cli/test/smokehouse/smokehouse.js b/lighthouse-cli/test/smokehouse/smokehouse.js
index dec9c9120..698508282 100644
--- a/lighthouse-cli/test/smokehouse/smokehouse.js
+++ b/lighthouse-cli/test/smokehouse/smokehouse.js
@@ -41,6 +41,7 @@ const DEFAULT_RETRIES = 0;
 async function runSmokehouse(smokeTestDefns, smokehouseOptions) {
   const {
     isDebug,
+    useFraggleRock,
     jobs = DEFAULT_CONCURRENT_RUNS,
     retries = DEFAULT_RETRIES,
     lighthouseRunner = cliLighthouseRunner,
@@ -52,7 +53,7 @@ async function runSmokehouse(smokeTestDefns, smokehouseOptions) {
   // Run each testDefn in parallel based on the concurrencyLimit.
   const concurrentMapper = new ConcurrentMapper();
 
-  const testOptions = {isDebug, retries, lighthouseRunner, takeNetworkRequestUrls};
+  const testOptions = {isDebug, useFraggleRock, retries, lighthouseRunner, takeNetworkRequestUrls};
   const smokePromises = smokeTestDefns.map(testDefn => {
     // If defn is set to `runSerially`, we'll run it in succession with other tests, not parallel.
     const concurrency = testDefn.runSerially ? 1 : jobs;
@@ -108,12 +109,12 @@ function purpleify(str) {
 /**
  * Run Lighthouse in the selected runner.
  * @param {Smokehouse.TestDfn} smokeTestDefn
- * @param {{isDebug?: boolean, retries: number, lighthouseRunner: Smokehouse.LighthouseRunner, takeNetworkRequestUrls?: () => string[]}} testOptions
+ * @param {{isDebug?: boolean, useFraggleRock?: boolean, retries: number, lighthouseRunner: Smokehouse.LighthouseRunner, takeNetworkRequestUrls?: () => string[]}} testOptions
  * @return {Promise<SmokehouseResult>}
  */
 async function runSmokeTest(smokeTestDefn, testOptions) {
   const {id, config: configJson, expectations} = smokeTestDefn;
-  const {lighthouseRunner, retries, isDebug, takeNetworkRequestUrls} = testOptions;
+  const {lighthouseRunner, retries, isDebug, useFraggleRock, takeNetworkRequestUrls} = testOptions;
   const requestedUrl = expectations.lhr.requestedUrl;
 
   console.log(`${purpleify(id)} smoketest starting…`);
@@ -131,7 +132,7 @@ async function runSmokeTest(smokeTestDefn, testOptions) {
     // Run Lighthouse.
     try {
       result = {
-        ...await lighthouseRunner(requestedUrl, configJson, {isDebug}),
+        ...await lighthouseRunner(requestedUrl, configJson, {isDebug, useFraggleRock}),
         networkRequests: takeNetworkRequestUrls ? takeNetworkRequestUrls() : undefined,
       };
     } catch (e) {
diff --git a/lighthouse-core/test/audits/byte-efficiency/byte-efficiency-audit-test.js b/lighthouse-core/test/audits/byte-efficiency/byte-efficiency-audit-test.js
index e02554528..e29629bd5 100644
--- a/lighthouse-core/test/audits/byte-efficiency/byte-efficiency-audit-test.js
+++ b/lighthouse-core/test/audits/byte-efficiency/byte-efficiency-audit-test.js
@@ -148,6 +148,15 @@ describe('Byte efficiency base audit', () => {
     });
   });
 
+  it('should not throw on invalid graph in timespan mode', () => {
+    assert.doesNotThrow(() => {
+      ByteEfficiencyAudit.createAuditProduct({
+        headings: baseHeadings,
+        items: [{wastedBytes: 350, totalBytes: 700, wastedPercent: 50}],
+      }, null, simulator, {gatherMode: 'timespan'});
+    });
+  });
+
   it('should populate KiB', () => {
     const result = ByteEfficiencyAudit.createAuditProduct({
       headings: baseHeadings,
@@ -329,4 +338,30 @@ describe('Byte efficiency base audit', () => {
     const result = await MockAudit.audit(artifacts, {settings, computedCache});
     expect(result.details.overallSavingsMs).toBeCloseTo(914.2695);
   });
+
+  it('should return n/a if no network records in timespan mode', async () => {
+    class MockAudit extends ByteEfficiencyAudit {
+      static audit_(artifacts, records) {
+        return {
+          items: records,
+          headings: [],
+        };
+      }
+    }
+
+    const artifacts = {
+      GatherContext: {gatherMode: 'timespan'},
+      traces: {defaultPass: trace},
+      devtoolsLogs: {defaultPass: []},
+    };
+    const computedCache = new Map();
+
+    const modestThrottling = {rttMs: 150, throughputKbps: 1000, cpuSlowdownMultiplier: 2};
+    const settings = {throttlingMethod: 'simulate', throttling: modestThrottling};
+    const result = await MockAudit.audit(artifacts, {settings, computedCache});
+    expect(result).toEqual({
+      notApplicable: true,
+      score: 1,
+    });
+  });
 });
diff --git a/lighthouse-core/test/audits/network-rtt-test.js b/lighthouse-core/test/audits/network-rtt-test.js
index a470c4229..bbdcda171 100644
--- a/lighthouse-core/test/audits/network-rtt-test.js
+++ b/lighthouse-core/test/audits/network-rtt-test.js
@@ -32,4 +32,14 @@ describe('Network RTT audit', () => {
       },
     ]);
   });
+
+  it('should return n/a if no network records', async () => {
+    const artifacts = {devtoolsLogs: {defaultPass: []}};
+    const result = await NetworkRTT.audit(artifacts, {computedCache: new Map()});
+
+    expect(result).toEqual({
+      notApplicable: true,
+      score: 1,
+    });
+  });
 });
diff --git a/lighthouse-core/test/audits/network-server-latency-test.js b/lighthouse-core/test/audits/network-server-latency-test.js
index 059be9f4d..621b53112 100644
--- a/lighthouse-core/test/audits/network-server-latency-test.js
+++ b/lighthouse-core/test/audits/network-server-latency-test.js
@@ -36,4 +36,14 @@ describe('Network Server Latency audit', () => {
       },
     ]);
   });
+
+  it('should return n/a if no network records', async () => {
+    const artifacts = {devtoolsLogs: {defaultPass: []}};
+    const result = await ServerLatency.audit(artifacts, {computedCache: new Map()});
+
+    expect(result).toEqual({
+      notApplicable: true,
+      score: 1,
+    });
+  });
 });
diff --git a/lighthouse-core/test/fraggle-rock/api-test-pptr.js b/lighthouse-core/test/fraggle-rock/api-test-pptr.js
index 55c68b311..5d7a4979e 100644
--- a/lighthouse-core/test/fraggle-rock/api-test-pptr.js
+++ b/lighthouse-core/test/fraggle-rock/api-test-pptr.js
@@ -174,11 +174,11 @@ describe('Fraggle Rock API', () => {
       const {auditResults, erroredAudits, notApplicableAudits} = getAuditsBreakdown(result.lhr);
       expect(auditResults.length).toMatchInlineSnapshot(`50`);
 
-      expect(notApplicableAudits.length).toMatchInlineSnapshot(`9`);
+      expect(notApplicableAudits.length).toMatchInlineSnapshot(`22`);
       expect(notApplicableAudits.map(audit => audit.id)).toContain('server-response-time');
 
       // TODO(FR-COMPAT): Reduce this number by handling the error, making N/A, or removing timespan support.
-      expect(erroredAudits.length).toMatchInlineSnapshot(`14`);
+      expect(erroredAudits.length).toMatchInlineSnapshot(`1`);
     });
   });
 
diff --git a/lighthouse-core/test/results/artifacts/artifacts.json b/lighthouse-core/test/results/artifacts/artifacts.json
index cba3a2af3..22cfda77f 100644
--- a/lighthouse-core/test/results/artifacts/artifacts.json
+++ b/lighthouse-core/test/results/artifacts/artifacts.json
@@ -28,7 +28,7 @@
     "gatherMode": "lighthouse-core/test/results/artifacts",
     "disableStorageReset": false,
     "formFactor": "mobile",
-    "emulatedUserAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4420.0 Mobile Safari/537.36 Chrome-Lighthouse",
+    "emulatedUserAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse",
     "screenEmulation": {
       "deviceScaleFactor": 2.625,
       "height": 640,
diff --git a/lighthouse-core/test/results/sample_v2.json b/lighthouse-core/test/results/sample_v2.json
index 8890acad5..7c45fafa6 100644
--- a/lighthouse-core/test/results/sample_v2.json
+++ b/lighthouse-core/test/results/sample_v2.json
@@ -4815,7 +4815,7 @@
       "deviceScaleFactor": 2.625,
       "disabled": false
     },
-    "emulatedUserAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4420.0 Mobile Safari/537.36 Chrome-Lighthouse",
+    "emulatedUserAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse",
     "auditMode": true,
     "gatherMode": false,
     "disableStorageReset": false,
@@ -8713,4 +8713,4 @@
       }
     }
   ]
-}
\ No newline at end of file
+}