lighthouse 9.3.1-dev.20220209 → 9.3.1-dev.20220210
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/dist/report/bundle.esm.js +1 -4
- package/dist/report/flow.js +2 -2
- package/dist/report/standalone.js +2 -2
- package/lighthouse-cli/run.js +1 -1
- package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +46 -26
- package/lighthouse-core/fraggle-rock/user-flow.js +8 -6
- package/lighthouse-core/gather/driver/navigation.js +29 -10
- package/lighthouse-core/gather/driver/network-monitor.js +8 -6
- package/lighthouse-core/gather/driver/prepare.js +13 -7
- package/lighthouse-core/gather/gather-runner.js +1 -1
- package/package.json +1 -1
- package/report/assets/templates.html +0 -3
- package/report/renderer/components.js +1 -1
- package/report/renderer/report-ui-features.js +0 -3
- package/types/global-lh.d.ts +1 -0
package/lighthouse-cli/run.js
CHANGED
|
@@ -208,7 +208,7 @@ async function runLighthouseWithFraggleRock(url, flags, config, launchedChrome)
|
|
|
208
208
|
const page = await browser.newPage();
|
|
209
209
|
flags.channel = 'fraggle-rock-cli';
|
|
210
210
|
const configContext = {configPath: flags.configPath, settingsOverrides: flags};
|
|
211
|
-
return fraggleRock.navigation(
|
|
211
|
+
return fraggleRock.navigation(url, {page, config, configContext});
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
/**
|
|
@@ -35,7 +35,7 @@ const NetworkRecords = require('../../computed/network-records.js');
|
|
|
35
35
|
* @property {Driver} driver
|
|
36
36
|
* @property {LH.Config.FRConfig} config
|
|
37
37
|
* @property {LH.Config.NavigationDefn} navigation
|
|
38
|
-
* @property {
|
|
38
|
+
* @property {LH.NavigationRequestor} requestor
|
|
39
39
|
* @property {LH.FRBaseArtifacts} baseArtifacts
|
|
40
40
|
* @property {Map<string, LH.ArbitraryEqualityMap>} computedCache
|
|
41
41
|
* @property {InternalOptions} [options]
|
|
@@ -44,17 +44,17 @@ const NetworkRecords = require('../../computed/network-records.js');
|
|
|
44
44
|
/** @typedef {Omit<Parameters<typeof collectPhaseArtifacts>[0], 'phase'>} PhaseState */
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
|
-
* @param {{driver: Driver, config: LH.Config.FRConfig,
|
|
47
|
+
* @param {{driver: Driver, config: LH.Config.FRConfig, requestor: LH.NavigationRequestor, options?: InternalOptions}} args
|
|
48
48
|
* @return {Promise<{baseArtifacts: LH.FRBaseArtifacts}>}
|
|
49
49
|
*/
|
|
50
|
-
async function _setup({driver, config,
|
|
50
|
+
async function _setup({driver, config, requestor, options}) {
|
|
51
51
|
await driver.connect();
|
|
52
52
|
if (!options?.skipAboutBlank) {
|
|
53
53
|
await gotoURL(driver, defaultNavigationConfig.blankPage, {waitUntil: ['navigated']});
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
const baseArtifacts = await getBaseArtifacts(config, driver, {gatherMode: 'navigation'});
|
|
57
|
-
baseArtifacts.URL.requestedUrl =
|
|
57
|
+
if (typeof requestor === 'string') baseArtifacts.URL.requestedUrl = requestor;
|
|
58
58
|
|
|
59
59
|
await prepare.prepareTargetForNavigationMode(driver, config.settings);
|
|
60
60
|
|
|
@@ -65,7 +65,7 @@ async function _setup({driver, config, requestedUrl, options}) {
|
|
|
65
65
|
* @param {NavigationContext} navigationContext
|
|
66
66
|
* @return {Promise<{warnings: Array<LH.IcuMessage>}>}
|
|
67
67
|
*/
|
|
68
|
-
async function _setupNavigation({
|
|
68
|
+
async function _setupNavigation({requestor, driver, navigation, config, options}) {
|
|
69
69
|
if (!options?.skipAboutBlank) {
|
|
70
70
|
await gotoURL(driver, navigation.blankPage, {...navigation, waitUntil: ['navigated']});
|
|
71
71
|
}
|
|
@@ -74,7 +74,7 @@ async function _setupNavigation({requestedUrl, driver, navigation, config, optio
|
|
|
74
74
|
config.settings,
|
|
75
75
|
{
|
|
76
76
|
...navigation,
|
|
77
|
-
|
|
77
|
+
requestor,
|
|
78
78
|
}
|
|
79
79
|
);
|
|
80
80
|
|
|
@@ -90,25 +90,25 @@ async function _cleanupNavigation({driver}) {
|
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
92
|
* @param {NavigationContext} navigationContext
|
|
93
|
-
* @return {Promise<{finalUrl: string, navigationError: LH.LighthouseError | undefined, warnings: Array<LH.IcuMessage>}>}
|
|
93
|
+
* @return {Promise<{requestedUrl: string, finalUrl: string, navigationError: LH.LighthouseError | undefined, warnings: Array<LH.IcuMessage>}>}
|
|
94
94
|
*/
|
|
95
95
|
async function _navigate(navigationContext) {
|
|
96
|
-
const {driver, config,
|
|
96
|
+
const {driver, config, requestor} = navigationContext;
|
|
97
97
|
|
|
98
98
|
try {
|
|
99
|
-
const {finalUrl, warnings} = await gotoURL(driver,
|
|
99
|
+
const {requestedUrl, finalUrl, warnings} = await gotoURL(driver, requestor, {
|
|
100
100
|
...navigationContext.navigation,
|
|
101
101
|
debugNavigation: config.settings.debugNavigation,
|
|
102
102
|
maxWaitForFcp: config.settings.maxWaitForFcp,
|
|
103
103
|
maxWaitForLoad: config.settings.maxWaitForLoad,
|
|
104
104
|
waitUntil: navigationContext.navigation.pauseAfterFcpMs ? ['fcp', 'load'] : ['load'],
|
|
105
105
|
});
|
|
106
|
-
|
|
107
|
-
return {finalUrl, navigationError: undefined, warnings};
|
|
106
|
+
return {requestedUrl, finalUrl, navigationError: undefined, warnings};
|
|
108
107
|
} catch (err) {
|
|
109
108
|
if (!(err instanceof LighthouseError)) throw err;
|
|
110
109
|
if (err.code !== 'NO_FCP' && err.code !== 'PAGE_HUNG') throw err;
|
|
111
|
-
|
|
110
|
+
if (typeof requestor !== 'string') throw err;
|
|
111
|
+
return {requestedUrl: requestor, finalUrl: requestor, navigationError: err, warnings: []};
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
|
|
@@ -152,7 +152,7 @@ async function _collectDebugData(navigationContext, phaseState) {
|
|
|
152
152
|
* @param {PhaseState} phaseState
|
|
153
153
|
* @param {Awaited<ReturnType<typeof _setupNavigation>>} setupResult
|
|
154
154
|
* @param {Awaited<ReturnType<typeof _navigate>>} navigateResult
|
|
155
|
-
* @return {Promise<{finalUrl: string, artifacts: Partial<LH.GathererArtifacts>, warnings: Array<LH.IcuMessage>, pageLoadError: LH.LighthouseError | undefined}>}
|
|
155
|
+
* @return {Promise<{requestedUrl: string, finalUrl: string, artifacts: Partial<LH.GathererArtifacts>, warnings: Array<LH.IcuMessage>, pageLoadError: LH.LighthouseError | undefined}>}
|
|
156
156
|
*/
|
|
157
157
|
async function _computeNavigationResult(
|
|
158
158
|
navigationContext,
|
|
@@ -174,7 +174,7 @@ async function _computeNavigationResult(
|
|
|
174
174
|
if (pageLoadError) {
|
|
175
175
|
const locale = navigationContext.config.settings.locale;
|
|
176
176
|
const localizedMessage = format.getFormatted(pageLoadError.friendlyMessage, locale);
|
|
177
|
-
log.error('NavigationRunner', localizedMessage,
|
|
177
|
+
log.error('NavigationRunner', localizedMessage, navigateResult.requestedUrl);
|
|
178
178
|
|
|
179
179
|
/** @type {Partial<LH.GathererArtifacts>} */
|
|
180
180
|
const artifacts = {};
|
|
@@ -183,6 +183,7 @@ async function _computeNavigationResult(
|
|
|
183
183
|
if (debugData.trace) artifacts.traces = {[pageLoadErrorId]: debugData.trace};
|
|
184
184
|
|
|
185
185
|
return {
|
|
186
|
+
requestedUrl: navigateResult.requestedUrl,
|
|
186
187
|
finalUrl,
|
|
187
188
|
pageLoadError,
|
|
188
189
|
artifacts,
|
|
@@ -192,7 +193,13 @@ async function _computeNavigationResult(
|
|
|
192
193
|
await collectPhaseArtifacts({phase: 'getArtifact', ...phaseState});
|
|
193
194
|
|
|
194
195
|
const artifacts = await awaitArtifacts(phaseState.artifactState);
|
|
195
|
-
return {
|
|
196
|
+
return {
|
|
197
|
+
requestedUrl: navigateResult.requestedUrl,
|
|
198
|
+
finalUrl,
|
|
199
|
+
artifacts,
|
|
200
|
+
warnings,
|
|
201
|
+
pageLoadError: undefined,
|
|
202
|
+
};
|
|
196
203
|
}
|
|
197
204
|
}
|
|
198
205
|
|
|
@@ -224,10 +231,10 @@ async function _navigation(navigationContext) {
|
|
|
224
231
|
}
|
|
225
232
|
|
|
226
233
|
/**
|
|
227
|
-
* @param {{driver: Driver, config: LH.Config.FRConfig,
|
|
234
|
+
* @param {{driver: Driver, config: LH.Config.FRConfig, requestor: LH.NavigationRequestor; baseArtifacts: LH.FRBaseArtifacts, computedCache: NavigationContext['computedCache'], options?: InternalOptions}} args
|
|
228
235
|
* @return {Promise<{artifacts: Partial<LH.FRArtifacts & LH.FRBaseArtifacts>}>}
|
|
229
236
|
*/
|
|
230
|
-
async function _navigations({driver, config,
|
|
237
|
+
async function _navigations({driver, config, requestor, baseArtifacts, computedCache, options}) {
|
|
231
238
|
if (!config.navigations) throw new Error('No navigations configured');
|
|
232
239
|
|
|
233
240
|
/** @type {Partial<LH.FRArtifacts & LH.FRBaseArtifacts>} */
|
|
@@ -239,7 +246,7 @@ async function _navigations({driver, config, requestedUrl, baseArtifacts, comput
|
|
|
239
246
|
const navigationContext = {
|
|
240
247
|
driver,
|
|
241
248
|
navigation,
|
|
242
|
-
|
|
249
|
+
requestor,
|
|
243
250
|
config,
|
|
244
251
|
baseArtifacts,
|
|
245
252
|
computedCache,
|
|
@@ -254,7 +261,10 @@ async function _navigations({driver, config, requestedUrl, baseArtifacts, comput
|
|
|
254
261
|
shouldHaltNavigations = true;
|
|
255
262
|
}
|
|
256
263
|
|
|
257
|
-
artifacts.URL = {
|
|
264
|
+
artifacts.URL = {
|
|
265
|
+
requestedUrl: navigationResult.requestedUrl,
|
|
266
|
+
finalUrl: navigationResult.finalUrl,
|
|
267
|
+
};
|
|
258
268
|
}
|
|
259
269
|
|
|
260
270
|
LighthouseRunWarnings.push(...navigationResult.warnings);
|
|
@@ -266,33 +276,43 @@ async function _navigations({driver, config, requestedUrl, baseArtifacts, comput
|
|
|
266
276
|
}
|
|
267
277
|
|
|
268
278
|
/**
|
|
269
|
-
* @param {{requestedUrl
|
|
279
|
+
* @param {{requestedUrl?: string, driver: Driver, config: LH.Config.FRConfig}} args
|
|
270
280
|
*/
|
|
271
281
|
async function _cleanup({requestedUrl, driver, config}) {
|
|
272
|
-
const didResetStorage = !config.settings.disableStorageReset;
|
|
282
|
+
const didResetStorage = !config.settings.disableStorageReset && requestedUrl;
|
|
273
283
|
if (didResetStorage) await storage.clearDataForOrigin(driver.defaultSession, requestedUrl);
|
|
274
284
|
|
|
275
285
|
await driver.disconnect();
|
|
276
286
|
}
|
|
277
287
|
|
|
278
288
|
/**
|
|
279
|
-
* @param {
|
|
289
|
+
* @param {LH.NavigationRequestor} requestor
|
|
290
|
+
* @param {{page: import('puppeteer').Page, config?: LH.Config.Json, configContext?: LH.Config.FRContext}} options
|
|
280
291
|
* @return {Promise<LH.RunnerResult|undefined>}
|
|
281
292
|
*/
|
|
282
|
-
async function navigation(options) {
|
|
283
|
-
const {
|
|
293
|
+
async function navigation(requestor, options) {
|
|
294
|
+
const {page, configContext = {}} = options;
|
|
284
295
|
const {config} = initializeConfig(options.config, {...configContext, gatherMode: 'navigation'});
|
|
285
296
|
const computedCache = new Map();
|
|
286
297
|
const internalOptions = {
|
|
287
298
|
skipAboutBlank: configContext.skipAboutBlank,
|
|
288
299
|
};
|
|
289
300
|
|
|
301
|
+
// We can't trigger the navigation through user interaction if we reset the page before starting.
|
|
302
|
+
if (typeof requestor !== 'string') {
|
|
303
|
+
internalOptions.skipAboutBlank = true;
|
|
304
|
+
}
|
|
305
|
+
|
|
290
306
|
const runnerOptions = {config, computedCache};
|
|
291
307
|
const artifacts = await Runner.gather(
|
|
292
308
|
async () => {
|
|
293
309
|
const driver = new Driver(page);
|
|
294
|
-
const
|
|
295
|
-
|
|
310
|
+
const context = {
|
|
311
|
+
driver,
|
|
312
|
+
config,
|
|
313
|
+
requestor: typeof requestor === 'string' ? URL.normalizeUrl(requestor) : requestor,
|
|
314
|
+
options: internalOptions,
|
|
315
|
+
};
|
|
296
316
|
const {baseArtifacts} = await _setup(context);
|
|
297
317
|
const {artifacts} = await _navigations({...context, baseArtifacts, computedCache});
|
|
298
318
|
await _cleanup(context);
|
|
@@ -54,11 +54,10 @@ class UserFlow {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
|
-
* @param {string} url
|
|
58
57
|
* @param {StepOptions=} stepOptions
|
|
59
58
|
*/
|
|
60
|
-
_getNextNavigationOptions(
|
|
61
|
-
const options = {
|
|
59
|
+
_getNextNavigationOptions(stepOptions) {
|
|
60
|
+
const options = {...this.options, ...stepOptions};
|
|
62
61
|
const configContext = {...options.configContext};
|
|
63
62
|
const settingsOverrides = {...configContext.settingsOverrides};
|
|
64
63
|
|
|
@@ -81,13 +80,16 @@ class UserFlow {
|
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
/**
|
|
84
|
-
* @param {
|
|
83
|
+
* @param {LH.NavigationRequestor} requestor
|
|
85
84
|
* @param {StepOptions=} stepOptions
|
|
86
85
|
*/
|
|
87
|
-
async navigate(
|
|
86
|
+
async navigate(requestor, stepOptions) {
|
|
88
87
|
if (this.currentTimespan) throw Error('Timespan already in progress');
|
|
89
88
|
|
|
90
|
-
const result = await navigation(
|
|
89
|
+
const result = await navigation(
|
|
90
|
+
requestor,
|
|
91
|
+
this._getNextNavigationOptions(stepOptions)
|
|
92
|
+
);
|
|
91
93
|
if (!result) throw Error('Navigation returned undefined');
|
|
92
94
|
|
|
93
95
|
const providedName = stepOptions?.stepName;
|
|
@@ -78,12 +78,14 @@ function resolveWaitForFullyLoadedOptions(options) {
|
|
|
78
78
|
* navigations.
|
|
79
79
|
*
|
|
80
80
|
* @param {LH.Gatherer.FRTransitionalDriver} driver
|
|
81
|
-
* @param {
|
|
81
|
+
* @param {LH.NavigationRequestor} requestor
|
|
82
82
|
* @param {NavigationOptions} options
|
|
83
|
-
* @return {Promise<{finalUrl: string, warnings: Array<LH.IcuMessage>}>}
|
|
83
|
+
* @return {Promise<{requestedUrl: string, finalUrl: string, warnings: Array<LH.IcuMessage>}>}
|
|
84
84
|
*/
|
|
85
|
-
async function gotoURL(driver,
|
|
86
|
-
const status =
|
|
85
|
+
async function gotoURL(driver, requestor, options) {
|
|
86
|
+
const status = typeof requestor === 'string' ?
|
|
87
|
+
{msg: `Navigating to ${requestor}`, id: 'lh:driver:navigate'} :
|
|
88
|
+
{msg: 'Navigating using a user defined function', id: 'lh:driver:navigate'};
|
|
87
89
|
log.time(status);
|
|
88
90
|
|
|
89
91
|
const session = driver.defaultSession;
|
|
@@ -94,9 +96,14 @@ async function gotoURL(driver, url, options) {
|
|
|
94
96
|
await session.sendCommand('Page.enable');
|
|
95
97
|
await session.sendCommand('Page.setLifecycleEventsEnabled', {enabled: true});
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
let waitForNavigationTriggered;
|
|
100
|
+
if (typeof requestor === 'string') {
|
|
101
|
+
// No timeout needed for Page.navigate. See https://github.com/GoogleChrome/lighthouse/pull/6413
|
|
102
|
+
session.setNextProtocolTimeout(Infinity);
|
|
103
|
+
waitForNavigationTriggered = session.sendCommand('Page.navigate', {url: requestor});
|
|
104
|
+
} else {
|
|
105
|
+
waitForNavigationTriggered = requestor();
|
|
106
|
+
}
|
|
100
107
|
|
|
101
108
|
const waitForNavigated = options.waitUntil.includes('navigated');
|
|
102
109
|
const waitForLoad = options.waitUntil.includes('load');
|
|
@@ -119,10 +126,21 @@ async function gotoURL(driver, url, options) {
|
|
|
119
126
|
|
|
120
127
|
const waitConditions = await Promise.all(waitConditionPromises);
|
|
121
128
|
const timedOut = waitConditions.some(condition => condition.timedOut);
|
|
122
|
-
const
|
|
129
|
+
const navigationUrls = await networkMonitor.getNavigationUrls();
|
|
130
|
+
|
|
131
|
+
let requestedUrl = navigationUrls.requestedUrl;
|
|
132
|
+
if (typeof requestor === 'string') {
|
|
133
|
+
if (requestor !== requestedUrl) {
|
|
134
|
+
log.error('Navigation', 'Provided URL did not match initial navigation URL');
|
|
135
|
+
}
|
|
136
|
+
requestedUrl = requestor;
|
|
137
|
+
}
|
|
138
|
+
if (!requestedUrl) throw Error('No navigations detected when running user defined requestor.');
|
|
139
|
+
|
|
140
|
+
const finalUrl = navigationUrls.finalUrl || requestedUrl;
|
|
123
141
|
|
|
124
142
|
// Bring `Page.navigate` errors back into the promise chain. See https://github.com/GoogleChrome/lighthouse/pull/6739.
|
|
125
|
-
await
|
|
143
|
+
await waitForNavigationTriggered;
|
|
126
144
|
await networkMonitor.disable();
|
|
127
145
|
|
|
128
146
|
if (options.debugNavigation) {
|
|
@@ -131,8 +149,9 @@ async function gotoURL(driver, url, options) {
|
|
|
131
149
|
|
|
132
150
|
log.timeEnd(status);
|
|
133
151
|
return {
|
|
152
|
+
requestedUrl,
|
|
134
153
|
finalUrl,
|
|
135
|
-
warnings: getNavigationWarnings({timedOut, finalUrl, requestedUrl
|
|
154
|
+
warnings: getNavigationWarnings({timedOut, finalUrl, requestedUrl}),
|
|
136
155
|
};
|
|
137
156
|
}
|
|
138
157
|
|
|
@@ -133,18 +133,20 @@ class NetworkMonitor {
|
|
|
133
133
|
this._sessions = new Map();
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
/** @return {Promise<string
|
|
137
|
-
async
|
|
136
|
+
/** @return {Promise<{requestedUrl?: string, finalUrl?: string}>} */
|
|
137
|
+
async getNavigationUrls() {
|
|
138
138
|
const frameNavigations = this._frameNavigations;
|
|
139
|
-
if (!frameNavigations.length) return
|
|
139
|
+
if (!frameNavigations.length) return {};
|
|
140
140
|
|
|
141
141
|
const resourceTreeResponse = await this._session.sendCommand('Page.getResourceTree');
|
|
142
142
|
const mainFrameId = resourceTreeResponse.frameTree.frame.id;
|
|
143
143
|
const mainFrameNavigations = frameNavigations.filter(frame => frame.id === mainFrameId);
|
|
144
|
-
|
|
145
|
-
if (!finalNavigation) log.warn('NetworkMonitor', 'No detected navigations');
|
|
144
|
+
if (!mainFrameNavigations.length) log.warn('NetworkMonitor', 'No detected navigations');
|
|
146
145
|
|
|
147
|
-
return
|
|
146
|
+
return {
|
|
147
|
+
requestedUrl: mainFrameNavigations[0]?.url,
|
|
148
|
+
finalUrl: mainFrameNavigations[mainFrameNavigations.length - 1]?.url,
|
|
149
|
+
};
|
|
148
150
|
}
|
|
149
151
|
|
|
150
152
|
/**
|
|
@@ -71,17 +71,17 @@ async function dismissJavaScriptDialogs(session) {
|
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
73
|
* @param {LH.Gatherer.FRProtocolSession} session
|
|
74
|
-
* @param {
|
|
74
|
+
* @param {string} url
|
|
75
75
|
* @return {Promise<{warnings: Array<LH.IcuMessage>}>}
|
|
76
76
|
*/
|
|
77
|
-
async function
|
|
77
|
+
async function resetStorageForUrl(session, url) {
|
|
78
78
|
/** @type {Array<LH.IcuMessage>} */
|
|
79
79
|
const warnings = [];
|
|
80
80
|
|
|
81
81
|
// Reset the storage and warn if there appears to be other important data.
|
|
82
|
-
const warning = await storage.getImportantStorageWarning(session,
|
|
82
|
+
const warning = await storage.getImportantStorageWarning(session, url);
|
|
83
83
|
if (warning) warnings.push(warning);
|
|
84
|
-
await storage.clearDataForOrigin(session,
|
|
84
|
+
await storage.clearDataForOrigin(session, url);
|
|
85
85
|
await storage.clearBrowserCaches(session);
|
|
86
86
|
|
|
87
87
|
return {warnings};
|
|
@@ -190,7 +190,7 @@ async function prepareTargetForNavigationMode(driver, settings) {
|
|
|
190
190
|
*
|
|
191
191
|
* @param {LH.Gatherer.FRProtocolSession} session
|
|
192
192
|
* @param {LH.Config.Settings} settings
|
|
193
|
-
* @param {Pick<LH.Config.NavigationDefn, 'disableThrottling'|'disableStorageReset'|'blockedUrlPatterns'> & {
|
|
193
|
+
* @param {Pick<LH.Config.NavigationDefn, 'disableThrottling'|'disableStorageReset'|'blockedUrlPatterns'> & {requestor: LH.NavigationRequestor}} navigation
|
|
194
194
|
* @return {Promise<{warnings: Array<LH.IcuMessage>}>}
|
|
195
195
|
*/
|
|
196
196
|
async function prepareTargetForIndividualNavigation(session, settings, navigation) {
|
|
@@ -200,9 +200,15 @@ async function prepareTargetForIndividualNavigation(session, settings, navigatio
|
|
|
200
200
|
/** @type {Array<LH.IcuMessage>} */
|
|
201
201
|
const warnings = [];
|
|
202
202
|
|
|
203
|
-
const
|
|
203
|
+
const {requestor} = navigation;
|
|
204
|
+
const shouldResetStorage =
|
|
205
|
+
!settings.disableStorageReset &&
|
|
206
|
+
!navigation.disableStorageReset &&
|
|
207
|
+
// Without prior knowledge of the destination, we cannot know which URL to clear storage for.
|
|
208
|
+
typeof requestor === 'string';
|
|
204
209
|
if (shouldResetStorage) {
|
|
205
|
-
const
|
|
210
|
+
const requestedUrl = requestor;
|
|
211
|
+
const {warnings: storageWarnings} = await resetStorageForUrl(session, requestedUrl);
|
|
206
212
|
warnings.push(...storageWarnings);
|
|
207
213
|
}
|
|
208
214
|
|
|
@@ -572,7 +572,7 @@ class GatherRunner {
|
|
|
572
572
|
driver.defaultSession,
|
|
573
573
|
passContext.settings,
|
|
574
574
|
{
|
|
575
|
-
|
|
575
|
+
requestor: passContext.url,
|
|
576
576
|
disableStorageReset: !passConfig.useThrottling,
|
|
577
577
|
disableThrottling: !passConfig.useThrottling,
|
|
578
578
|
blockedUrlPatterns: passConfig.blockedUrlPatterns,
|
package/package.json
CHANGED
|
@@ -349,7 +349,7 @@ function createGaugePwaComponent(dom) {
|
|
|
349
349
|
function createHeadingComponent(dom) {
|
|
350
350
|
const el0 = dom.createFragment();
|
|
351
351
|
const el1 = dom.createElement('style');
|
|
352
|
-
el1.append('\n /* CSS Fireworks. Originally by Eddie Lin\n https://codepen.io/paulirish/pen/yEVMbP\n */\n .lh-pyro {\n display: none;\n z-index: 1;\n pointer-events: none;\n }\n .lh-score100 .lh-pyro {\n display: block;\n }\n .lh-score100 .lh-lighthouse stop:first-child {\n stop-color: hsla(200, 12%, 95%, 0);\n }\n .lh-score100 .lh-lighthouse stop:last-child {\n stop-color: hsla(65, 81%, 76%, 1);\n }\n\n .lh-pyro > .lh-pyro-before, .lh-pyro > .lh-pyro-after {\n position: absolute;\n width: 5px;\n height: 5px;\n border-radius: 2.5px;\n box-shadow: 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff;\n animation: 1s bang ease-out infinite backwards, 1s gravity ease-in infinite backwards, 5s position linear infinite backwards;\n animation-delay: 1s, 1s, 1s;\n }\n\n .lh-pyro > .lh-pyro-after {\n animation-delay: 2.25s, 2.25s, 2.25s;\n animation-duration: 1.25s, 1.25s, 6.25s;\n }\n
|
|
352
|
+
el1.append('\n /* CSS Fireworks. Originally by Eddie Lin\n https://codepen.io/paulirish/pen/yEVMbP\n */\n .lh-pyro {\n display: none;\n z-index: 1;\n pointer-events: none;\n }\n .lh-score100 .lh-pyro {\n display: block;\n }\n .lh-score100 .lh-lighthouse stop:first-child {\n stop-color: hsla(200, 12%, 95%, 0);\n }\n .lh-score100 .lh-lighthouse stop:last-child {\n stop-color: hsla(65, 81%, 76%, 1);\n }\n\n .lh-pyro > .lh-pyro-before, .lh-pyro > .lh-pyro-after {\n position: absolute;\n width: 5px;\n height: 5px;\n border-radius: 2.5px;\n box-shadow: 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff;\n animation: 1s bang ease-out infinite backwards, 1s gravity ease-in infinite backwards, 5s position linear infinite backwards;\n animation-delay: 1s, 1s, 1s;\n }\n\n .lh-pyro > .lh-pyro-after {\n animation-delay: 2.25s, 2.25s, 2.25s;\n animation-duration: 1.25s, 1.25s, 6.25s;\n }\n\n @keyframes bang {\n to {\n box-shadow: -70px -115.67px #47ebbc, -28px -99.67px #eb47a4, 58px -31.67px #7eeb47, 13px -141.67px #eb47c5, -19px 6.33px #7347eb, -2px -74.67px #ebd247, 24px -151.67px #eb47e0, 57px -138.67px #b4eb47, -51px -104.67px #479eeb, 62px 8.33px #ebcf47, -93px 0.33px #d547eb, -16px -118.67px #47bfeb, 53px -84.67px #47eb83, 66px -57.67px #eb47bf, -93px -65.67px #91eb47, 30px -13.67px #86eb47, -2px -59.67px #83eb47, -44px 1.33px #eb47eb, 61px -58.67px #47eb73, 5px -22.67px #47e8eb, -66px -28.67px #ebe247, 42px -123.67px #eb5547, -75px 26.33px #7beb47, 15px -52.67px #a147eb, 36px -51.67px #eb8347, -38px -12.67px #eb5547, -46px -59.67px #47eb81, 78px -114.67px #eb47ba, 15px -156.67px #eb47bf, -36px 1.33px #eb4783, -72px -86.67px #eba147, 31px -46.67px #ebe247, -68px 29.33px #47e2eb, -55px 19.33px #ebe047, -56px 27.33px #4776eb, -13px -91.67px #eb5547, -47px -138.67px #47ebc7, -18px -96.67px #eb47ac, 11px -88.67px #4783eb, -67px -28.67px #47baeb, 53px 10.33px #ba47eb, 11px 19.33px #5247eb, -5px -11.67px #eb4791, -68px -4.67px #47eba7, 95px -37.67px #eb478b, -67px -162.67px #eb5d47, -54px -120.67px #eb6847, 49px -12.67px #ebe047, 88px 8.33px #47ebda, 97px 33.33px #eb8147, 6px -71.67px #ebbc47;\n }\n }\n @keyframes gravity {\n to {\n transform: translateY(80px);\n opacity: 0;\n }\n }\n @keyframes position {\n 0%, 19.9% {\n margin-top: 4%;\n margin-left: 47%;\n }\n 20%, 39.9% {\n margin-top: 7%;\n margin-left: 30%;\n }\n 40%, 59.9% {\n margin-top: 6%;\n margin-left: 70%;\n }\n 60%, 79.9% {\n margin-top: 3%;\n margin-left: 20%;\n }\n 80%, 99.9% {\n margin-top: 3%;\n margin-left: 80%;\n }\n }\n ');
|
|
353
353
|
el0.append(el1);
|
|
354
354
|
const el2 = dom.createElement('div', 'lh-header-container');
|
|
355
355
|
const el3 = dom.createElement('div', 'lh-scores-wrapper-placeholder');
|
|
@@ -180,9 +180,6 @@ export class ReportUIFeatures {
|
|
|
180
180
|
_enableFireworks() {
|
|
181
181
|
const scoresContainer = this._dom.find('.lh-scores-container', this._dom.rootEl);
|
|
182
182
|
scoresContainer.classList.add('lh-score100');
|
|
183
|
-
scoresContainer.addEventListener('click', _ => {
|
|
184
|
-
scoresContainer.classList.toggle('lh-fireworks-paused');
|
|
185
|
-
});
|
|
186
183
|
}
|
|
187
184
|
|
|
188
185
|
_setupMediaQueryListeners() {
|
package/types/global-lh.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ import Treemap_ from './lhr/treemap';
|
|
|
26
26
|
declare global {
|
|
27
27
|
module LH {
|
|
28
28
|
export type ArbitraryEqualityMap = ArbitraryEqualityMap_;
|
|
29
|
+
export type NavigationRequestor = string | (() => Promise<void> | void);
|
|
29
30
|
|
|
30
31
|
// artifacts.d.ts
|
|
31
32
|
export import Artifacts = Artifacts_.Artifacts;
|