lighthouse 9.4.0-dev.20220228 → 9.4.0-dev.20220303

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,6 +33,7 @@ import offlineReady from './test-definitions/offline-ready.js';
33
33
  import offlineSwBroken from './test-definitions/offline-sw-broken.js';
34
34
  import offlineSwSlow from './test-definitions/offline-sw-slow.js';
35
35
  import oopifRequests from './test-definitions/oopif-requests.js';
36
+ import oopifScripts from './test-definitions/oopif-scripts.js';
36
37
  import perfBudgets from './test-definitions/perf-budgets.js';
37
38
  import perfDebug from './test-definitions/perf-debug.js';
38
39
  import perfDiagnosticsAnimations from './test-definitions/perf-diagnostics-animations.js';
@@ -92,6 +93,7 @@ const smokeTests = [
92
93
  offlineSwBroken,
93
94
  offlineSwSlow,
94
95
  oopifRequests,
96
+ oopifScripts,
95
97
  perfBudgets,
96
98
  perfDebug,
97
99
  perfDiagnosticsAnimations,
@@ -13,11 +13,13 @@
13
13
 
14
14
  /* eslint-disable no-console */
15
15
 
16
- import cloneDeep from 'lodash.clonedeep';
16
+ import _ from 'lodash';
17
17
 
18
18
  import smokeTests from '../core-tests.js';
19
19
  import {runSmokehouse, getShardedDefinitions} from '../smokehouse.js';
20
20
 
21
+ const {cloneDeep} = _;
22
+
21
23
  /**
22
24
  * @param {Smokehouse.SmokehouseLibOptions} options
23
25
  */
@@ -17,7 +17,7 @@ import path from 'path';
17
17
  import fs from 'fs';
18
18
  import url from 'url';
19
19
 
20
- import cloneDeep from 'lodash.clonedeep';
20
+ import _ from 'lodash';
21
21
  import yargs from 'yargs';
22
22
  import * as yargsHelpers from 'yargs/helpers';
23
23
  import log from 'lighthouse-logger';
@@ -26,6 +26,8 @@ import {runSmokehouse, getShardedDefinitions} from '../smokehouse.js';
26
26
  import {updateTestDefnFormat} from './back-compat-util.js';
27
27
  import {LH_ROOT} from '../../../../root.js';
28
28
 
29
+ const {cloneDeep} = _;
30
+
29
31
  const coreTestDefnsPath =
30
32
  path.join(LH_ROOT, 'lighthouse-cli/test/smokehouse/core-tests.js');
31
33
 
@@ -10,11 +10,13 @@
10
10
  * against the results actually collected from Lighthouse.
11
11
  */
12
12
 
13
- import cloneDeep from 'lodash.clonedeep';
13
+ import _ from 'lodash';
14
14
  import log from 'lighthouse-logger';
15
15
 
16
16
  import {LocalConsole} from './lib/local-console.js';
17
17
 
18
+ const {cloneDeep} = _;
19
+
18
20
  /**
19
21
  * @typedef Difference
20
22
  * @property {string} path
@@ -197,7 +197,7 @@ class ScriptTreemapDataAudit extends Audit {
197
197
 
198
198
  nodes.push({
199
199
  name,
200
- resourceBytes: scriptElement.src.length,
200
+ resourceBytes: scriptElement.content?.length || 0,
201
201
  });
202
202
  continue;
203
203
  }
@@ -6,7 +6,7 @@
6
6
  'use strict';
7
7
 
8
8
  const path = require('path');
9
- const isDeepEqual = require('lodash.isequal');
9
+ const {isEqual: isDeepEqual} = require('lodash');
10
10
  const constants = require('./constants.js');
11
11
  const Budget = require('./budget.js');
12
12
  const ConfigPlugin = require('./config-plugin.js');
@@ -5,9 +5,11 @@
5
5
  */
6
6
  'use strict';
7
7
 
8
- const {snapshot} = require('./gather/snapshot-runner.js');
9
- const {startTimespan} = require('./gather/timespan-runner.js');
10
- const {navigation} = require('./gather/navigation-runner.js');
8
+ const {snapshotGather} = require('./gather/snapshot-runner.js');
9
+ const {startTimespanGather} = require('./gather/timespan-runner.js');
10
+ const {navigationGather} = require('./gather/navigation-runner.js');
11
+ const {generateFlowReportHtml} = require('../../report/generator/report-generator.js');
12
+ const Runner = require('../runner.js');
11
13
  const UserFlow = require('./user-flow.js');
12
14
 
13
15
  /**
@@ -18,9 +20,48 @@ async function startFlow(page, options) {
18
20
  return new UserFlow(page, options);
19
21
  }
20
22
 
23
+ /**
24
+ * @param {Parameters<navigationGather>} params
25
+ * @return {Promise<LH.RunnerResult|undefined>}
26
+ */
27
+ async function navigation(...params) {
28
+ const gatherResult = await navigationGather(...params);
29
+ return Runner.audit(gatherResult.artifacts, gatherResult.runnerOptions);
30
+ }
31
+
32
+ /**
33
+ * @param {Parameters<snapshotGather>} params
34
+ * @return {Promise<LH.RunnerResult|undefined>}
35
+ */
36
+ async function snapshot(...params) {
37
+ const gatherResult = await snapshotGather(...params);
38
+ return Runner.audit(gatherResult.artifacts, gatherResult.runnerOptions);
39
+ }
40
+
41
+ /**
42
+ * @param {Parameters<startTimespanGather>} params
43
+ * @return {Promise<{endTimespan: () => Promise<LH.RunnerResult|undefined>}>}
44
+ */
45
+ async function startTimespan(...params) {
46
+ const {endTimespanGather} = await startTimespanGather(...params);
47
+ const endTimespan = async () => {
48
+ const gatherResult = await endTimespanGather();
49
+ return Runner.audit(gatherResult.artifacts, gatherResult.runnerOptions);
50
+ };
51
+ return {endTimespan};
52
+ }
53
+
54
+ /**
55
+ * @param {LH.FlowResult} flowResult
56
+ */
57
+ async function generateFlowReport(flowResult) {
58
+ return generateFlowReportHtml(flowResult);
59
+ }
60
+
21
61
  module.exports = {
22
62
  snapshot,
23
63
  startTimespan,
24
64
  navigation,
25
65
  startFlow,
66
+ generateFlowReport,
26
67
  };
@@ -6,7 +6,7 @@
6
6
  'use strict';
7
7
 
8
8
  const log = require('lighthouse-logger');
9
- const isEqual = require('lodash.isequal');
9
+ const {isEqual} = require('lodash');
10
10
  const {
11
11
  getBrowserVersion,
12
12
  getBenchmarkIndex,
@@ -290,9 +290,9 @@ async function _cleanup({requestedUrl, driver, config}) {
290
290
  /**
291
291
  * @param {LH.NavigationRequestor} requestor
292
292
  * @param {{page: import('puppeteer').Page, config?: LH.Config.Json, configContext?: LH.Config.FRContext}} options
293
- * @return {Promise<LH.RunnerResult|undefined>}
293
+ * @return {Promise<LH.Gatherer.FRGatherResult>}
294
294
  */
295
- async function navigation(requestor, options) {
295
+ async function navigationGather(requestor, options) {
296
296
  const {page, configContext = {}} = options;
297
297
  log.setLevel(configContext.logLevel || 'error');
298
298
 
@@ -325,11 +325,11 @@ async function navigation(requestor, options) {
325
325
  },
326
326
  runnerOptions
327
327
  );
328
- return Runner.audit(artifacts, runnerOptions);
328
+ return {artifacts, runnerOptions};
329
329
  }
330
330
 
331
331
  module.exports = {
332
- navigation,
332
+ navigationGather,
333
333
  _setup,
334
334
  _setupNavigation,
335
335
  _navigate,
@@ -16,8 +16,11 @@ const {
16
16
  const {initializeConfig} = require('../config/config.js');
17
17
  const {getBaseArtifacts, finalizeArtifacts} = require('./base-artifacts.js');
18
18
 
19
- /** @param {{page: import('puppeteer').Page, config?: LH.Config.Json, configContext?: LH.Config.FRContext}} options */
20
- async function snapshot(options) {
19
+ /**
20
+ * @param {{page: import('puppeteer').Page, config?: LH.Config.Json, configContext?: LH.Config.FRContext}} options
21
+ * @return {Promise<LH.Gatherer.FRGatherResult>}
22
+ */
23
+ async function snapshotGather(options) {
21
24
  const {configContext = {}} = options;
22
25
  log.setLevel(configContext.logLevel || 'error');
23
26
 
@@ -57,9 +60,9 @@ async function snapshot(options) {
57
60
  },
58
61
  runnerOptions
59
62
  );
60
- return Runner.audit(artifacts, runnerOptions);
63
+ return {artifacts, runnerOptions};
61
64
  }
62
65
 
63
66
  module.exports = {
64
- snapshot,
67
+ snapshotGather,
65
68
  };
@@ -19,9 +19,9 @@ const {getBaseArtifacts, finalizeArtifacts} = require('./base-artifacts.js');
19
19
 
20
20
  /**
21
21
  * @param {{page: import('puppeteer').Page, config?: LH.Config.Json, configContext?: LH.Config.FRContext}} options
22
- * @return {Promise<{endTimespan(): Promise<LH.RunnerResult|undefined>}>}
22
+ * @return {Promise<{endTimespanGather(): Promise<LH.Gatherer.FRGatherResult>}>}
23
23
  */
24
- async function startTimespan(options) {
24
+ async function startTimespanGather(options) {
25
25
  const {configContext = {}} = options;
26
26
  log.setLevel(configContext.logLevel || 'error');
27
27
 
@@ -52,7 +52,7 @@ async function startTimespan(options) {
52
52
  await collectPhaseArtifacts({phase: 'startSensitiveInstrumentation', ...phaseOptions});
53
53
 
54
54
  return {
55
- async endTimespan() {
55
+ async endTimespanGather() {
56
56
  const finalUrl = await driver.url();
57
57
  phaseOptions.url = finalUrl;
58
58
 
@@ -72,11 +72,11 @@ async function startTimespan(options) {
72
72
  },
73
73
  runnerOptions
74
74
  );
75
- return Runner.audit(artifacts, runnerOptions);
75
+ return {artifacts, runnerOptions};
76
76
  },
77
77
  };
78
78
  }
79
79
 
80
80
  module.exports = {
81
- startTimespan,
81
+ startTimespanGather,
82
82
  };
@@ -6,13 +6,15 @@
6
6
  'use strict';
7
7
 
8
8
  const {generateFlowReportHtml} = require('../../report/generator/report-generator.js');
9
- const {snapshot} = require('./gather/snapshot-runner.js');
10
- const {startTimespan} = require('./gather/timespan-runner.js');
11
- const {navigation} = require('./gather/navigation-runner.js');
9
+ const {snapshotGather} = require('./gather/snapshot-runner.js');
10
+ const {startTimespanGather} = require('./gather/timespan-runner.js');
11
+ const {navigationGather} = require('./gather/navigation-runner.js');
12
+ const Runner = require('../runner.js');
12
13
 
13
- /** @typedef {Parameters<snapshot>[0]} FrOptions */
14
+ /** @typedef {Parameters<snapshotGather>[0]} FrOptions */
14
15
  /** @typedef {Omit<FrOptions, 'page'> & {name?: string}} UserFlowOptions */
15
16
  /** @typedef {Omit<FrOptions, 'page'> & {stepName?: string}} StepOptions */
17
+ /** @typedef {{gatherResult: LH.Gatherer.FRGatherResult, name: string}} StepArtifact */
16
18
 
17
19
  class UserFlow {
18
20
  /**
@@ -24,8 +26,8 @@ class UserFlow {
24
26
  this.options = {page, ...options};
25
27
  /** @type {string|undefined} */
26
28
  this.name = options?.name;
27
- /** @type {LH.FlowResult.Step[]} */
28
- this.steps = [];
29
+ /** @type {StepArtifact[]} */
30
+ this.stepArtifacts = [];
29
31
  }
30
32
 
31
33
  /**
@@ -38,12 +40,12 @@ class UserFlow {
38
40
  }
39
41
 
40
42
  /**
41
- * @param {LH.Result} lhr
43
+ * @param {LH.Artifacts} artifacts
42
44
  * @return {string}
43
45
  */
44
- _getDefaultStepName(lhr) {
45
- const shortUrl = this._shortenUrl(lhr.finalUrl);
46
- switch (lhr.gatherMode) {
46
+ _getDefaultStepName(artifacts) {
47
+ const shortUrl = this._shortenUrl(artifacts.URL.finalUrl);
48
+ switch (artifacts.GatherContext.gatherMode) {
47
49
  case 'navigation':
48
50
  return `Navigation report (${shortUrl})`;
49
51
  case 'timespan':
@@ -66,7 +68,8 @@ class UserFlow {
66
68
  }
67
69
 
68
70
  // On repeat navigations, we want to disable storage reset by default (i.e. it's not a cold load).
69
- const isSubsequentNavigation = this.steps.some(step => step.lhr.gatherMode === 'navigation');
71
+ const isSubsequentNavigation = this.stepArtifacts
72
+ .some(step => step.gatherResult.artifacts.GatherContext.gatherMode === 'navigation');
70
73
  if (isSubsequentNavigation) {
71
74
  if (settingsOverrides.disableStorageReset === undefined) {
72
75
  settingsOverrides.disableStorageReset = true;
@@ -84,85 +87,93 @@ class UserFlow {
84
87
  * @param {StepOptions=} stepOptions
85
88
  */
86
89
  async navigate(requestor, stepOptions) {
87
- if (this.currentTimespan) throw Error('Timespan already in progress');
90
+ if (this.currentTimespan) throw new Error('Timespan already in progress');
88
91
 
89
- const result = await navigation(
92
+ const gatherResult = await navigationGather(
90
93
  requestor,
91
94
  this._getNextNavigationOptions(stepOptions)
92
95
  );
93
- if (!result) throw Error('Navigation returned undefined');
94
96
 
95
97
  const providedName = stepOptions?.stepName;
96
- this.steps.push({
97
- lhr: result.lhr,
98
- name: providedName || this._getDefaultStepName(result.lhr),
98
+ this.stepArtifacts.push({
99
+ gatherResult,
100
+ name: providedName || this._getDefaultStepName(gatherResult.artifacts),
99
101
  });
100
102
 
101
- return result;
103
+ return gatherResult;
102
104
  }
103
105
 
104
106
  /**
105
107
  * @param {StepOptions=} stepOptions
106
108
  */
107
109
  async startTimespan(stepOptions) {
108
- if (this.currentTimespan) throw Error('Timespan already in progress');
110
+ if (this.currentTimespan) throw new Error('Timespan already in progress');
109
111
 
110
112
  const options = {...this.options, ...stepOptions};
111
- const timespan = await startTimespan(options);
113
+ const timespan = await startTimespanGather(options);
112
114
  this.currentTimespan = {timespan, options};
113
115
  }
114
116
 
115
117
  async endTimespan() {
116
- if (!this.currentTimespan) throw Error('No timespan in progress');
118
+ if (!this.currentTimespan) throw new Error('No timespan in progress');
117
119
 
118
120
  const {timespan, options} = this.currentTimespan;
119
- const result = await timespan.endTimespan();
121
+ const gatherResult = await timespan.endTimespanGather();
120
122
  this.currentTimespan = undefined;
121
- if (!result) throw Error('Timespan returned undefined');
122
123
 
123
124
  const providedName = options?.stepName;
124
- this.steps.push({
125
- lhr: result.lhr,
126
- name: providedName || this._getDefaultStepName(result.lhr),
125
+ this.stepArtifacts.push({
126
+ gatherResult,
127
+ name: providedName || this._getDefaultStepName(gatherResult.artifacts),
127
128
  });
128
129
 
129
- return result;
130
+ return gatherResult;
130
131
  }
131
132
 
132
133
  /**
133
134
  * @param {StepOptions=} stepOptions
134
135
  */
135
136
  async snapshot(stepOptions) {
136
- if (this.currentTimespan) throw Error('Timespan already in progress');
137
+ if (this.currentTimespan) throw new Error('Timespan already in progress');
137
138
 
138
139
  const options = {...this.options, ...stepOptions};
139
- const result = await snapshot(options);
140
- if (!result) throw Error('Snapshot returned undefined');
140
+ const gatherResult = await snapshotGather(options);
141
141
 
142
142
  const providedName = stepOptions?.stepName;
143
- this.steps.push({
144
- lhr: result.lhr,
145
- name: providedName || this._getDefaultStepName(result.lhr),
143
+ this.stepArtifacts.push({
144
+ gatherResult,
145
+ name: providedName || this._getDefaultStepName(gatherResult.artifacts),
146
146
  });
147
147
 
148
- return result;
148
+ return gatherResult;
149
149
  }
150
150
 
151
151
  /**
152
- * @return {LH.FlowResult}
152
+ * @returns {Promise<LH.FlowResult>}
153
153
  */
154
- getFlowResult() {
155
- if (!this.steps.length) throw Error('Need at least one step before getting the flow result');
156
- const url = new URL(this.steps[0].lhr.finalUrl);
157
- const name = this.name || `User flow (${url.hostname})`;
158
- return {steps: this.steps, name};
154
+ async createFlowResult() {
155
+ if (!this.stepArtifacts.length) {
156
+ throw new Error('Need at least one step before getting the result');
157
+ }
158
+ const url = new URL(this.stepArtifacts[0].gatherResult.artifacts.URL.finalUrl);
159
+ const flowName = this.name || `User flow (${url.hostname})`;
160
+
161
+ /** @type {LH.FlowResult['steps']} */
162
+ const steps = [];
163
+ for (const {gatherResult, name} of this.stepArtifacts) {
164
+ const result = await Runner.audit(gatherResult.artifacts, gatherResult.runnerOptions);
165
+ if (!result) throw new Error(`Step "${name}" did not return a result`);
166
+ steps.push({lhr: result.lhr, name});
167
+ }
168
+
169
+ return {steps, name: flowName};
159
170
  }
160
171
 
161
172
  /**
162
- * @return {string}
173
+ * @return {Promise<string>}
163
174
  */
164
- generateReport() {
165
- const flowResult = this.getFlowResult();
175
+ async generateReport() {
176
+ const flowResult = await this.createFlowResult();
166
177
  return generateFlowReportHtml(flowResult);
167
178
  }
168
179
  }
@@ -5,7 +5,7 @@
5
5
  */
6
6
  'use strict';
7
7
 
8
- const isEqual = require('lodash.isequal');
8
+ const {isEqual} = require('lodash');
9
9
 
10
10
  /**
11
11
  * @fileoverview This class is designed to allow maps with arbitrary equality functions.
@@ -5,7 +5,7 @@
5
5
  */
6
6
  'use strict';
7
7
 
8
- const isDeepEqual = require('lodash.isequal');
8
+ const {isEqual: isDeepEqual} = require('lodash');
9
9
  const Driver = require('./gather/driver.js');
10
10
  const GatherRunner = require('./gather/gather-runner.js');
11
11
  const ReportScoring = require('./scoring.js');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lighthouse",
3
- "version": "9.4.0-dev.20220228",
3
+ "version": "9.4.0-dev.20220303",
4
4
  "description": "Automated auditing, performance metrics, and best practices for the web.",
5
5
  "main": "./lighthouse-core/index.js",
6
6
  "bin": {
@@ -115,10 +115,7 @@
115
115
  "@types/jest": "^27.0.3",
116
116
  "@types/jpeg-js": "^0.3.7",
117
117
  "@types/jsdom": "^16.2.13",
118
- "@types/lodash.clonedeep": "^4.5.6",
119
- "@types/lodash.get": "^4.4.6",
120
- "@types/lodash.isequal": "^4.5.2",
121
- "@types/lodash.set": "^4.3.6",
118
+ "@types/lodash": "^4.14.178",
122
119
  "@types/node": "*",
123
120
  "@types/pako": "^1.0.1",
124
121
  "@types/resize-observer-browser": "^0.1.1",
@@ -195,10 +192,7 @@
195
192
  "js-library-detector": "^6.4.0",
196
193
  "lighthouse-logger": "^1.3.0",
197
194
  "lighthouse-stack-packs": "^1.7.0",
198
- "lodash.clonedeep": "^4.5.0",
199
- "lodash.get": "^4.4.2",
200
- "lodash.isequal": "^4.5.0",
201
- "lodash.set": "^4.3.2",
195
+ "lodash": "^4.17.21",
202
196
  "lookup-closest-locale": "6.2.0",
203
197
  "metaviewport-parser": "0.2.0",
204
198
  "open": "^8.4.0",
@@ -5,8 +5,7 @@
5
5
  */
6
6
  'use strict';
7
7
 
8
- const _set = require('lodash.set');
9
- const _get = require('lodash.get');
8
+ const {set: _set, get: _get} = require('lodash');
10
9
 
11
10
  const format = require('./format.js');
12
11
 
@@ -45,7 +45,7 @@
45
45
  {"id":"npm:bootstrap:20120510","severity":"medium","semver":{"vulnerable":["<2.1.0"]}}
46
46
  ],
47
47
  "dojo":[
48
- {"id":"SNYK-JS-DOJO-1535223","severity":"high","semver":{"vulnerable":["<=1.16.4"]}},
48
+ {"id":"SNYK-JS-DOJO-1535223","severity":"high","semver":{"vulnerable":["<1.17.0"]}},
49
49
  {"id":"SNYK-JS-DOJO-559224","severity":"medium","semver":{"vulnerable":["<1.11.10",">=1.12.1 <1.12.8",">=1.13.0 <1.13.7",">=1.14.0 <1.14.6",">=1.15.0 <1.15.3",">=1.16.0 <1.16.2"]}},
50
50
  {"id":"SNYK-JS-DOJO-174934","severity":"medium","semver":{"vulnerable":[">=1.0.0 <1.0.3",">=1.1.0 <1.1.2",">=1.2.0 <1.2.4",">=1.3.0 <1.3.3",">=1.4.0 <1.4.2"]}},
51
51
  {"id":"SNYK-JS-DOJO-174933","severity":"medium","semver":{"vulnerable":["<1.2.0"]}},
@@ -70,7 +70,7 @@
70
70
  {"id":"SNYK-JS-HANDLEBARS-1279029","severity":"medium","semver":{"vulnerable":["<4.7.7"]}},
71
71
  {"id":"SNYK-JS-HANDLEBARS-1056767","severity":"high","semver":{"vulnerable":["<4.7.7"]}},
72
72
  {"id":"SNYK-JS-HANDLEBARS-567742","severity":"medium","semver":{"vulnerable":["<4.6.0"]}},
73
- {"id":"SNYK-JS-HANDLEBARS-534988","severity":"high","semver":{"vulnerable":[">=4.0.0 <4.5.3","<3.0.8"]}},
73
+ {"id":"SNYK-JS-HANDLEBARS-534988","severity":"critical","semver":{"vulnerable":[">=4.0.0 <4.5.3","<3.0.8"]}},
74
74
  {"id":"SNYK-JS-HANDLEBARS-534478","severity":"high","semver":{"vulnerable":[">=4.0.0 <4.5.3","<3.0.8"]}},
75
75
  {"id":"SNYK-JS-HANDLEBARS-480388","severity":"high","semver":{"vulnerable":[">=4.0.0 <4.4.5"]}},
76
76
  {"id":"SNYK-JS-HANDLEBARS-469063","severity":"high","semver":{"vulnerable":[">=4.0.0 <4.3.0","<3.8.0"]}},
@@ -116,7 +116,7 @@
116
116
  {"id":"SNYK-JS-LODASH-1040724","severity":"high","semver":{"vulnerable":["<4.17.21"]}},
117
117
  {"id":"SNYK-JS-LODASH-1018905","severity":"medium","semver":{"vulnerable":["<4.17.21"]}},
118
118
  {"id":"SNYK-JS-LODASH-608086","severity":"high","semver":{"vulnerable":["<4.17.17"]}},
119
- {"id":"SNYK-JS-LODASH-590103","severity":"high","semver":{"vulnerable":["<4.17.20"]}},
119
+ {"id":"SNYK-JS-LODASH-590103","severity":"critical","semver":{"vulnerable":["<4.17.20"]}},
120
120
  {"id":"SNYK-JS-LODASH-567746","severity":"medium","semver":{"vulnerable":["<4.17.16"]}},
121
121
  {"id":"SNYK-JS-LODASH-450202","severity":"high","semver":{"vulnerable":["<4.17.12"]}},
122
122
  {"id":"SNYK-JS-LODASH-73639","severity":"medium","semver":{"vulnerable":["<4.17.11"]}},
@@ -62,6 +62,14 @@ declare module Gatherer {
62
62
  settings: Config.Settings;
63
63
  }
64
64
 
65
+ interface FRGatherResult {
66
+ artifacts: Artifacts;
67
+ runnerOptions: {
68
+ config: Config.FRConfig;
69
+ computedCache: Map<string, ArbitraryEqualityMap>
70
+ }
71
+ }
72
+
65
73
  interface PassContext {
66
74
  gatherMode: 'navigation';
67
75
  /** The url of the currently loaded page. If the main document redirects, this will be updated to keep track. */