lighthouse 11.2.0-dev.20231016 → 11.2.0-dev.20231018
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.
- package/cli/test/smokehouse/frontends/smokehouse-bin.js +18 -7
- package/cli/test/smokehouse/lighthouse-runners/bundle.d.ts +2 -4
- package/cli/test/smokehouse/lighthouse-runners/bundle.js +8 -4
- package/cli/test/smokehouse/lighthouse-runners/cli.d.ts +2 -4
- package/cli/test/smokehouse/lighthouse-runners/cli.js +5 -3
- package/cli/test/smokehouse/lighthouse-runners/devtools.d.ts +2 -1
- package/cli/test/smokehouse/lighthouse-runners/devtools.js +3 -1
- package/cli/test/smokehouse/smokehouse.d.ts +4 -2
- package/cli/test/smokehouse/smokehouse.js +10 -7
- package/core/config/config.d.ts +1 -2
- package/core/config/config.js +18 -62
- package/core/config/constants.d.ts +1 -3
- package/core/config/constants.js +2 -18
- package/core/config/default-config.js +3 -3
- package/core/config/filters.d.ts +0 -8
- package/core/config/filters.js +0 -28
- package/core/config/validation.d.ts +4 -15
- package/core/config/validation.js +18 -63
- package/core/gather/base-artifacts.d.ts +2 -2
- package/core/gather/base-artifacts.js +5 -5
- package/core/gather/driver/navigation.d.ts +1 -1
- package/core/gather/driver/navigation.js +1 -1
- package/core/gather/driver/prepare.d.ts +3 -18
- package/core/gather/driver/prepare.js +14 -38
- package/core/gather/navigation-runner.d.ts +3 -31
- package/core/gather/navigation-runner.js +39 -112
- package/core/lib/navigation-error.d.ts +1 -2
- package/core/lib/navigation-error.js +2 -6
- package/package.json +1 -1
- package/types/config.d.ts +0 -38
- package/types/internal/smokehouse.d.ts +10 -5
|
@@ -68,43 +68,6 @@ function assertValidArtifact(artifactDefn) {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
/**
|
|
72
|
-
* Throws an error if the provided object does not implement the required navigations interface.
|
|
73
|
-
* @param {LH.Config.ResolvedConfig['navigations']} navigationsDefn
|
|
74
|
-
* @return {{warnings: string[]}}
|
|
75
|
-
*/
|
|
76
|
-
function assertValidNavigations(navigationsDefn) {
|
|
77
|
-
if (!navigationsDefn || !navigationsDefn.length) return {warnings: []};
|
|
78
|
-
|
|
79
|
-
/** @type {string[]} */
|
|
80
|
-
const warnings = [];
|
|
81
|
-
|
|
82
|
-
// Assert that the first navigation has loadFailureMode fatal.
|
|
83
|
-
const firstNavigation = navigationsDefn[0];
|
|
84
|
-
if (firstNavigation.loadFailureMode !== 'fatal') {
|
|
85
|
-
const currentMode = firstNavigation.loadFailureMode;
|
|
86
|
-
const warning = [
|
|
87
|
-
`"${firstNavigation.id}" is the first navigation but had a failure mode of ${currentMode}.`,
|
|
88
|
-
`The first navigation will always be treated as loadFailureMode=fatal.`,
|
|
89
|
-
].join(' ');
|
|
90
|
-
|
|
91
|
-
warnings.push(warning);
|
|
92
|
-
firstNavigation.loadFailureMode = 'fatal';
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Assert that navigations have unique IDs.
|
|
96
|
-
const navigationIds = navigationsDefn.map(navigation => navigation.id);
|
|
97
|
-
const duplicateId = navigationIds.find(
|
|
98
|
-
(id, i) => navigationIds.slice(i + 1).some(other => id === other)
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
if (duplicateId) {
|
|
102
|
-
throw new Error(`Navigation must have unique identifiers, but "${duplicateId}" was repeated.`);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return {warnings};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
71
|
/**
|
|
109
72
|
* Throws an error if the provided object does not implement the required properties of an audit
|
|
110
73
|
* definition.
|
|
@@ -223,42 +186,36 @@ function assertValidSettings(settings) {
|
|
|
223
186
|
}
|
|
224
187
|
|
|
225
188
|
/**
|
|
226
|
-
* Asserts that artifacts are in a
|
|
189
|
+
* Asserts that artifacts are unique, valid and are in a dependency order that can be computed.
|
|
227
190
|
*
|
|
228
|
-
* @param {Array<LH.Config.
|
|
191
|
+
* @param {Array<LH.Config.AnyArtifactDefn>} artifactDefns
|
|
229
192
|
*/
|
|
230
|
-
function
|
|
193
|
+
function assertValidArtifacts(artifactDefns) {
|
|
194
|
+
/** @type {Set<string>} */
|
|
231
195
|
const availableArtifacts = new Set();
|
|
232
196
|
|
|
233
|
-
for (const
|
|
234
|
-
|
|
235
|
-
availableArtifacts.add(artifact.id);
|
|
236
|
-
if (!artifact.dependencies) continue;
|
|
197
|
+
for (const artifact of artifactDefns) {
|
|
198
|
+
assertValidArtifact(artifact);
|
|
237
199
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
200
|
+
if (availableArtifacts.has(artifact.id)) {
|
|
201
|
+
throw new Error(`Config defined multiple artifacts with id '${artifact.id}'`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
availableArtifacts.add(artifact.id);
|
|
205
|
+
if (!artifact.dependencies) continue;
|
|
206
|
+
|
|
207
|
+
for (const [dependencyKey, {id: dependencyId}] of Object.entries(artifact.dependencies)) {
|
|
208
|
+
if (availableArtifacts.has(dependencyId)) continue;
|
|
209
|
+
throwInvalidDependencyOrder(artifact.id, dependencyKey);
|
|
242
210
|
}
|
|
243
211
|
}
|
|
244
212
|
}
|
|
245
213
|
|
|
246
214
|
/**
|
|
247
215
|
* @param {LH.Config.ResolvedConfig} resolvedConfig
|
|
248
|
-
* @return {{warnings: string[]}}
|
|
249
216
|
*/
|
|
250
217
|
function assertValidConfig(resolvedConfig) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
/** @type {Set<string>} */
|
|
254
|
-
const artifactIds = new Set();
|
|
255
|
-
for (const artifactDefn of resolvedConfig.artifacts || []) {
|
|
256
|
-
if (artifactIds.has(artifactDefn.id)) {
|
|
257
|
-
throw new Error(`Config defined multiple artifacts with id '${artifactDefn.id}'`);
|
|
258
|
-
}
|
|
259
|
-
artifactIds.add(artifactDefn.id);
|
|
260
|
-
assertValidArtifact(artifactDefn);
|
|
261
|
-
}
|
|
218
|
+
assertValidArtifacts(resolvedConfig.artifacts || []);
|
|
262
219
|
|
|
263
220
|
for (const auditDefn of resolvedConfig.audits || []) {
|
|
264
221
|
assertValidAudit(auditDefn);
|
|
@@ -266,7 +223,6 @@ function assertValidConfig(resolvedConfig) {
|
|
|
266
223
|
|
|
267
224
|
assertValidCategories(resolvedConfig.categories, resolvedConfig.audits, resolvedConfig.groups);
|
|
268
225
|
assertValidSettings(resolvedConfig.settings);
|
|
269
|
-
return {warnings};
|
|
270
226
|
}
|
|
271
227
|
|
|
272
228
|
/**
|
|
@@ -303,11 +259,10 @@ export {
|
|
|
303
259
|
isValidArtifactDependency,
|
|
304
260
|
assertValidPluginName,
|
|
305
261
|
assertValidArtifact,
|
|
306
|
-
assertValidNavigations,
|
|
307
262
|
assertValidAudit,
|
|
308
263
|
assertValidCategories,
|
|
309
264
|
assertValidSettings,
|
|
310
|
-
|
|
265
|
+
assertValidArtifacts,
|
|
311
266
|
assertValidConfig,
|
|
312
267
|
throwInvalidDependencyOrder,
|
|
313
268
|
throwInvalidArtifactDependency,
|
|
@@ -9,8 +9,8 @@ export function getBaseArtifacts(resolvedConfig: LH.Config.ResolvedConfig, drive
|
|
|
9
9
|
}): Promise<LH.BaseArtifacts>;
|
|
10
10
|
/**
|
|
11
11
|
* @param {LH.BaseArtifacts} baseArtifacts
|
|
12
|
-
* @param {Partial<LH.
|
|
12
|
+
* @param {Partial<LH.GathererArtifacts>} gathererArtifacts
|
|
13
13
|
* @return {LH.Artifacts}
|
|
14
14
|
*/
|
|
15
|
-
export function finalizeArtifacts(baseArtifacts: LH.BaseArtifacts, gathererArtifacts: Partial<LH.
|
|
15
|
+
export function finalizeArtifacts(baseArtifacts: LH.BaseArtifacts, gathererArtifacts: Partial<LH.GathererArtifacts>): LH.Artifacts;
|
|
16
16
|
//# sourceMappingURL=base-artifacts.d.ts.map
|
|
@@ -60,20 +60,20 @@ function deduplicateWarnings(warnings) {
|
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* @param {LH.BaseArtifacts} baseArtifacts
|
|
63
|
-
* @param {Partial<LH.
|
|
63
|
+
* @param {Partial<LH.GathererArtifacts>} gathererArtifacts
|
|
64
64
|
* @return {LH.Artifacts}
|
|
65
65
|
*/
|
|
66
66
|
function finalizeArtifacts(baseArtifacts, gathererArtifacts) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
baseArtifacts.LighthouseRunWarnings.push(
|
|
68
|
+
...getEnvironmentWarnings({settings: baseArtifacts.settings, baseArtifacts})
|
|
69
|
+
);
|
|
70
70
|
|
|
71
71
|
// Cast to remove the partial from gathererArtifacts.
|
|
72
72
|
const artifacts = /** @type {LH.Artifacts} */ ({...baseArtifacts, ...gathererArtifacts});
|
|
73
73
|
|
|
74
74
|
// Set the post-run meta artifacts.
|
|
75
75
|
artifacts.Timing = log.getTimeEntries();
|
|
76
|
-
artifacts.LighthouseRunWarnings = deduplicateWarnings(
|
|
76
|
+
artifacts.LighthouseRunWarnings = deduplicateWarnings(baseArtifacts.LighthouseRunWarnings);
|
|
77
77
|
|
|
78
78
|
if (artifacts.PageLoadError && !artifacts.URL.finalDisplayedUrl) {
|
|
79
79
|
artifacts.URL.finalDisplayedUrl = artifacts.URL.requestedUrl || '';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type NavigationOptions = {
|
|
2
2
|
waitUntil: Array<'fcp' | 'load' | 'navigated'>;
|
|
3
|
-
} &
|
|
3
|
+
} & Partial<LH.Config.Settings>;
|
|
4
4
|
/**
|
|
5
5
|
* Navigates to the given URL, assuming that the page is not already on this URL.
|
|
6
6
|
* Resolves on the url of the loaded page, taking into account any redirects.
|
|
@@ -39,7 +39,7 @@ const DEFAULT_NETWORK_QUIET_THRESHOLD = 5000;
|
|
|
39
39
|
// Controls how long to wait between longtasks before determining the CPU is idle, off by default
|
|
40
40
|
const DEFAULT_CPU_QUIET_THRESHOLD = 0;
|
|
41
41
|
|
|
42
|
-
/** @typedef {{waitUntil: Array<'fcp'|'load'|'navigated'>} &
|
|
42
|
+
/** @typedef {{waitUntil: Array<'fcp'|'load'|'navigated'>} & Partial<LH.Config.Settings>} NavigationOptions */
|
|
43
43
|
|
|
44
44
|
/** @param {NavigationOptions} options */
|
|
45
45
|
function resolveWaitForFullyLoadedOptions(options) {
|
|
@@ -5,12 +5,8 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @param {LH.Gatherer.ProtocolSession} session
|
|
7
7
|
* @param {LH.Config.Settings} settings
|
|
8
|
-
* @param {{disableThrottling: boolean, blockedUrlPatterns?: string[]}} options
|
|
9
8
|
*/
|
|
10
|
-
export function prepareThrottlingAndNetwork(session: LH.Gatherer.ProtocolSession, settings: LH.Config.Settings
|
|
11
|
-
disableThrottling: boolean;
|
|
12
|
-
blockedUrlPatterns?: string[];
|
|
13
|
-
}): Promise<void>;
|
|
9
|
+
export function prepareThrottlingAndNetwork(session: LH.Gatherer.ProtocolSession, settings: LH.Config.Settings): Promise<void>;
|
|
14
10
|
/**
|
|
15
11
|
* Prepares a target to be analyzed in timespan mode by enabling protocol domains, emulation, and throttling.
|
|
16
12
|
*
|
|
@@ -26,21 +22,10 @@ export function prepareTargetForTimespanMode(driver: LH.Gatherer.Driver, setting
|
|
|
26
22
|
*
|
|
27
23
|
* @param {LH.Gatherer.Driver} driver
|
|
28
24
|
* @param {LH.Config.Settings} settings
|
|
29
|
-
|
|
30
|
-
export function prepareTargetForNavigationMode(driver: LH.Gatherer.Driver, settings: LH.Config.Settings): Promise<void>;
|
|
31
|
-
/**
|
|
32
|
-
* Prepares a target for a particular navigation by resetting storage and setting network.
|
|
33
|
-
*
|
|
34
|
-
* This method assumes `prepareTargetForNavigationMode` has already been invoked.
|
|
35
|
-
*
|
|
36
|
-
* @param {LH.Gatherer.ProtocolSession} session
|
|
37
|
-
* @param {LH.Config.Settings} settings
|
|
38
|
-
* @param {Pick<LH.Config.NavigationDefn, 'disableThrottling'|'disableStorageReset'|'blockedUrlPatterns'> & {requestor: LH.NavigationRequestor}} navigation
|
|
25
|
+
* @param {LH.NavigationRequestor} requestor
|
|
39
26
|
* @return {Promise<{warnings: Array<LH.IcuMessage>}>}
|
|
40
27
|
*/
|
|
41
|
-
export function
|
|
42
|
-
requestor: LH.NavigationRequestor;
|
|
43
|
-
}): Promise<{
|
|
28
|
+
export function prepareTargetForNavigationMode(driver: LH.Gatherer.Driver, settings: LH.Config.Settings, requestor: LH.NavigationRequestor): Promise<{
|
|
44
29
|
warnings: Array<LH.IcuMessage>;
|
|
45
30
|
}>;
|
|
46
31
|
/**
|
|
@@ -114,21 +114,17 @@ async function resetStorageForUrl(session, url) {
|
|
|
114
114
|
*
|
|
115
115
|
* @param {LH.Gatherer.ProtocolSession} session
|
|
116
116
|
* @param {LH.Config.Settings} settings
|
|
117
|
-
* @param {{disableThrottling: boolean, blockedUrlPatterns?: string[]}} options
|
|
118
117
|
*/
|
|
119
|
-
async function prepareThrottlingAndNetwork(session, settings
|
|
118
|
+
async function prepareThrottlingAndNetwork(session, settings) {
|
|
120
119
|
const status = {msg: 'Preparing network conditions', id: `lh:gather:prepareThrottlingAndNetwork`};
|
|
121
120
|
log.time(status);
|
|
122
121
|
|
|
123
|
-
|
|
124
|
-
else await emulation.throttle(session, settings);
|
|
122
|
+
await emulation.throttle(session, settings);
|
|
125
123
|
|
|
126
124
|
// Set request blocking before any network activity.
|
|
127
125
|
// No "clearing" is done at the end of the recording since Network.setBlockedURLs([]) will unset all if
|
|
128
126
|
// neccessary at the beginning of the next section.
|
|
129
|
-
const blockedUrls =
|
|
130
|
-
settings.blockedUrlPatterns || []
|
|
131
|
-
);
|
|
127
|
+
const blockedUrls = settings.blockedUrlPatterns || [];
|
|
132
128
|
await session.sendCommand('Network.setBlockedURLs', {urls: blockedUrls});
|
|
133
129
|
|
|
134
130
|
const headers = settings.extraHeaders;
|
|
@@ -163,10 +159,7 @@ async function prepareTargetForTimespanMode(driver, settings) {
|
|
|
163
159
|
log.time(status);
|
|
164
160
|
|
|
165
161
|
await prepareDeviceEmulation(driver, settings);
|
|
166
|
-
await prepareThrottlingAndNetwork(driver.defaultSession, settings
|
|
167
|
-
disableThrottling: false,
|
|
168
|
-
blockedUrlPatterns: undefined,
|
|
169
|
-
});
|
|
162
|
+
await prepareThrottlingAndNetwork(driver.defaultSession, settings);
|
|
170
163
|
await warmUpIntlSegmenter(driver);
|
|
171
164
|
|
|
172
165
|
log.timeEnd(status);
|
|
@@ -192,11 +185,16 @@ async function warmUpIntlSegmenter(driver) {
|
|
|
192
185
|
*
|
|
193
186
|
* @param {LH.Gatherer.Driver} driver
|
|
194
187
|
* @param {LH.Config.Settings} settings
|
|
188
|
+
* @param {LH.NavigationRequestor} requestor
|
|
189
|
+
* @return {Promise<{warnings: Array<LH.IcuMessage>}>}
|
|
195
190
|
*/
|
|
196
|
-
async function prepareTargetForNavigationMode(driver, settings) {
|
|
191
|
+
async function prepareTargetForNavigationMode(driver, settings, requestor) {
|
|
197
192
|
const status = {msg: 'Preparing target for navigation mode', id: 'lh:prepare:navigationMode'};
|
|
198
193
|
log.time(status);
|
|
199
194
|
|
|
195
|
+
/** @type {Array<LH.IcuMessage>} */
|
|
196
|
+
const warnings = [];
|
|
197
|
+
|
|
200
198
|
await prepareDeviceEmulation(driver, settings);
|
|
201
199
|
|
|
202
200
|
// Automatically handle any JavaScript dialogs to prevent a hung renderer.
|
|
@@ -212,41 +210,20 @@ async function prepareTargetForNavigationMode(driver, settings) {
|
|
|
212
210
|
|
|
213
211
|
await warmUpIntlSegmenter(driver);
|
|
214
212
|
|
|
215
|
-
log.timeEnd(status);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Prepares a target for a particular navigation by resetting storage and setting network.
|
|
220
|
-
*
|
|
221
|
-
* This method assumes `prepareTargetForNavigationMode` has already been invoked.
|
|
222
|
-
*
|
|
223
|
-
* @param {LH.Gatherer.ProtocolSession} session
|
|
224
|
-
* @param {LH.Config.Settings} settings
|
|
225
|
-
* @param {Pick<LH.Config.NavigationDefn, 'disableThrottling'|'disableStorageReset'|'blockedUrlPatterns'> & {requestor: LH.NavigationRequestor}} navigation
|
|
226
|
-
* @return {Promise<{warnings: Array<LH.IcuMessage>}>}
|
|
227
|
-
*/
|
|
228
|
-
async function prepareTargetForIndividualNavigation(session, settings, navigation) {
|
|
229
|
-
const status = {msg: 'Preparing target for navigation', id: 'lh:prepare:navigation'};
|
|
230
|
-
log.time(status);
|
|
231
|
-
|
|
232
|
-
/** @type {Array<LH.IcuMessage>} */
|
|
233
|
-
const warnings = [];
|
|
234
|
-
|
|
235
|
-
const {requestor} = navigation;
|
|
236
213
|
const shouldResetStorage =
|
|
237
214
|
!settings.disableStorageReset &&
|
|
238
|
-
!navigation.disableStorageReset &&
|
|
239
215
|
// Without prior knowledge of the destination, we cannot know which URL to clear storage for.
|
|
240
216
|
typeof requestor === 'string';
|
|
241
217
|
if (shouldResetStorage) {
|
|
242
|
-
const
|
|
243
|
-
|
|
218
|
+
const {warnings: storageWarnings} =
|
|
219
|
+
await resetStorageForUrl(driver.defaultSession, requestor);
|
|
244
220
|
warnings.push(...storageWarnings);
|
|
245
221
|
}
|
|
246
222
|
|
|
247
|
-
await prepareThrottlingAndNetwork(
|
|
223
|
+
await prepareThrottlingAndNetwork(driver.defaultSession, settings);
|
|
248
224
|
|
|
249
225
|
log.timeEnd(status);
|
|
226
|
+
|
|
250
227
|
return {warnings};
|
|
251
228
|
}
|
|
252
229
|
|
|
@@ -254,6 +231,5 @@ export {
|
|
|
254
231
|
prepareThrottlingAndNetwork,
|
|
255
232
|
prepareTargetForTimespanMode,
|
|
256
233
|
prepareTargetForNavigationMode,
|
|
257
|
-
prepareTargetForIndividualNavigation,
|
|
258
234
|
enableAsyncStacks,
|
|
259
235
|
};
|
|
@@ -2,7 +2,6 @@ export type NavigationContext = {
|
|
|
2
2
|
driver: Driver;
|
|
3
3
|
page: LH.Puppeteer.Page;
|
|
4
4
|
resolvedConfig: LH.Config.ResolvedConfig;
|
|
5
|
-
navigation: LH.Config.NavigationDefn;
|
|
6
5
|
requestor: LH.NavigationRequestor;
|
|
7
6
|
baseArtifacts: LH.BaseArtifacts;
|
|
8
7
|
computedCache: Map<string, LH.ArbitraryEqualityMap>;
|
|
@@ -31,40 +30,18 @@ export function _setup({ driver, resolvedConfig, requestor }: {
|
|
|
31
30
|
}>;
|
|
32
31
|
/**
|
|
33
32
|
* @param {NavigationContext} navigationContext
|
|
34
|
-
* @return {Promise<{
|
|
35
|
-
*/
|
|
36
|
-
export function _setupNavigation({ requestor, driver, navigation, resolvedConfig }: NavigationContext): Promise<{
|
|
37
|
-
warnings: Array<LH.IcuMessage>;
|
|
38
|
-
}>;
|
|
39
|
-
/**
|
|
40
|
-
* @param {NavigationContext} navigationContext
|
|
41
|
-
* @return {Promise<{requestedUrl: string, mainDocumentUrl: string, navigationError: LH.LighthouseError | undefined, warnings: Array<LH.IcuMessage>}>}
|
|
33
|
+
* @return {Promise<{requestedUrl: string, mainDocumentUrl: string, navigationError: LH.LighthouseError | undefined}>}
|
|
42
34
|
*/
|
|
43
35
|
export function _navigate(navigationContext: NavigationContext): Promise<{
|
|
44
36
|
requestedUrl: string;
|
|
45
37
|
mainDocumentUrl: string;
|
|
46
38
|
navigationError: LH.LighthouseError | undefined;
|
|
47
|
-
warnings: Array<LH.IcuMessage>;
|
|
48
39
|
}>;
|
|
49
40
|
/**
|
|
50
41
|
* @param {NavigationContext} navigationContext
|
|
51
42
|
* @return {ReturnType<typeof _computeNavigationResult>}
|
|
52
43
|
*/
|
|
53
44
|
export function _navigation(navigationContext: NavigationContext): ReturnType<typeof _computeNavigationResult>;
|
|
54
|
-
/**
|
|
55
|
-
* @param {{driver: Driver, page: LH.Puppeteer.Page, resolvedConfig: LH.Config.ResolvedConfig, requestor: LH.NavigationRequestor; baseArtifacts: LH.BaseArtifacts, computedCache: NavigationContext['computedCache']}} args
|
|
56
|
-
* @return {Promise<{artifacts: Partial<LH.Artifacts & LH.BaseArtifacts>}>}
|
|
57
|
-
*/
|
|
58
|
-
export function _navigations(args: {
|
|
59
|
-
driver: Driver;
|
|
60
|
-
page: LH.Puppeteer.Page;
|
|
61
|
-
resolvedConfig: LH.Config.ResolvedConfig;
|
|
62
|
-
requestor: LH.NavigationRequestor;
|
|
63
|
-
baseArtifacts: LH.BaseArtifacts;
|
|
64
|
-
computedCache: NavigationContext['computedCache'];
|
|
65
|
-
}): Promise<{
|
|
66
|
-
artifacts: Partial<LH.Artifacts & LH.BaseArtifacts>;
|
|
67
|
-
}>;
|
|
68
45
|
/**
|
|
69
46
|
* @param {{requestedUrl?: string, driver: Driver, resolvedConfig: LH.Config.ResolvedConfig, lhBrowser?: LH.Puppeteer.Browser, lhPage?: LH.Puppeteer.Page}} args
|
|
70
47
|
*/
|
|
@@ -81,14 +58,9 @@ import { LighthouseError } from '../lib/lh-error.js';
|
|
|
81
58
|
/**
|
|
82
59
|
* @param {NavigationContext} navigationContext
|
|
83
60
|
* @param {PhaseState} phaseState
|
|
84
|
-
* @param {Awaited<ReturnType<typeof _setupNavigation>>} setupResult
|
|
85
61
|
* @param {Awaited<ReturnType<typeof _navigate>>} navigateResult
|
|
86
|
-
* @return {Promise<
|
|
62
|
+
* @return {Promise<Partial<LH.GathererArtifacts>>}
|
|
87
63
|
*/
|
|
88
|
-
declare function _computeNavigationResult(navigationContext: NavigationContext, phaseState: PhaseState,
|
|
89
|
-
artifacts: Partial<LH.GathererArtifacts>;
|
|
90
|
-
warnings: Array<LH.IcuMessage>;
|
|
91
|
-
pageLoadError: LH.LighthouseError | undefined;
|
|
92
|
-
}>;
|
|
64
|
+
declare function _computeNavigationResult(navigationContext: NavigationContext, phaseState: PhaseState, navigateResult: Awaited<ReturnType<typeof _navigate>>): Promise<Partial<LH.GathererArtifacts>>;
|
|
93
65
|
export {};
|
|
94
66
|
//# sourceMappingURL=navigation-runner.d.ts.map
|
|
@@ -14,7 +14,6 @@ import * as prepare from './driver/prepare.js';
|
|
|
14
14
|
import {gotoURL} from './driver/navigation.js';
|
|
15
15
|
import * as storage from './driver/storage.js';
|
|
16
16
|
import * as emulation from '../lib/emulation.js';
|
|
17
|
-
import {defaultNavigationConfig} from '../config/constants.js';
|
|
18
17
|
import {initializeConfig} from '../config/config.js';
|
|
19
18
|
import {getBaseArtifacts, finalizeArtifacts} from './base-artifacts.js';
|
|
20
19
|
import * as format from '../../shared/localization/format.js';
|
|
@@ -30,7 +29,6 @@ import {NetworkRecords} from '../computed/network-records.js';
|
|
|
30
29
|
* @property {Driver} driver
|
|
31
30
|
* @property {LH.Puppeteer.Page} page
|
|
32
31
|
* @property {LH.Config.ResolvedConfig} resolvedConfig
|
|
33
|
-
* @property {LH.Config.NavigationDefn} navigation
|
|
34
32
|
* @property {LH.NavigationRequestor} requestor
|
|
35
33
|
* @property {LH.BaseArtifacts} baseArtifacts
|
|
36
34
|
* @property {Map<string, LH.ArbitraryEqualityMap>} computedCache
|
|
@@ -50,36 +48,23 @@ async function _setup({driver, resolvedConfig, requestor}) {
|
|
|
50
48
|
|
|
51
49
|
// We can't trigger the navigation through user interaction if we reset the page before starting.
|
|
52
50
|
if (typeof requestor === 'string' && !resolvedConfig.settings.skipAboutBlank) {
|
|
53
|
-
|
|
51
|
+
// Disable network monitor on the blank page to prevent it from picking up network requests and
|
|
52
|
+
// frame navigated events before the run starts.
|
|
53
|
+
await driver._networkMonitor?.disable();
|
|
54
|
+
|
|
55
|
+
await gotoURL(driver, resolvedConfig.settings.blankPage, {waitUntil: ['navigated']});
|
|
56
|
+
|
|
57
|
+
await driver._networkMonitor?.enable();
|
|
54
58
|
}
|
|
55
59
|
|
|
56
60
|
const baseArtifacts = await getBaseArtifacts(resolvedConfig, driver, {gatherMode: 'navigation'});
|
|
57
61
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return {baseArtifacts};
|
|
61
|
-
}
|
|
62
|
+
const {warnings} =
|
|
63
|
+
await prepare.prepareTargetForNavigationMode(driver, resolvedConfig.settings, requestor);
|
|
62
64
|
|
|
63
|
-
|
|
64
|
-
* @param {NavigationContext} navigationContext
|
|
65
|
-
* @return {Promise<{warnings: Array<LH.IcuMessage>}>}
|
|
66
|
-
*/
|
|
67
|
-
async function _setupNavigation({requestor, driver, navigation, resolvedConfig}) {
|
|
68
|
-
// We can't trigger the navigation through user interaction if we reset the page before starting.
|
|
69
|
-
if (typeof requestor === 'string' && !resolvedConfig.settings.skipAboutBlank) {
|
|
70
|
-
await gotoURL(driver, navigation.blankPage, {...navigation, waitUntil: ['navigated']});
|
|
71
|
-
}
|
|
65
|
+
baseArtifacts.LighthouseRunWarnings.push(...warnings);
|
|
72
66
|
|
|
73
|
-
|
|
74
|
-
driver.defaultSession,
|
|
75
|
-
resolvedConfig.settings,
|
|
76
|
-
{
|
|
77
|
-
...navigation,
|
|
78
|
-
requestor,
|
|
79
|
-
}
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
return {warnings};
|
|
67
|
+
return {baseArtifacts};
|
|
83
68
|
}
|
|
84
69
|
|
|
85
70
|
/**
|
|
@@ -91,20 +76,20 @@ async function _cleanupNavigation({driver}) {
|
|
|
91
76
|
|
|
92
77
|
/**
|
|
93
78
|
* @param {NavigationContext} navigationContext
|
|
94
|
-
* @return {Promise<{requestedUrl: string, mainDocumentUrl: string, navigationError: LH.LighthouseError | undefined
|
|
79
|
+
* @return {Promise<{requestedUrl: string, mainDocumentUrl: string, navigationError: LH.LighthouseError | undefined}>}
|
|
95
80
|
*/
|
|
96
81
|
async function _navigate(navigationContext) {
|
|
97
82
|
const {driver, resolvedConfig, requestor} = navigationContext;
|
|
98
83
|
|
|
99
84
|
try {
|
|
100
85
|
const {requestedUrl, mainDocumentUrl, warnings} = await gotoURL(driver, requestor, {
|
|
101
|
-
...
|
|
102
|
-
|
|
103
|
-
maxWaitForFcp: resolvedConfig.settings.maxWaitForFcp,
|
|
104
|
-
maxWaitForLoad: resolvedConfig.settings.maxWaitForLoad,
|
|
105
|
-
waitUntil: navigationContext.navigation.pauseAfterFcpMs ? ['fcp', 'load'] : ['load'],
|
|
86
|
+
...resolvedConfig.settings,
|
|
87
|
+
waitUntil: resolvedConfig.settings.pauseAfterFcpMs ? ['fcp', 'load'] : ['load'],
|
|
106
88
|
});
|
|
107
|
-
|
|
89
|
+
|
|
90
|
+
navigationContext.baseArtifacts.LighthouseRunWarnings.push(...warnings);
|
|
91
|
+
|
|
92
|
+
return {requestedUrl, mainDocumentUrl, navigationError: undefined};
|
|
108
93
|
} catch (err) {
|
|
109
94
|
if (!(err instanceof LighthouseError)) throw err;
|
|
110
95
|
if (err.code !== 'NO_FCP' && err.code !== 'PAGE_HUNG') throw err;
|
|
@@ -115,7 +100,6 @@ async function _navigate(navigationContext) {
|
|
|
115
100
|
requestedUrl: requestor,
|
|
116
101
|
mainDocumentUrl: requestor,
|
|
117
102
|
navigationError: err,
|
|
118
|
-
warnings: [],
|
|
119
103
|
};
|
|
120
104
|
}
|
|
121
105
|
}
|
|
@@ -158,36 +142,32 @@ async function _collectDebugData(navigationContext, phaseState) {
|
|
|
158
142
|
/**
|
|
159
143
|
* @param {NavigationContext} navigationContext
|
|
160
144
|
* @param {PhaseState} phaseState
|
|
161
|
-
* @param {Awaited<ReturnType<typeof _setupNavigation>>} setupResult
|
|
162
145
|
* @param {Awaited<ReturnType<typeof _navigate>>} navigateResult
|
|
163
|
-
* @return {Promise<
|
|
146
|
+
* @return {Promise<Partial<LH.GathererArtifacts>>}
|
|
164
147
|
*/
|
|
165
148
|
async function _computeNavigationResult(
|
|
166
149
|
navigationContext,
|
|
167
150
|
phaseState,
|
|
168
|
-
setupResult,
|
|
169
151
|
navigateResult
|
|
170
152
|
) {
|
|
171
|
-
const {navigationError, mainDocumentUrl} = navigateResult;
|
|
172
|
-
const warnings = [...setupResult.warnings, ...navigateResult.warnings];
|
|
153
|
+
const {navigationError, requestedUrl, mainDocumentUrl} = navigateResult;
|
|
173
154
|
const debugData = await _collectDebugData(navigationContext, phaseState);
|
|
174
155
|
const pageLoadError = debugData.records
|
|
175
156
|
? getPageLoadError(navigationError, {
|
|
176
157
|
url: mainDocumentUrl,
|
|
177
|
-
loadFailureMode: navigationContext.navigation.loadFailureMode,
|
|
178
158
|
networkRecords: debugData.records,
|
|
179
|
-
warnings,
|
|
159
|
+
warnings: navigationContext.baseArtifacts.LighthouseRunWarnings,
|
|
180
160
|
})
|
|
181
161
|
: navigationError;
|
|
182
162
|
|
|
183
163
|
if (pageLoadError) {
|
|
184
164
|
const locale = navigationContext.resolvedConfig.settings.locale;
|
|
185
165
|
const localizedMessage = format.getFormatted(pageLoadError.friendlyMessage, locale);
|
|
186
|
-
log.error('NavigationRunner', localizedMessage,
|
|
166
|
+
log.error('NavigationRunner', localizedMessage, requestedUrl);
|
|
187
167
|
|
|
188
168
|
/** @type {Partial<LH.GathererArtifacts>} */
|
|
189
169
|
const artifacts = {};
|
|
190
|
-
const pageLoadErrorId =
|
|
170
|
+
const pageLoadErrorId = 'pageLoadError-defaultPass';
|
|
191
171
|
if (debugData.devtoolsLog) {
|
|
192
172
|
artifacts.DevtoolsLogError = debugData.devtoolsLog;
|
|
193
173
|
artifacts.devtoolsLogs = {[pageLoadErrorId]: debugData.devtoolsLog};
|
|
@@ -197,20 +177,14 @@ async function _computeNavigationResult(
|
|
|
197
177
|
artifacts.traces = {[pageLoadErrorId]: debugData.trace};
|
|
198
178
|
}
|
|
199
179
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
};
|
|
180
|
+
navigationContext.baseArtifacts.LighthouseRunWarnings.push(pageLoadError.friendlyMessage);
|
|
181
|
+
navigationContext.baseArtifacts.PageLoadError = pageLoadError;
|
|
182
|
+
|
|
183
|
+
return artifacts;
|
|
205
184
|
} else {
|
|
206
185
|
await collectPhaseArtifacts({phase: 'getArtifact', ...phaseState});
|
|
207
186
|
|
|
208
|
-
|
|
209
|
-
return {
|
|
210
|
-
artifacts,
|
|
211
|
-
warnings,
|
|
212
|
-
pageLoadError: undefined,
|
|
213
|
-
};
|
|
187
|
+
return await awaitArtifacts(phaseState.artifactState);
|
|
214
188
|
}
|
|
215
189
|
}
|
|
216
190
|
|
|
@@ -219,6 +193,10 @@ async function _computeNavigationResult(
|
|
|
219
193
|
* @return {ReturnType<typeof _computeNavigationResult>}
|
|
220
194
|
*/
|
|
221
195
|
async function _navigation(navigationContext) {
|
|
196
|
+
if (!navigationContext.resolvedConfig.artifacts) {
|
|
197
|
+
throw new Error('No artifacts were defined on the config');
|
|
198
|
+
}
|
|
199
|
+
|
|
222
200
|
const artifactState = getEmptyArtifactState();
|
|
223
201
|
const phaseState = {
|
|
224
202
|
url: await navigationContext.driver.url(),
|
|
@@ -226,14 +204,12 @@ async function _navigation(navigationContext) {
|
|
|
226
204
|
driver: navigationContext.driver,
|
|
227
205
|
page: navigationContext.page,
|
|
228
206
|
computedCache: navigationContext.computedCache,
|
|
229
|
-
artifactDefinitions: navigationContext.
|
|
207
|
+
artifactDefinitions: navigationContext.resolvedConfig.artifacts,
|
|
230
208
|
artifactState,
|
|
231
209
|
baseArtifacts: navigationContext.baseArtifacts,
|
|
232
210
|
settings: navigationContext.resolvedConfig.settings,
|
|
233
211
|
};
|
|
234
212
|
|
|
235
|
-
const setupResult = await _setupNavigation(navigationContext);
|
|
236
|
-
|
|
237
213
|
const disableAsyncStacks =
|
|
238
214
|
await prepare.enableAsyncStacks(navigationContext.driver.defaultSession);
|
|
239
215
|
|
|
@@ -262,58 +238,7 @@ async function _navigation(navigationContext) {
|
|
|
262
238
|
|
|
263
239
|
await _cleanupNavigation(navigationContext);
|
|
264
240
|
|
|
265
|
-
return _computeNavigationResult(navigationContext, phaseState,
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* @param {{driver: Driver, page: LH.Puppeteer.Page, resolvedConfig: LH.Config.ResolvedConfig, requestor: LH.NavigationRequestor; baseArtifacts: LH.BaseArtifacts, computedCache: NavigationContext['computedCache']}} args
|
|
270
|
-
* @return {Promise<{artifacts: Partial<LH.Artifacts & LH.BaseArtifacts>}>}
|
|
271
|
-
*/
|
|
272
|
-
async function _navigations(args) {
|
|
273
|
-
const {
|
|
274
|
-
driver,
|
|
275
|
-
page,
|
|
276
|
-
resolvedConfig,
|
|
277
|
-
requestor,
|
|
278
|
-
baseArtifacts,
|
|
279
|
-
computedCache,
|
|
280
|
-
} = args;
|
|
281
|
-
|
|
282
|
-
if (!resolvedConfig.artifacts || !resolvedConfig.navigations) {
|
|
283
|
-
throw new Error('No artifacts were defined on the config');
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/** @type {Partial<LH.Artifacts & LH.BaseArtifacts>} */
|
|
287
|
-
const artifacts = {};
|
|
288
|
-
/** @type {Array<LH.IcuMessage>} */
|
|
289
|
-
const LighthouseRunWarnings = [];
|
|
290
|
-
|
|
291
|
-
for (const navigation of resolvedConfig.navigations) {
|
|
292
|
-
const navigationContext = {
|
|
293
|
-
driver,
|
|
294
|
-
page,
|
|
295
|
-
navigation,
|
|
296
|
-
requestor,
|
|
297
|
-
resolvedConfig,
|
|
298
|
-
baseArtifacts,
|
|
299
|
-
computedCache,
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
let shouldHaltNavigations = false;
|
|
303
|
-
const navigationResult = await _navigation(navigationContext);
|
|
304
|
-
if (navigation.loadFailureMode === 'fatal') {
|
|
305
|
-
if (navigationResult.pageLoadError) {
|
|
306
|
-
artifacts.PageLoadError = navigationResult.pageLoadError;
|
|
307
|
-
shouldHaltNavigations = true;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
LighthouseRunWarnings.push(...navigationResult.warnings);
|
|
312
|
-
Object.assign(artifacts, navigationResult.artifacts);
|
|
313
|
-
if (shouldHaltNavigations) break;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
return {artifacts: {...artifacts, LighthouseRunWarnings}};
|
|
241
|
+
return _computeNavigationResult(navigationContext, phaseState, navigateResult);
|
|
317
242
|
}
|
|
318
243
|
|
|
319
244
|
/**
|
|
@@ -369,11 +294,15 @@ async function navigationGather(page, requestor, options = {}) {
|
|
|
369
294
|
driver,
|
|
370
295
|
lhBrowser,
|
|
371
296
|
lhPage,
|
|
297
|
+
page,
|
|
372
298
|
resolvedConfig,
|
|
373
299
|
requestor: normalizedRequestor,
|
|
300
|
+
computedCache: new Map(),
|
|
374
301
|
};
|
|
375
302
|
const {baseArtifacts} = await _setup(context);
|
|
376
|
-
|
|
303
|
+
|
|
304
|
+
const artifacts = await _navigation({...context, baseArtifacts});
|
|
305
|
+
|
|
377
306
|
await _cleanup(context);
|
|
378
307
|
|
|
379
308
|
return finalizeArtifacts(baseArtifacts, artifacts);
|
|
@@ -386,9 +315,7 @@ async function navigationGather(page, requestor, options = {}) {
|
|
|
386
315
|
export {
|
|
387
316
|
navigationGather,
|
|
388
317
|
_setup,
|
|
389
|
-
_setupNavigation,
|
|
390
318
|
_navigate,
|
|
391
319
|
_navigation,
|
|
392
|
-
_navigations,
|
|
393
320
|
_cleanup,
|
|
394
321
|
};
|