lighthouse 11.2.0-dev.20231017 → 11.2.0-dev.20231019
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/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/gatherers/inspector-issues.js +1 -0
- 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/dist/report/bundle.esm.js +4 -4
- package/dist/report/flow.js +7 -7
- package/dist/report/standalone.js +5 -5
- package/package.json +5 -5
- package/report/renderer/performance-category-renderer.js +2 -1
- package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +1 -0
- package/types/artifacts.d.ts +1 -0
- package/types/config.d.ts +0 -38
- package/types/internal/smokehouse.d.ts +10 -5
|
@@ -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
|
};
|
|
@@ -15,12 +15,11 @@ export function getInterstitialError(mainRecord: LH.Artifacts.NetworkRequest | u
|
|
|
15
15
|
* Returns an error if the page load should be considered failed, e.g. from a
|
|
16
16
|
* main document request failure, a security issue, etc.
|
|
17
17
|
* @param {LH.LighthouseError|undefined} navigationError
|
|
18
|
-
* @param {{url: string,
|
|
18
|
+
* @param {{url: string, networkRecords: Array<LH.Artifacts.NetworkRequest>, warnings: Array<string | LH.IcuMessage>}} context
|
|
19
19
|
* @return {LH.LighthouseError|undefined}
|
|
20
20
|
*/
|
|
21
21
|
export function getPageLoadError(navigationError: LH.LighthouseError | undefined, context: {
|
|
22
22
|
url: string;
|
|
23
|
-
loadFailureMode: LH.Config.SharedPassNavigationJson['loadFailureMode'];
|
|
24
23
|
networkRecords: Array<LH.Artifacts.NetworkRequest>;
|
|
25
24
|
warnings: Array<string | LH.IcuMessage>;
|
|
26
25
|
}): LH.LighthouseError | undefined;
|
|
@@ -113,11 +113,11 @@ function getNonHtmlError(finalRecord) {
|
|
|
113
113
|
* Returns an error if the page load should be considered failed, e.g. from a
|
|
114
114
|
* main document request failure, a security issue, etc.
|
|
115
115
|
* @param {LH.LighthouseError|undefined} navigationError
|
|
116
|
-
* @param {{url: string,
|
|
116
|
+
* @param {{url: string, networkRecords: Array<LH.Artifacts.NetworkRequest>, warnings: Array<string | LH.IcuMessage>}} context
|
|
117
117
|
* @return {LH.LighthouseError|undefined}
|
|
118
118
|
*/
|
|
119
119
|
function getPageLoadError(navigationError, context) {
|
|
120
|
-
const {url,
|
|
120
|
+
const {url, networkRecords} = context;
|
|
121
121
|
/** @type {LH.Artifacts.NetworkRequest|undefined} */
|
|
122
122
|
let mainRecord = NetworkAnalyzer.findResourceForUrl(networkRecords, url);
|
|
123
123
|
|
|
@@ -148,10 +148,6 @@ function getPageLoadError(navigationError, context) {
|
|
|
148
148
|
const interstitialError = getInterstitialError(mainRecord, networkRecords);
|
|
149
149
|
const nonHtmlError = getNonHtmlError(finalRecord);
|
|
150
150
|
|
|
151
|
-
// Check to see if we need to ignore the page load failure.
|
|
152
|
-
// e.g. When the driver is offline, the load will fail without page offline support.
|
|
153
|
-
if (loadFailureMode === 'ignore') return;
|
|
154
|
-
|
|
155
151
|
// We want to special-case the interstitial beyond FAILED_DOCUMENT_REQUEST. See https://github.com/GoogleChrome/lighthouse/pull/8865#issuecomment-497507618
|
|
156
152
|
if (interstitialError) return interstitialError;
|
|
157
153
|
|