lighthouse 11.6.0-dev.20240225 → 11.6.0-dev.20240226
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/core/gather/driver/execution-context.d.ts +2 -1
- package/core/gather/driver/execution-context.js +9 -9
- package/core/gather/driver/wait-for-condition.js +4 -2
- package/core/gather/navigation-runner.js +37 -38
- package/core/gather/snapshot-runner.js +25 -25
- package/core/gather/timespan-runner.js +24 -25
- package/core/lib/network-recorder.js +1 -1
- package/package.json +1 -1
|
@@ -53,9 +53,10 @@ export class ExecutionContext {
|
|
|
53
53
|
* page without isolation.
|
|
54
54
|
* @param {string} expression
|
|
55
55
|
* @param {number|undefined} contextId
|
|
56
|
+
* @param {number} timeout
|
|
56
57
|
* @return {Promise<*>}
|
|
57
58
|
*/
|
|
58
|
-
_evaluateInContext(expression: string, contextId: number | undefined): Promise<any>;
|
|
59
|
+
_evaluateInContext(expression: string, contextId: number | undefined, timeout: number): Promise<any>;
|
|
59
60
|
/**
|
|
60
61
|
* Note: Prefer `evaluate` instead.
|
|
61
62
|
* Evaluate an expression in the context of the current page. If useIsolation is true, the expression
|
|
@@ -80,15 +80,10 @@ class ExecutionContext {
|
|
|
80
80
|
* page without isolation.
|
|
81
81
|
* @param {string} expression
|
|
82
82
|
* @param {number|undefined} contextId
|
|
83
|
+
* @param {number} timeout
|
|
83
84
|
* @return {Promise<*>}
|
|
84
85
|
*/
|
|
85
|
-
async _evaluateInContext(expression, contextId) {
|
|
86
|
-
// Use a higher than default timeout if the user hasn't specified a specific timeout.
|
|
87
|
-
// Otherwise, use whatever was requested.
|
|
88
|
-
const timeout = this._session.hasNextProtocolTimeout() ?
|
|
89
|
-
this._session.getNextProtocolTimeout() :
|
|
90
|
-
60000;
|
|
91
|
-
|
|
86
|
+
async _evaluateInContext(expression, contextId, timeout) {
|
|
92
87
|
// `__lighthouseExecutionContextUniqueIdentifier` is only used by the FullPageScreenshot gatherer.
|
|
93
88
|
// See `getNodeDetails` in page-functions.
|
|
94
89
|
const uniqueExecutionContextIdentifier = contextId === undefined ?
|
|
@@ -166,17 +161,22 @@ class ExecutionContext {
|
|
|
166
161
|
* @return {Promise<*>}
|
|
167
162
|
*/
|
|
168
163
|
async evaluateAsync(expression, options = {}) {
|
|
164
|
+
// Use a higher than default timeout if the user hasn't specified a specific timeout.
|
|
165
|
+
// Otherwise, use whatever was requested.
|
|
166
|
+
const timeout = this._session.hasNextProtocolTimeout() ?
|
|
167
|
+
this._session.getNextProtocolTimeout() :
|
|
168
|
+
60000;
|
|
169
169
|
const contextId = options.useIsolation ? await this._getOrCreateIsolatedContextId() : undefined;
|
|
170
170
|
|
|
171
171
|
try {
|
|
172
172
|
// `await` is not redundant here because we want to `catch` the async errors
|
|
173
|
-
return await this._evaluateInContext(expression, contextId);
|
|
173
|
+
return await this._evaluateInContext(expression, contextId, timeout);
|
|
174
174
|
} catch (err) {
|
|
175
175
|
// If we were using isolation and the context disappeared on us, retry one more time.
|
|
176
176
|
if (contextId && err.message.includes('Cannot find context')) {
|
|
177
177
|
this.clearContextId();
|
|
178
178
|
const freshContextId = await this._getOrCreateIsolatedContextId();
|
|
179
|
-
return this._evaluateInContext(expression, freshContextId);
|
|
179
|
+
return this._evaluateInContext(expression, freshContextId, timeout);
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
throw err;
|
|
@@ -497,8 +497,10 @@ async function waitForFullyLoaded(session, networkMonitor, options) {
|
|
|
497
497
|
log.warn('waitFor', 'Timed out waiting for page load. Checking if page is hung...');
|
|
498
498
|
if (await isPageHung(session)) {
|
|
499
499
|
log.warn('waitFor', 'Page appears to be hung, killing JavaScript...');
|
|
500
|
-
await
|
|
501
|
-
|
|
500
|
+
// We don't await these, as we want to exit with PAGE_HUNG
|
|
501
|
+
void session.sendCommand('Emulation.setScriptExecutionDisabled', {value: true})
|
|
502
|
+
.catch(_ => {});
|
|
503
|
+
void session.sendCommand('Runtime.terminateExecution').catch(_ => {});
|
|
502
504
|
throw new LighthouseError(LighthouseError.errors.PAGE_HUNG);
|
|
503
505
|
}
|
|
504
506
|
|
|
@@ -265,44 +265,43 @@ async function navigationGather(page, requestor, options = {}) {
|
|
|
265
265
|
const isCallback = typeof requestor === 'function';
|
|
266
266
|
|
|
267
267
|
const runnerOptions = {resolvedConfig, computedCache};
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
);
|
|
268
|
+
|
|
269
|
+
const gatherFn = async () => {
|
|
270
|
+
const normalizedRequestor = isCallback ? requestor : UrlUtils.normalizeUrl(requestor);
|
|
271
|
+
|
|
272
|
+
/** @type {LH.Puppeteer.Browser|undefined} */
|
|
273
|
+
let lhBrowser = undefined;
|
|
274
|
+
/** @type {LH.Puppeteer.Page|undefined} */
|
|
275
|
+
let lhPage = undefined;
|
|
276
|
+
|
|
277
|
+
// For navigation mode, we shouldn't connect to a browser in audit mode,
|
|
278
|
+
// therefore we connect to the browser in the gatherFn callback.
|
|
279
|
+
if (!page) {
|
|
280
|
+
const {hostname = DEFAULT_HOSTNAME, port = DEFAULT_PORT} = flags;
|
|
281
|
+
lhBrowser = await puppeteer.connect({browserURL: `http://${hostname}:${port}`, defaultViewport: null});
|
|
282
|
+
lhPage = await lhBrowser.newPage();
|
|
283
|
+
page = lhPage;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const driver = new Driver(page);
|
|
287
|
+
const context = {
|
|
288
|
+
driver,
|
|
289
|
+
lhBrowser,
|
|
290
|
+
lhPage,
|
|
291
|
+
page,
|
|
292
|
+
resolvedConfig,
|
|
293
|
+
requestor: normalizedRequestor,
|
|
294
|
+
computedCache,
|
|
295
|
+
};
|
|
296
|
+
const {baseArtifacts} = await _setup(context);
|
|
297
|
+
|
|
298
|
+
const artifacts = await _navigation({...context, baseArtifacts});
|
|
299
|
+
|
|
300
|
+
await _cleanup(context);
|
|
301
|
+
|
|
302
|
+
return finalizeArtifacts(baseArtifacts, artifacts);
|
|
303
|
+
};
|
|
304
|
+
const artifacts = await Runner.gather(gatherFn, runnerOptions);
|
|
306
305
|
return {artifacts, runnerOptions};
|
|
307
306
|
}
|
|
308
307
|
|
|
@@ -30,35 +30,35 @@ async function snapshotGather(page, options = {}) {
|
|
|
30
30
|
const url = await driver.url();
|
|
31
31
|
|
|
32
32
|
const runnerOptions = {resolvedConfig, computedCache};
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
|
|
34
|
+
const gatherFn = async () => {
|
|
35
|
+
const baseArtifacts =
|
|
36
36
|
await getBaseArtifacts(resolvedConfig, driver, {gatherMode: 'snapshot'});
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
baseArtifacts.URL = {
|
|
38
|
+
finalDisplayedUrl: url,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const artifactDefinitions = resolvedConfig.artifacts || [];
|
|
42
|
+
const artifactState = getEmptyArtifactState();
|
|
43
|
+
await collectPhaseArtifacts({
|
|
44
|
+
phase: 'getArtifact',
|
|
45
|
+
gatherMode: 'snapshot',
|
|
46
|
+
driver,
|
|
47
|
+
page,
|
|
48
|
+
baseArtifacts,
|
|
49
|
+
artifactDefinitions,
|
|
50
|
+
artifactState,
|
|
51
|
+
computedCache,
|
|
52
|
+
settings: resolvedConfig.settings,
|
|
53
|
+
});
|
|
40
54
|
|
|
41
|
-
|
|
42
|
-
const artifactState = getEmptyArtifactState();
|
|
43
|
-
await collectPhaseArtifacts({
|
|
44
|
-
phase: 'getArtifact',
|
|
45
|
-
gatherMode: 'snapshot',
|
|
46
|
-
driver,
|
|
47
|
-
page,
|
|
48
|
-
baseArtifacts,
|
|
49
|
-
artifactDefinitions,
|
|
50
|
-
artifactState,
|
|
51
|
-
computedCache,
|
|
52
|
-
settings: resolvedConfig.settings,
|
|
53
|
-
});
|
|
55
|
+
await driver.disconnect();
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
const artifacts = await awaitArtifacts(artifactState);
|
|
58
|
+
return finalizeArtifacts(baseArtifacts, artifacts);
|
|
59
|
+
};
|
|
56
60
|
|
|
57
|
-
|
|
58
|
-
return finalizeArtifacts(baseArtifacts, artifacts);
|
|
59
|
-
},
|
|
60
|
-
runnerOptions
|
|
61
|
-
);
|
|
61
|
+
const artifacts = await Runner.gather(gatherFn, runnerOptions);
|
|
62
62
|
return {artifacts, runnerOptions};
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -72,31 +72,30 @@ async function startTimespanGather(page, options = {}) {
|
|
|
72
72
|
const finalDisplayedUrl = await driver.url();
|
|
73
73
|
|
|
74
74
|
const runnerOptions = {resolvedConfig, computedCache};
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
);
|
|
75
|
+
const gatherFn = async () => {
|
|
76
|
+
baseArtifacts.URL = {finalDisplayedUrl};
|
|
77
|
+
|
|
78
|
+
await collectPhaseArtifacts({phase: 'stopSensitiveInstrumentation', ...phaseOptions});
|
|
79
|
+
await collectPhaseArtifacts({phase: 'stopInstrumentation', ...phaseOptions});
|
|
80
|
+
|
|
81
|
+
// bf-cache-failures can emit `Page.frameNavigated` at the end of the run.
|
|
82
|
+
// This can cause us to issue protocol commands after the target closes.
|
|
83
|
+
// We should disable our `Page.frameNavigated` handlers before that.
|
|
84
|
+
await disableAsyncStacks();
|
|
85
|
+
|
|
86
|
+
driver.defaultSession.off('Page.frameNavigated', onFrameNavigated);
|
|
87
|
+
if (pageNavigationDetected) {
|
|
88
|
+
baseArtifacts.LighthouseRunWarnings.push(str_(UIStrings.warningNavigationDetected));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
await collectPhaseArtifacts({phase: 'getArtifact', ...phaseOptions});
|
|
92
|
+
await driver.disconnect();
|
|
93
|
+
|
|
94
|
+
const artifacts = await awaitArtifacts(artifactState);
|
|
95
|
+
return finalizeArtifacts(baseArtifacts, artifacts);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const artifacts = await Runner.gather(gatherFn, runnerOptions);
|
|
100
99
|
return {artifacts, runnerOptions};
|
|
101
100
|
},
|
|
102
101
|
};
|
|
@@ -257,7 +257,7 @@ class NetworkRecorder extends RequestEventEmitter {
|
|
|
257
257
|
let candidates = recordsByURL.get(initiatorURL) || [];
|
|
258
258
|
// The (valid) initiator must come before the initiated request.
|
|
259
259
|
candidates = candidates.filter(c => {
|
|
260
|
-
return c.responseHeadersEndTime <= record.
|
|
260
|
+
return c.responseHeadersEndTime <= record.rendererStartTime &&
|
|
261
261
|
c.finished && !c.failed;
|
|
262
262
|
});
|
|
263
263
|
if (candidates.length > 1) {
|
package/package.json
CHANGED