lighthouse 9.5.0-dev.20230101 → 9.5.0-dev.20230103
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/config/config-helpers.js +1 -1
- package/core/config/config.js +17 -17
- package/core/config/filters.js +22 -20
- package/core/config/validation.js +7 -7
- package/core/gather/base-artifacts.js +3 -3
- package/core/gather/driver/prepare.js +9 -5
- package/core/gather/driver/storage.js +32 -8
- package/core/gather/navigation-runner.js +36 -27
- package/core/gather/snapshot-runner.js +7 -6
- package/core/gather/timespan-runner.js +7 -7
- package/core/index.js +2 -2
- package/core/legacy/config/config.js +2 -2
- package/core/runner.js +16 -16
- package/core/user-flow.js +2 -2
- package/dist/report/bundle.esm.js +2 -1
- package/package.json +4 -4
- package/report/renderer/topbar-features.js +2 -1
- package/shared/localization/locales/en-US.json +6 -0
- package/shared/localization/locales/en-XL.json +6 -0
- package/types/gatherer.d.ts +1 -1
|
@@ -120,7 +120,7 @@ const mergeConfigFragment = _mergeConfigFragment;
|
|
|
120
120
|
* Merge an array of items by a caller-defined key. `mergeConfigFragment` is used to merge any items
|
|
121
121
|
* with a matching key.
|
|
122
122
|
*
|
|
123
|
-
* @template T
|
|
123
|
+
* @template {Record<string, any>} T
|
|
124
124
|
* @param {Array<T>|null|undefined} baseArray
|
|
125
125
|
* @param {Array<T>|null|undefined} extensionArray
|
|
126
126
|
* @param {(item: T) => string} keyFn
|
package/core/config/config.js
CHANGED
|
@@ -238,7 +238,7 @@ function resolveFakeNavigations(artifactDefns, settings) {
|
|
|
238
238
|
* @param {LH.Gatherer.GatherMode} gatherMode
|
|
239
239
|
* @param {LH.Config.Json=} configJSON
|
|
240
240
|
* @param {LH.Flags=} flags
|
|
241
|
-
* @return {Promise<{
|
|
241
|
+
* @return {Promise<{resolvedConfig: LH.Config.FRConfig, warnings: string[]}>}
|
|
242
242
|
*/
|
|
243
243
|
async function initializeConfig(gatherMode, configJSON, flags = {}) {
|
|
244
244
|
const status = {msg: 'Initialize config', id: 'lh:config'};
|
|
@@ -257,7 +257,7 @@ async function initializeConfig(gatherMode, configJSON, flags = {}) {
|
|
|
257
257
|
const navigations = resolveFakeNavigations(artifacts, settings);
|
|
258
258
|
|
|
259
259
|
/** @type {LH.Config.FRConfig} */
|
|
260
|
-
let
|
|
260
|
+
let resolvedConfig = {
|
|
261
261
|
artifacts,
|
|
262
262
|
navigations,
|
|
263
263
|
audits: await resolveAuditsToDefns(configWorkingCopy.audits, configDir),
|
|
@@ -266,25 +266,25 @@ async function initializeConfig(gatherMode, configJSON, flags = {}) {
|
|
|
266
266
|
settings,
|
|
267
267
|
};
|
|
268
268
|
|
|
269
|
-
const {warnings} = assertValidConfig(
|
|
269
|
+
const {warnings} = assertValidConfig(resolvedConfig);
|
|
270
270
|
|
|
271
|
-
|
|
272
|
-
|
|
271
|
+
resolvedConfig = filterConfigByGatherMode(resolvedConfig, gatherMode);
|
|
272
|
+
resolvedConfig = filterConfigByExplicitFilters(resolvedConfig, settings);
|
|
273
273
|
|
|
274
274
|
log.timeEnd(status);
|
|
275
|
-
return {
|
|
275
|
+
return {resolvedConfig, warnings};
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
/**
|
|
279
|
-
* @param {LH.Config.FRConfig}
|
|
279
|
+
* @param {LH.Config.FRConfig} resolvedConfig
|
|
280
280
|
* @return {string}
|
|
281
281
|
*/
|
|
282
|
-
function getConfigDisplayString(
|
|
282
|
+
function getConfigDisplayString(resolvedConfig) {
|
|
283
283
|
/** @type {LH.Config.FRConfig} */
|
|
284
|
-
const
|
|
284
|
+
const resolvedConfigCopy = JSON.parse(JSON.stringify(resolvedConfig));
|
|
285
285
|
|
|
286
|
-
if (
|
|
287
|
-
for (const navigation of
|
|
286
|
+
if (resolvedConfigCopy.navigations) {
|
|
287
|
+
for (const navigation of resolvedConfigCopy.navigations) {
|
|
288
288
|
for (let i = 0; i < navigation.artifacts.length; ++i) {
|
|
289
289
|
// @ts-expect-error Breaking the Config.AnyArtifactDefn type.
|
|
290
290
|
navigation.artifacts[i] = navigation.artifacts[i].id;
|
|
@@ -292,8 +292,8 @@ function getConfigDisplayString(config) {
|
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
if (
|
|
296
|
-
for (const artifactDefn of
|
|
295
|
+
if (resolvedConfigCopy.artifacts) {
|
|
296
|
+
for (const artifactDefn of resolvedConfigCopy.artifacts) {
|
|
297
297
|
// @ts-expect-error Breaking the Config.AnyArtifactDefn type.
|
|
298
298
|
artifactDefn.gatherer = artifactDefn.gatherer.path;
|
|
299
299
|
// Dependencies are not declared on Config JSON
|
|
@@ -301,8 +301,8 @@ function getConfigDisplayString(config) {
|
|
|
301
301
|
}
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
-
if (
|
|
305
|
-
for (const auditDefn of
|
|
304
|
+
if (resolvedConfigCopy.audits) {
|
|
305
|
+
for (const auditDefn of resolvedConfigCopy.audits) {
|
|
306
306
|
// @ts-expect-error Breaking the Config.AuditDefn type.
|
|
307
307
|
auditDefn.implementation = undefined;
|
|
308
308
|
if (Object.keys(auditDefn.options).length === 0) {
|
|
@@ -313,9 +313,9 @@ function getConfigDisplayString(config) {
|
|
|
313
313
|
}
|
|
314
314
|
|
|
315
315
|
// Printed config is more useful with localized strings.
|
|
316
|
-
format.replaceIcuMessages(
|
|
316
|
+
format.replaceIcuMessages(resolvedConfigCopy, resolvedConfigCopy.settings.locale);
|
|
317
317
|
|
|
318
|
-
return JSON.stringify(
|
|
318
|
+
return JSON.stringify(resolvedConfigCopy, null, 2);
|
|
319
319
|
}
|
|
320
320
|
|
|
321
321
|
export {
|
package/core/config/filters.js
CHANGED
|
@@ -257,19 +257,19 @@ function filterCategoriesByAvailableAudits(categories, availableAudits) {
|
|
|
257
257
|
/**
|
|
258
258
|
* Filters a config's artifacts, audits, and categories down to the set that supports the specified gather mode.
|
|
259
259
|
*
|
|
260
|
-
* @param {LH.Config.FRConfig}
|
|
260
|
+
* @param {LH.Config.FRConfig} resolvedConfig
|
|
261
261
|
* @param {LH.Gatherer.GatherMode} mode
|
|
262
262
|
* @return {LH.Config.FRConfig}
|
|
263
263
|
*/
|
|
264
|
-
function filterConfigByGatherMode(
|
|
265
|
-
const artifacts = filterArtifactsByGatherMode(
|
|
266
|
-
const supportedAudits = filterAuditsByGatherMode(
|
|
264
|
+
function filterConfigByGatherMode(resolvedConfig, mode) {
|
|
265
|
+
const artifacts = filterArtifactsByGatherMode(resolvedConfig.artifacts, mode);
|
|
266
|
+
const supportedAudits = filterAuditsByGatherMode(resolvedConfig.audits, mode);
|
|
267
267
|
const audits = filterAuditsByAvailableArtifacts(supportedAudits, artifacts || []);
|
|
268
|
-
const supportedCategories = filterCategoriesByGatherMode(
|
|
268
|
+
const supportedCategories = filterCategoriesByGatherMode(resolvedConfig.categories, mode);
|
|
269
269
|
const categories = filterCategoriesByAvailableAudits(supportedCategories, audits || []);
|
|
270
270
|
|
|
271
271
|
return {
|
|
272
|
-
...
|
|
272
|
+
...resolvedConfig,
|
|
273
273
|
artifacts,
|
|
274
274
|
audits,
|
|
275
275
|
categories,
|
|
@@ -280,22 +280,22 @@ function filterConfigByGatherMode(config, mode) {
|
|
|
280
280
|
* Filters a config's artifacts, audits, and categories down to the requested set.
|
|
281
281
|
* Skip audits overrides inclusion via `onlyAudits`/`onlyCategories`.
|
|
282
282
|
*
|
|
283
|
-
* @param {LH.Config.FRConfig}
|
|
283
|
+
* @param {LH.Config.FRConfig} resolvedConfig
|
|
284
284
|
* @param {Pick<LH.Config.Settings, 'onlyAudits'|'onlyCategories'|'skipAudits'>} filters
|
|
285
285
|
* @return {LH.Config.FRConfig}
|
|
286
286
|
*/
|
|
287
|
-
function filterConfigByExplicitFilters(
|
|
287
|
+
function filterConfigByExplicitFilters(resolvedConfig, filters) {
|
|
288
288
|
const {onlyAudits, onlyCategories, skipAudits} = filters;
|
|
289
289
|
|
|
290
|
-
warnOnUnknownOnlyCategories(
|
|
290
|
+
warnOnUnknownOnlyCategories(resolvedConfig.categories, onlyCategories);
|
|
291
291
|
|
|
292
|
-
let baseAuditIds = getAuditIdsInCategories(
|
|
292
|
+
let baseAuditIds = getAuditIdsInCategories(resolvedConfig.categories, undefined);
|
|
293
293
|
if (onlyCategories) {
|
|
294
|
-
baseAuditIds = getAuditIdsInCategories(
|
|
294
|
+
baseAuditIds = getAuditIdsInCategories(resolvedConfig.categories, onlyCategories);
|
|
295
295
|
} else if (onlyAudits) {
|
|
296
296
|
baseAuditIds = new Set();
|
|
297
|
-
} else if (!
|
|
298
|
-
baseAuditIds = new Set(
|
|
297
|
+
} else if (!resolvedConfig.categories || !Object.keys(resolvedConfig.categories).length) {
|
|
298
|
+
baseAuditIds = new Set(resolvedConfig.audits?.map(audit => audit.implementation.meta.id));
|
|
299
299
|
}
|
|
300
300
|
|
|
301
301
|
const auditIdsToKeep = new Set(
|
|
@@ -306,17 +306,19 @@ function filterConfigByExplicitFilters(config, filters) {
|
|
|
306
306
|
].filter(auditId => !skipAudits || !skipAudits.includes(auditId))
|
|
307
307
|
);
|
|
308
308
|
|
|
309
|
-
const audits = auditIdsToKeep.size &&
|
|
310
|
-
|
|
311
|
-
|
|
309
|
+
const audits = auditIdsToKeep.size && resolvedConfig.audits ?
|
|
310
|
+
resolvedConfig.audits.filter(audit => auditIdsToKeep.has(audit.implementation.meta.id)) :
|
|
311
|
+
resolvedConfig.audits;
|
|
312
312
|
|
|
313
|
-
const availableCategories =
|
|
313
|
+
const availableCategories =
|
|
314
|
+
filterCategoriesByAvailableAudits(resolvedConfig.categories, audits || []);
|
|
314
315
|
const categories = filterCategoriesByExplicitFilters(availableCategories, onlyCategories);
|
|
315
|
-
const artifacts = filterArtifactsByAvailableAudits(
|
|
316
|
-
const navigations =
|
|
316
|
+
const artifacts = filterArtifactsByAvailableAudits(resolvedConfig.artifacts, audits);
|
|
317
|
+
const navigations =
|
|
318
|
+
filterNavigationsByAvailableArtifacts(resolvedConfig.navigations, artifacts || []);
|
|
317
319
|
|
|
318
320
|
return {
|
|
319
|
-
...
|
|
321
|
+
...resolvedConfig,
|
|
320
322
|
artifacts,
|
|
321
323
|
navigations,
|
|
322
324
|
audits,
|
|
@@ -247,22 +247,22 @@ function assertArtifactTopologicalOrder(navigations) {
|
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
/**
|
|
250
|
-
* @param {LH.Config.FRConfig}
|
|
250
|
+
* @param {LH.Config.FRConfig} resolvedConfig
|
|
251
251
|
* @return {{warnings: string[]}}
|
|
252
252
|
*/
|
|
253
|
-
function assertValidConfig(
|
|
254
|
-
const {warnings} = assertValidFRNavigations(
|
|
253
|
+
function assertValidConfig(resolvedConfig) {
|
|
254
|
+
const {warnings} = assertValidFRNavigations(resolvedConfig.navigations);
|
|
255
255
|
|
|
256
|
-
for (const artifactDefn of
|
|
256
|
+
for (const artifactDefn of resolvedConfig.artifacts || []) {
|
|
257
257
|
assertValidFRGatherer(artifactDefn.gatherer);
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
for (const auditDefn of
|
|
260
|
+
for (const auditDefn of resolvedConfig.audits || []) {
|
|
261
261
|
assertValidAudit(auditDefn);
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
-
assertValidCategories(
|
|
265
|
-
assertValidSettings(
|
|
264
|
+
assertValidCategories(resolvedConfig.categories, resolvedConfig.audits, resolvedConfig.groups);
|
|
265
|
+
assertValidSettings(resolvedConfig.settings);
|
|
266
266
|
return {warnings};
|
|
267
267
|
}
|
|
268
268
|
|
|
@@ -12,12 +12,12 @@ import {
|
|
|
12
12
|
} from './driver/environment.js';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* @param {LH.Config.FRConfig}
|
|
15
|
+
* @param {LH.Config.FRConfig} resolvedConfig
|
|
16
16
|
* @param {LH.Gatherer.FRTransitionalDriver} driver
|
|
17
17
|
* @param {{gatherMode: LH.Gatherer.GatherMode}} context
|
|
18
18
|
* @return {Promise<LH.BaseArtifacts>}
|
|
19
19
|
*/
|
|
20
|
-
async function getBaseArtifacts(
|
|
20
|
+
async function getBaseArtifacts(resolvedConfig, driver, context) {
|
|
21
21
|
const BenchmarkIndex = await getBenchmarkIndex(driver.executionContext);
|
|
22
22
|
const {userAgent} = await getBrowserVersion(driver.defaultSession);
|
|
23
23
|
|
|
@@ -26,7 +26,7 @@ async function getBaseArtifacts(config, driver, context) {
|
|
|
26
26
|
fetchTime: new Date().toJSON(),
|
|
27
27
|
Timing: [],
|
|
28
28
|
LighthouseRunWarnings: [],
|
|
29
|
-
settings:
|
|
29
|
+
settings: resolvedConfig.settings,
|
|
30
30
|
// Environment artifacts that can always be computed.
|
|
31
31
|
BenchmarkIndex,
|
|
32
32
|
HostUserAgent: userAgent,
|
|
@@ -70,6 +70,7 @@ async function dismissJavaScriptDialogs(session) {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
|
+
* Reset the storage and warn if any stored data could be affecting the scores.
|
|
73
74
|
* @param {LH.Gatherer.FRProtocolSession} session
|
|
74
75
|
* @param {string} url
|
|
75
76
|
* @return {Promise<{warnings: Array<LH.IcuMessage>}>}
|
|
@@ -78,11 +79,14 @@ async function resetStorageForUrl(session, url) {
|
|
|
78
79
|
/** @type {Array<LH.IcuMessage>} */
|
|
79
80
|
const warnings = [];
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
await storage.clearDataForOrigin(session, url);
|
|
85
|
-
|
|
82
|
+
const importantStorageWarning = await storage.getImportantStorageWarning(session, url);
|
|
83
|
+
if (importantStorageWarning) warnings.push(importantStorageWarning);
|
|
84
|
+
|
|
85
|
+
const clearDataWarnings = await storage.clearDataForOrigin(session, url);
|
|
86
|
+
warnings.push(...clearDataWarnings);
|
|
87
|
+
|
|
88
|
+
const clearCacheWarnings = await storage.clearBrowserCaches(session);
|
|
89
|
+
warnings.push(...clearCacheWarnings);
|
|
86
90
|
|
|
87
91
|
return {warnings};
|
|
88
92
|
}
|
|
@@ -8,6 +8,7 @@ import log from 'lighthouse-logger';
|
|
|
8
8
|
|
|
9
9
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
10
10
|
|
|
11
|
+
/* eslint-disable max-len */
|
|
11
12
|
const UIStrings = {
|
|
12
13
|
/**
|
|
13
14
|
* @description A warning that previously-saved data may have affected the measured performance and instructions on how to avoid the problem. "locations" will be a list of possible types of data storage locations, e.g. "IndexedDB", "Local Storage", or "Web SQL".
|
|
@@ -22,7 +23,12 @@ const UIStrings = {
|
|
|
22
23
|
`Audit this page in an incognito window to prevent those resources ` +
|
|
23
24
|
`from affecting your scores.}
|
|
24
25
|
}`,
|
|
26
|
+
/** A warning that the data in the browser cache may have affected the measured performance because the operation to clear the browser cache timed out. */
|
|
27
|
+
warningCacheTimeout: 'Clearing the browser cache timed out. Try auditing this page again and file a bug if the issue persists.',
|
|
28
|
+
/** A warning that the data on the page's origin may have affected the measured performance because the operation to clear the origin data timed out. */
|
|
29
|
+
warningOriginDataTimeout: 'Clearing the origin data timed out. Try auditing this page again and file a bug if the issue persists.',
|
|
25
30
|
};
|
|
31
|
+
/* eslint-enable max-len */
|
|
26
32
|
|
|
27
33
|
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
28
34
|
|
|
@@ -30,12 +36,14 @@ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
|
30
36
|
/**
|
|
31
37
|
* @param {LH.Gatherer.FRProtocolSession} session
|
|
32
38
|
* @param {string} url
|
|
33
|
-
* @return {Promise<
|
|
39
|
+
* @return {Promise<LH.IcuMessage[]>}
|
|
34
40
|
*/
|
|
35
41
|
async function clearDataForOrigin(session, url) {
|
|
36
42
|
const status = {msg: 'Cleaning origin data', id: 'lh:storage:clearDataForOrigin'};
|
|
37
43
|
log.time(status);
|
|
38
44
|
|
|
45
|
+
const warnings = [];
|
|
46
|
+
|
|
39
47
|
const origin = new URL(url).origin;
|
|
40
48
|
|
|
41
49
|
// Clear some types of storage.
|
|
@@ -62,12 +70,15 @@ async function clearDataForOrigin(session, url) {
|
|
|
62
70
|
} catch (err) {
|
|
63
71
|
if (/** @type {LH.LighthouseError} */ (err).code === 'PROTOCOL_TIMEOUT') {
|
|
64
72
|
log.warn('Driver', 'clearDataForOrigin timed out');
|
|
73
|
+
warnings.push(str_(UIStrings.warningOriginDataTimeout));
|
|
65
74
|
} else {
|
|
66
75
|
throw err;
|
|
67
76
|
}
|
|
68
77
|
} finally {
|
|
69
78
|
log.timeEnd(status);
|
|
70
79
|
}
|
|
80
|
+
|
|
81
|
+
return warnings;
|
|
71
82
|
}
|
|
72
83
|
|
|
73
84
|
/**
|
|
@@ -102,19 +113,32 @@ async function getImportantStorageWarning(session, url) {
|
|
|
102
113
|
/**
|
|
103
114
|
* Clear the network cache on disk and in memory.
|
|
104
115
|
* @param {LH.Gatherer.FRProtocolSession} session
|
|
105
|
-
* @return {Promise<
|
|
116
|
+
* @return {Promise<LH.IcuMessage[]>}
|
|
106
117
|
*/
|
|
107
118
|
async function clearBrowserCaches(session) {
|
|
108
119
|
const status = {msg: 'Cleaning browser cache', id: 'lh:storage:clearBrowserCaches'};
|
|
109
120
|
log.time(status);
|
|
110
121
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
122
|
+
const warnings = [];
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
// Wipe entire disk cache
|
|
126
|
+
await session.sendCommand('Network.clearBrowserCache');
|
|
127
|
+
// Toggle 'Disable Cache' to evict the memory cache
|
|
128
|
+
await session.sendCommand('Network.setCacheDisabled', {cacheDisabled: true});
|
|
129
|
+
await session.sendCommand('Network.setCacheDisabled', {cacheDisabled: false});
|
|
130
|
+
} catch (err) {
|
|
131
|
+
if (/** @type {LH.LighthouseError} */ (err).code === 'PROTOCOL_TIMEOUT') {
|
|
132
|
+
log.warn('Driver', 'clearBrowserCaches timed out');
|
|
133
|
+
warnings.push(str_(UIStrings.warningCacheTimeout));
|
|
134
|
+
} else {
|
|
135
|
+
throw err;
|
|
136
|
+
}
|
|
137
|
+
} finally {
|
|
138
|
+
log.timeEnd(status);
|
|
139
|
+
}
|
|
116
140
|
|
|
117
|
-
|
|
141
|
+
return warnings;
|
|
118
142
|
}
|
|
119
143
|
|
|
120
144
|
export {
|
|
@@ -29,7 +29,7 @@ import {NetworkRecords} from '../computed/network-records.js';
|
|
|
29
29
|
* @typedef NavigationContext
|
|
30
30
|
* @property {Driver} driver
|
|
31
31
|
* @property {LH.Puppeteer.Page} page
|
|
32
|
-
* @property {LH.Config.FRConfig}
|
|
32
|
+
* @property {LH.Config.FRConfig} resolvedConfig
|
|
33
33
|
* @property {LH.Config.NavigationDefn} navigation
|
|
34
34
|
* @property {LH.NavigationRequestor} requestor
|
|
35
35
|
* @property {LH.FRBaseArtifacts} baseArtifacts
|
|
@@ -42,20 +42,20 @@ const DEFAULT_HOSTNAME = '127.0.0.1';
|
|
|
42
42
|
const DEFAULT_PORT = 9222;
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
|
-
* @param {{driver: Driver,
|
|
45
|
+
* @param {{driver: Driver, resolvedConfig: LH.Config.FRConfig, requestor: LH.NavigationRequestor}} args
|
|
46
46
|
* @return {Promise<{baseArtifacts: LH.FRBaseArtifacts}>}
|
|
47
47
|
*/
|
|
48
|
-
async function _setup({driver,
|
|
48
|
+
async function _setup({driver, resolvedConfig, requestor}) {
|
|
49
49
|
await driver.connect();
|
|
50
50
|
|
|
51
51
|
// We can't trigger the navigation through user interaction if we reset the page before starting.
|
|
52
|
-
if (typeof requestor === 'string' && !
|
|
52
|
+
if (typeof requestor === 'string' && !resolvedConfig.settings.skipAboutBlank) {
|
|
53
53
|
await gotoURL(driver, defaultNavigationConfig.blankPage, {waitUntil: ['navigated']});
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
const baseArtifacts = await getBaseArtifacts(
|
|
56
|
+
const baseArtifacts = await getBaseArtifacts(resolvedConfig, driver, {gatherMode: 'navigation'});
|
|
57
57
|
|
|
58
|
-
await prepare.prepareTargetForNavigationMode(driver,
|
|
58
|
+
await prepare.prepareTargetForNavigationMode(driver, resolvedConfig.settings);
|
|
59
59
|
|
|
60
60
|
return {baseArtifacts};
|
|
61
61
|
}
|
|
@@ -64,15 +64,15 @@ async function _setup({driver, config, requestor}) {
|
|
|
64
64
|
* @param {NavigationContext} navigationContext
|
|
65
65
|
* @return {Promise<{warnings: Array<LH.IcuMessage>}>}
|
|
66
66
|
*/
|
|
67
|
-
async function _setupNavigation({requestor, driver, navigation,
|
|
67
|
+
async function _setupNavigation({requestor, driver, navigation, resolvedConfig}) {
|
|
68
68
|
// We can't trigger the navigation through user interaction if we reset the page before starting.
|
|
69
|
-
if (typeof requestor === 'string' && !
|
|
69
|
+
if (typeof requestor === 'string' && !resolvedConfig.settings.skipAboutBlank) {
|
|
70
70
|
await gotoURL(driver, navigation.blankPage, {...navigation, waitUntil: ['navigated']});
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
const {warnings} = await prepare.prepareTargetForIndividualNavigation(
|
|
74
74
|
driver.defaultSession,
|
|
75
|
-
|
|
75
|
+
resolvedConfig.settings,
|
|
76
76
|
{
|
|
77
77
|
...navigation,
|
|
78
78
|
requestor,
|
|
@@ -94,14 +94,14 @@ async function _cleanupNavigation({driver}) {
|
|
|
94
94
|
* @return {Promise<{requestedUrl: string, mainDocumentUrl: string, navigationError: LH.LighthouseError | undefined, warnings: Array<LH.IcuMessage>}>}
|
|
95
95
|
*/
|
|
96
96
|
async function _navigate(navigationContext) {
|
|
97
|
-
const {driver,
|
|
97
|
+
const {driver, resolvedConfig, requestor} = navigationContext;
|
|
98
98
|
|
|
99
99
|
try {
|
|
100
100
|
const {requestedUrl, mainDocumentUrl, warnings} = await gotoURL(driver, requestor, {
|
|
101
101
|
...navigationContext.navigation,
|
|
102
|
-
debugNavigation:
|
|
103
|
-
maxWaitForFcp:
|
|
104
|
-
maxWaitForLoad:
|
|
102
|
+
debugNavigation: resolvedConfig.settings.debugNavigation,
|
|
103
|
+
maxWaitForFcp: resolvedConfig.settings.maxWaitForFcp,
|
|
104
|
+
maxWaitForLoad: resolvedConfig.settings.maxWaitForLoad,
|
|
105
105
|
waitUntil: navigationContext.navigation.pauseAfterFcpMs ? ['fcp', 'load'] : ['load'],
|
|
106
106
|
});
|
|
107
107
|
return {requestedUrl, mainDocumentUrl, navigationError: undefined, warnings};
|
|
@@ -181,7 +181,7 @@ async function _computeNavigationResult(
|
|
|
181
181
|
: navigationError;
|
|
182
182
|
|
|
183
183
|
if (pageLoadError) {
|
|
184
|
-
const locale = navigationContext.
|
|
184
|
+
const locale = navigationContext.resolvedConfig.settings.locale;
|
|
185
185
|
const localizedMessage = format.getFormatted(pageLoadError.friendlyMessage, locale);
|
|
186
186
|
log.error('NavigationRunner', localizedMessage, navigateResult.requestedUrl);
|
|
187
187
|
|
|
@@ -223,7 +223,7 @@ async function _navigation(navigationContext) {
|
|
|
223
223
|
artifactDefinitions: navigationContext.navigation.artifacts,
|
|
224
224
|
artifactState,
|
|
225
225
|
baseArtifacts: navigationContext.baseArtifacts,
|
|
226
|
-
settings: navigationContext.
|
|
226
|
+
settings: navigationContext.resolvedConfig.settings,
|
|
227
227
|
};
|
|
228
228
|
|
|
229
229
|
const setupResult = await _setupNavigation(navigationContext);
|
|
@@ -250,24 +250,33 @@ async function _navigation(navigationContext) {
|
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
/**
|
|
253
|
-
* @param {{driver: Driver, page: LH.Puppeteer.Page,
|
|
253
|
+
* @param {{driver: Driver, page: LH.Puppeteer.Page, resolvedConfig: LH.Config.FRConfig, requestor: LH.NavigationRequestor; baseArtifacts: LH.FRBaseArtifacts, computedCache: NavigationContext['computedCache']}} args
|
|
254
254
|
* @return {Promise<{artifacts: Partial<LH.FRArtifacts & LH.FRBaseArtifacts>}>}
|
|
255
255
|
*/
|
|
256
|
-
async function _navigations(
|
|
257
|
-
|
|
256
|
+
async function _navigations(args) {
|
|
257
|
+
const {
|
|
258
|
+
driver,
|
|
259
|
+
page,
|
|
260
|
+
resolvedConfig,
|
|
261
|
+
requestor,
|
|
262
|
+
baseArtifacts,
|
|
263
|
+
computedCache,
|
|
264
|
+
} = args;
|
|
265
|
+
|
|
266
|
+
if (!resolvedConfig.navigations) throw new Error('No navigations configured');
|
|
258
267
|
|
|
259
268
|
/** @type {Partial<LH.FRArtifacts & LH.FRBaseArtifacts>} */
|
|
260
269
|
const artifacts = {};
|
|
261
270
|
/** @type {Array<LH.IcuMessage>} */
|
|
262
271
|
const LighthouseRunWarnings = [];
|
|
263
272
|
|
|
264
|
-
for (const navigation of
|
|
273
|
+
for (const navigation of resolvedConfig.navigations) {
|
|
265
274
|
const navigationContext = {
|
|
266
275
|
driver,
|
|
267
276
|
page,
|
|
268
277
|
navigation,
|
|
269
278
|
requestor,
|
|
270
|
-
|
|
279
|
+
resolvedConfig,
|
|
271
280
|
baseArtifacts,
|
|
272
281
|
computedCache,
|
|
273
282
|
};
|
|
@@ -290,10 +299,10 @@ async function _navigations({driver, page, config, requestor, baseArtifacts, com
|
|
|
290
299
|
}
|
|
291
300
|
|
|
292
301
|
/**
|
|
293
|
-
* @param {{requestedUrl?: string, driver: Driver,
|
|
302
|
+
* @param {{requestedUrl?: string, driver: Driver, resolvedConfig: LH.Config.FRConfig}} args
|
|
294
303
|
*/
|
|
295
|
-
async function _cleanup({requestedUrl, driver,
|
|
296
|
-
const didResetStorage = !
|
|
304
|
+
async function _cleanup({requestedUrl, driver, resolvedConfig}) {
|
|
305
|
+
const didResetStorage = !resolvedConfig.settings.disableStorageReset && requestedUrl;
|
|
297
306
|
if (didResetStorage) await storage.clearDataForOrigin(driver.defaultSession, requestedUrl);
|
|
298
307
|
|
|
299
308
|
await driver.disconnect();
|
|
@@ -306,15 +315,15 @@ async function _cleanup({requestedUrl, driver, config}) {
|
|
|
306
315
|
* @return {Promise<LH.Gatherer.FRGatherResult>}
|
|
307
316
|
*/
|
|
308
317
|
async function navigationGather(page, requestor, options = {}) {
|
|
309
|
-
const {flags = {}} = options;
|
|
318
|
+
const {flags = {}, config} = options;
|
|
310
319
|
log.setLevel(flags.logLevel || 'error');
|
|
311
320
|
|
|
312
|
-
const {
|
|
321
|
+
const {resolvedConfig} = await initializeConfig('navigation', config, flags);
|
|
313
322
|
const computedCache = new Map();
|
|
314
323
|
|
|
315
324
|
const isCallback = typeof requestor === 'function';
|
|
316
325
|
|
|
317
|
-
const runnerOptions = {
|
|
326
|
+
const runnerOptions = {resolvedConfig, computedCache};
|
|
318
327
|
const artifacts = await Runner.gather(
|
|
319
328
|
async () => {
|
|
320
329
|
const normalizedRequestor = isCallback ? requestor : UrlUtils.normalizeUrl(requestor);
|
|
@@ -330,7 +339,7 @@ async function navigationGather(page, requestor, options = {}) {
|
|
|
330
339
|
const driver = new Driver(page);
|
|
331
340
|
const context = {
|
|
332
341
|
driver,
|
|
333
|
-
|
|
342
|
+
resolvedConfig,
|
|
334
343
|
requestor: normalizedRequestor,
|
|
335
344
|
};
|
|
336
345
|
const {baseArtifacts} = await _setup(context);
|
|
@@ -18,10 +18,10 @@ import {getBaseArtifacts, finalizeArtifacts} from './base-artifacts.js';
|
|
|
18
18
|
* @return {Promise<LH.Gatherer.FRGatherResult>}
|
|
19
19
|
*/
|
|
20
20
|
async function snapshotGather(page, options = {}) {
|
|
21
|
-
const {flags = {}} = options;
|
|
21
|
+
const {flags = {}, config} = options;
|
|
22
22
|
log.setLevel(flags.logLevel || 'error');
|
|
23
23
|
|
|
24
|
-
const {
|
|
24
|
+
const {resolvedConfig} = await initializeConfig('snapshot', config, flags);
|
|
25
25
|
const driver = new Driver(page);
|
|
26
26
|
await driver.connect();
|
|
27
27
|
|
|
@@ -29,15 +29,16 @@ async function snapshotGather(page, options = {}) {
|
|
|
29
29
|
const computedCache = new Map();
|
|
30
30
|
const url = await driver.url();
|
|
31
31
|
|
|
32
|
-
const runnerOptions = {
|
|
32
|
+
const runnerOptions = {resolvedConfig, computedCache};
|
|
33
33
|
const artifacts = await Runner.gather(
|
|
34
34
|
async () => {
|
|
35
|
-
const baseArtifacts =
|
|
35
|
+
const baseArtifacts =
|
|
36
|
+
await getBaseArtifacts(resolvedConfig, driver, {gatherMode: 'snapshot'});
|
|
36
37
|
baseArtifacts.URL = {
|
|
37
38
|
finalDisplayedUrl: url,
|
|
38
39
|
};
|
|
39
40
|
|
|
40
|
-
const artifactDefinitions =
|
|
41
|
+
const artifactDefinitions = resolvedConfig.artifacts || [];
|
|
41
42
|
const artifactState = getEmptyArtifactState();
|
|
42
43
|
await collectPhaseArtifacts({
|
|
43
44
|
phase: 'getArtifact',
|
|
@@ -48,7 +49,7 @@ async function snapshotGather(page, options = {}) {
|
|
|
48
49
|
artifactDefinitions,
|
|
49
50
|
artifactState,
|
|
50
51
|
computedCache,
|
|
51
|
-
settings:
|
|
52
|
+
settings: resolvedConfig.settings,
|
|
52
53
|
});
|
|
53
54
|
|
|
54
55
|
await driver.disconnect();
|
|
@@ -19,17 +19,17 @@ import {getBaseArtifacts, finalizeArtifacts} from './base-artifacts.js';
|
|
|
19
19
|
* @return {Promise<{endTimespanGather(): Promise<LH.Gatherer.FRGatherResult>}>}
|
|
20
20
|
*/
|
|
21
21
|
async function startTimespanGather(page, options = {}) {
|
|
22
|
-
const {flags = {}} = options;
|
|
22
|
+
const {flags = {}, config} = options;
|
|
23
23
|
log.setLevel(flags.logLevel || 'error');
|
|
24
24
|
|
|
25
|
-
const {
|
|
25
|
+
const {resolvedConfig} = await initializeConfig('timespan', config, flags);
|
|
26
26
|
const driver = new Driver(page);
|
|
27
27
|
await driver.connect();
|
|
28
28
|
|
|
29
29
|
/** @type {Map<string, LH.ArbitraryEqualityMap>} */
|
|
30
30
|
const computedCache = new Map();
|
|
31
|
-
const artifactDefinitions =
|
|
32
|
-
const baseArtifacts = await getBaseArtifacts(
|
|
31
|
+
const artifactDefinitions = resolvedConfig.artifacts || [];
|
|
32
|
+
const baseArtifacts = await getBaseArtifacts(resolvedConfig, driver, {gatherMode: 'timespan'});
|
|
33
33
|
const artifactState = getEmptyArtifactState();
|
|
34
34
|
/** @type {Omit<import('./runner-helpers.js').CollectPhaseArtifactOptions, 'phase'>} */
|
|
35
35
|
const phaseOptions = {
|
|
@@ -40,10 +40,10 @@ async function startTimespanGather(page, options = {}) {
|
|
|
40
40
|
baseArtifacts,
|
|
41
41
|
computedCache,
|
|
42
42
|
gatherMode: 'timespan',
|
|
43
|
-
settings:
|
|
43
|
+
settings: resolvedConfig.settings,
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
-
await prepareTargetForTimespanMode(driver,
|
|
46
|
+
await prepareTargetForTimespanMode(driver, resolvedConfig.settings);
|
|
47
47
|
await collectPhaseArtifacts({phase: 'startInstrumentation', ...phaseOptions});
|
|
48
48
|
await collectPhaseArtifacts({phase: 'startSensitiveInstrumentation', ...phaseOptions});
|
|
49
49
|
|
|
@@ -51,7 +51,7 @@ async function startTimespanGather(page, options = {}) {
|
|
|
51
51
|
async endTimespanGather() {
|
|
52
52
|
const finalDisplayedUrl = await driver.url();
|
|
53
53
|
|
|
54
|
-
const runnerOptions = {
|
|
54
|
+
const runnerOptions = {resolvedConfig, computedCache};
|
|
55
55
|
const artifacts = await Runner.gather(
|
|
56
56
|
async () => {
|
|
57
57
|
baseArtifacts.URL = {finalDisplayedUrl};
|
package/core/index.js
CHANGED
|
@@ -63,9 +63,9 @@ async function legacyNavigation(url, flags = {}, configJSON, userConnection) {
|
|
|
63
63
|
flags.logLevel = flags.logLevel || 'error';
|
|
64
64
|
log.setLevel(flags.logLevel);
|
|
65
65
|
|
|
66
|
-
const
|
|
66
|
+
const resolvedConfig = await Config.fromJson(configJSON, flags);
|
|
67
67
|
const computedCache = new Map();
|
|
68
|
-
const options = {
|
|
68
|
+
const options = {resolvedConfig, computedCache};
|
|
69
69
|
const connection = userConnection || new CriConnection(flags.port, flags.hostname);
|
|
70
70
|
|
|
71
71
|
// kick off a lighthouse run
|
|
@@ -179,9 +179,9 @@ class Config {
|
|
|
179
179
|
|
|
180
180
|
const audits = await Config.requireAudits(configJSON.audits, configDir);
|
|
181
181
|
|
|
182
|
-
const
|
|
182
|
+
const resolvedConfig = new Config(configJSON, {settings, passes, audits});
|
|
183
183
|
log.timeEnd(status);
|
|
184
|
-
return
|
|
184
|
+
return resolvedConfig;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
/**
|
package/core/runner.js
CHANGED
|
@@ -34,12 +34,12 @@ class Runner {
|
|
|
34
34
|
/**
|
|
35
35
|
* @template {LH.Config.Config | LH.Config.FRConfig} TConfig
|
|
36
36
|
* @param {LH.Artifacts} artifacts
|
|
37
|
-
* @param {{
|
|
37
|
+
* @param {{resolvedConfig: TConfig, driverMock?: Driver, computedCache: Map<string, ArbitraryEqualityMap>}} options
|
|
38
38
|
* @return {Promise<LH.RunnerResult|undefined>}
|
|
39
39
|
*/
|
|
40
40
|
static async audit(artifacts, options) {
|
|
41
|
-
const {
|
|
42
|
-
const settings =
|
|
41
|
+
const {resolvedConfig, computedCache} = options;
|
|
42
|
+
const settings = resolvedConfig.settings;
|
|
43
43
|
|
|
44
44
|
try {
|
|
45
45
|
const runnerStatus = {msg: 'Audit phase', id: 'lh:runner:audit'};
|
|
@@ -54,10 +54,10 @@ class Runner {
|
|
|
54
54
|
// Potentially quit early
|
|
55
55
|
if (settings.gatherMode && !settings.auditMode) return;
|
|
56
56
|
|
|
57
|
-
if (!
|
|
57
|
+
if (!resolvedConfig.audits) {
|
|
58
58
|
throw new Error('No audits to evaluate.');
|
|
59
59
|
}
|
|
60
|
-
const auditResultsById = await Runner._runAudits(settings,
|
|
60
|
+
const auditResultsById = await Runner._runAudits(settings, resolvedConfig.audits, artifacts,
|
|
61
61
|
lighthouseRunWarnings, computedCache);
|
|
62
62
|
|
|
63
63
|
// LHR construction phase
|
|
@@ -79,8 +79,8 @@ class Runner {
|
|
|
79
79
|
|
|
80
80
|
/** @type {Record<string, LH.RawIcu<LH.Result.Category>>} */
|
|
81
81
|
let categories = {};
|
|
82
|
-
if (
|
|
83
|
-
categories = ReportScoring.scoreAllCategories(
|
|
82
|
+
if (resolvedConfig.categories) {
|
|
83
|
+
categories = ReportScoring.scoreAllCategories(resolvedConfig.categories, auditResultsById);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
log.timeEnd(resultsStatus);
|
|
@@ -108,7 +108,7 @@ class Runner {
|
|
|
108
108
|
audits: auditResultsById,
|
|
109
109
|
configSettings: settings,
|
|
110
110
|
categories,
|
|
111
|
-
categoryGroups:
|
|
111
|
+
categoryGroups: resolvedConfig.groups || undefined,
|
|
112
112
|
stackPacks: stackPacks.getStackPacks(artifacts.Stacks),
|
|
113
113
|
timing: this._getTiming(artifacts),
|
|
114
114
|
i18n: {
|
|
@@ -143,12 +143,12 @@ class Runner {
|
|
|
143
143
|
* and -GA will run everything plus save artifacts and lhr to disk.
|
|
144
144
|
*
|
|
145
145
|
* @template {LH.Config.Config | LH.Config.FRConfig} TConfig
|
|
146
|
-
* @param {(runnerData: {
|
|
147
|
-
* @param {{
|
|
146
|
+
* @param {(runnerData: {resolvedConfig: TConfig, driverMock?: Driver}) => Promise<LH.Artifacts>} gatherFn
|
|
147
|
+
* @param {{resolvedConfig: TConfig, driverMock?: Driver, computedCache: Map<string, ArbitraryEqualityMap>}} options
|
|
148
148
|
* @return {Promise<LH.Artifacts>}
|
|
149
149
|
*/
|
|
150
150
|
static async gather(gatherFn, options) {
|
|
151
|
-
const settings = options.
|
|
151
|
+
const settings = options.resolvedConfig.settings;
|
|
152
152
|
|
|
153
153
|
// Either load saved artifacts from disk or from the browser.
|
|
154
154
|
try {
|
|
@@ -170,7 +170,7 @@ class Runner {
|
|
|
170
170
|
log.time(runnerStatus, 'verbose');
|
|
171
171
|
|
|
172
172
|
artifacts = await gatherFn({
|
|
173
|
-
|
|
173
|
+
resolvedConfig: options.resolvedConfig,
|
|
174
174
|
driverMock: options.driverMock,
|
|
175
175
|
});
|
|
176
176
|
|
|
@@ -248,22 +248,22 @@ class Runner {
|
|
|
248
248
|
/**
|
|
249
249
|
* Establish connection, load page and collect all required artifacts
|
|
250
250
|
* @param {string} requestedUrl
|
|
251
|
-
* @param {{
|
|
251
|
+
* @param {{resolvedConfig: Config, computedCache: Map<string, ArbitraryEqualityMap>, driverMock?: Driver}} runnerOpts
|
|
252
252
|
* @param {Connection} connection
|
|
253
253
|
* @return {Promise<LH.Artifacts>}
|
|
254
254
|
*/
|
|
255
255
|
static async _gatherArtifactsFromBrowser(requestedUrl, runnerOpts, connection) {
|
|
256
|
-
if (!runnerOpts.
|
|
256
|
+
if (!runnerOpts.resolvedConfig.passes) {
|
|
257
257
|
throw new Error('No browser artifacts are either provided or requested.');
|
|
258
258
|
}
|
|
259
259
|
const driver = runnerOpts.driverMock || new Driver(connection);
|
|
260
260
|
const gatherOpts = {
|
|
261
261
|
driver,
|
|
262
262
|
requestedUrl,
|
|
263
|
-
settings: runnerOpts.
|
|
263
|
+
settings: runnerOpts.resolvedConfig.settings,
|
|
264
264
|
computedCache: runnerOpts.computedCache,
|
|
265
265
|
};
|
|
266
|
-
const artifacts = await GatherRunner.run(runnerOpts.
|
|
266
|
+
const artifacts = await GatherRunner.run(runnerOpts.resolvedConfig.passes, gatherOpts);
|
|
267
267
|
return artifacts;
|
|
268
268
|
}
|
|
269
269
|
|
package/core/user-flow.js
CHANGED
|
@@ -323,9 +323,9 @@ async function auditGatherSteps(gatherSteps, options) {
|
|
|
323
323
|
// Step specific configs take precedence over a config for the entire flow.
|
|
324
324
|
const configJson = options.config;
|
|
325
325
|
const {gatherMode} = artifacts.GatherContext;
|
|
326
|
-
const {
|
|
326
|
+
const {resolvedConfig} = await initializeConfig(gatherMode, configJson, flags);
|
|
327
327
|
runnerOptions = {
|
|
328
|
-
|
|
328
|
+
resolvedConfig,
|
|
329
329
|
computedCache: new Map(),
|
|
330
330
|
};
|
|
331
331
|
}
|
|
@@ -5286,7 +5286,8 @@ class TopbarFeatures {
|
|
|
5286
5286
|
*/
|
|
5287
5287
|
_setUpCollapseDetailsAfterPrinting() {
|
|
5288
5288
|
// FF and IE implement these old events.
|
|
5289
|
-
|
|
5289
|
+
const supportsOldPrintEvents = 'onbeforeprint' in self;
|
|
5290
|
+
if (supportsOldPrintEvents) {
|
|
5290
5291
|
self.addEventListener('afterprint', this.collapseAllDetails);
|
|
5291
5292
|
} else {
|
|
5292
5293
|
// Note: FF implements both window.onbeforeprint and media listeners. However,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lighthouse",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "9.5.0-dev.
|
|
4
|
+
"version": "9.5.0-dev.20230103",
|
|
5
5
|
"description": "Automated auditing, performance metrics, and best practices for the web.",
|
|
6
6
|
"main": "./core/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -127,8 +127,8 @@
|
|
|
127
127
|
"@types/ws": "^7.0.0",
|
|
128
128
|
"@types/yargs": "^17.0.8",
|
|
129
129
|
"@types/yargs-parser": "^20.2.1",
|
|
130
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
131
|
-
"@typescript-eslint/parser": "^5.
|
|
130
|
+
"@typescript-eslint/eslint-plugin": "^5.48.0",
|
|
131
|
+
"@typescript-eslint/parser": "^5.48.0",
|
|
132
132
|
"acorn": "^8.5.0",
|
|
133
133
|
"angular": "^1.7.4",
|
|
134
134
|
"archiver": "^3.0.0",
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
"terser": "^5.3.8",
|
|
179
179
|
"testdouble": "^3.16.5",
|
|
180
180
|
"typed-query-selector": "^2.6.1",
|
|
181
|
-
"typescript": "^4.
|
|
181
|
+
"typescript": "^4.9.4",
|
|
182
182
|
"wait-for-expect": "^3.0.2",
|
|
183
183
|
"webtreemap-cdt": "^3.2.1"
|
|
184
184
|
},
|
|
@@ -240,7 +240,8 @@ export class TopbarFeatures {
|
|
|
240
240
|
*/
|
|
241
241
|
_setUpCollapseDetailsAfterPrinting() {
|
|
242
242
|
// FF and IE implement these old events.
|
|
243
|
-
|
|
243
|
+
const supportsOldPrintEvents = 'onbeforeprint' in self;
|
|
244
|
+
if (supportsOldPrintEvents) {
|
|
244
245
|
self.addEventListener('afterprint', this.collapseAllDetails);
|
|
245
246
|
} else {
|
|
246
247
|
// Note: FF implements both window.onbeforeprint and media listeners. However,
|
|
@@ -1679,9 +1679,15 @@
|
|
|
1679
1679
|
"core/gather/driver/navigation.js | warningTimeout": {
|
|
1680
1680
|
"message": "The page loaded too slowly to finish within the time limit. Results may be incomplete."
|
|
1681
1681
|
},
|
|
1682
|
+
"core/gather/driver/storage.js | warningCacheTimeout": {
|
|
1683
|
+
"message": "Clearing the browser cache timed out. Try auditing this page again and file a bug if the issue persists."
|
|
1684
|
+
},
|
|
1682
1685
|
"core/gather/driver/storage.js | warningData": {
|
|
1683
1686
|
"message": "{locationCount, plural,\n =1 {There may be stored data affecting loading performance in this location: {locations}. Audit this page in an incognito window to prevent those resources from affecting your scores.}\n other {There may be stored data affecting loading performance in these locations: {locations}. Audit this page in an incognito window to prevent those resources from affecting your scores.}\n }"
|
|
1684
1687
|
},
|
|
1688
|
+
"core/gather/driver/storage.js | warningOriginDataTimeout": {
|
|
1689
|
+
"message": "Clearing the origin data timed out. Try auditing this page again and file a bug if the issue persists."
|
|
1690
|
+
},
|
|
1685
1691
|
"core/lib/bfcache-strings.js | appBanner": {
|
|
1686
1692
|
"message": "Pages that requested an AppBanner are not currently eligible for back/forward cache."
|
|
1687
1693
|
},
|
|
@@ -1679,9 +1679,15 @@
|
|
|
1679
1679
|
"core/gather/driver/navigation.js | warningTimeout": {
|
|
1680
1680
|
"message": "T̂h́ê ṕâǵê ĺôád̂éd̂ t́ôó ŝĺôẃl̂ý t̂ó f̂ín̂íŝh́ ŵít̂h́îń t̂h́ê t́îḿê ĺîḿît́. R̂éŝúl̂t́ŝ ḿâý b̂é îńĉóm̂ṕl̂ét̂é."
|
|
1681
1681
|
},
|
|
1682
|
+
"core/gather/driver/storage.js | warningCacheTimeout": {
|
|
1683
|
+
"message": "Ĉĺêár̂ín̂ǵ t̂h́ê b́r̂óŵśêŕ ĉáĉh́ê t́îḿêd́ ôút̂. T́r̂ý âúd̂ít̂ín̂ǵ t̂h́îś p̂áĝé âǵâín̂ án̂d́ f̂íl̂é â b́ûǵ îf́ t̂h́ê íŝśûé p̂ér̂śîśt̂ś."
|
|
1684
|
+
},
|
|
1682
1685
|
"core/gather/driver/storage.js | warningData": {
|
|
1683
1686
|
"message": "{locationCount, plural,\n =1 {T̂h́êŕê ḿâý b̂é ŝt́ôŕêd́ d̂át̂á âf́f̂éĉt́îńĝ ĺôád̂ín̂ǵ p̂ér̂f́ôŕm̂án̂ćê ín̂ t́ĥíŝ ĺôćât́îón̂: {locations}. Áûd́ît́ t̂h́îś p̂áĝé îń âń îńĉóĝńît́ô ẃîńd̂óŵ t́ô ṕr̂év̂én̂t́ t̂h́ôśê ŕêśôúr̂ćêś f̂ŕôḿ âf́f̂éĉt́îńĝ ýôúr̂ śĉór̂éŝ.}\n other {T́ĥér̂é m̂áŷ b́ê śt̂ór̂éd̂ d́ât́â áf̂f́êćt̂ín̂ǵ l̂óâd́îńĝ ṕêŕf̂ór̂ḿâńĉé îń t̂h́êśê ĺôćât́îón̂ś: {locations}. Âúd̂ít̂ t́ĥíŝ ṕâǵê ín̂ án̂ ín̂ćôǵn̂ít̂ó ŵín̂d́ôẃ t̂ó p̂ŕêv́êńt̂ t́ĥóŝé r̂éŝóûŕĉéŝ f́r̂óm̂ áf̂f́êćt̂ín̂ǵ ŷóûŕ ŝćôŕêś.}\n }"
|
|
1684
1687
|
},
|
|
1688
|
+
"core/gather/driver/storage.js | warningOriginDataTimeout": {
|
|
1689
|
+
"message": "Ĉĺêár̂ín̂ǵ t̂h́ê ór̂íĝín̂ d́ât́â t́îḿêd́ ôút̂. T́r̂ý âúd̂ít̂ín̂ǵ t̂h́îś p̂áĝé âǵâín̂ án̂d́ f̂íl̂é â b́ûǵ îf́ t̂h́ê íŝśûé p̂ér̂śîśt̂ś."
|
|
1690
|
+
},
|
|
1685
1691
|
"core/lib/bfcache-strings.js | appBanner": {
|
|
1686
1692
|
"message": "P̂áĝéŝ t́ĥát̂ ŕêq́ûéŝt́êd́ âń Âṕp̂B́âńn̂ér̂ ár̂é n̂ót̂ ćûŕr̂én̂t́l̂ý êĺîǵîb́l̂é f̂ór̂ b́âćk̂/f́ôŕŵár̂d́ ĉáĉh́ê."
|
|
1687
1693
|
},
|
package/types/gatherer.d.ts
CHANGED