lighthouse 11.2.0 → 11.3.0-dev.20231102
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/cli-flags.d.ts +5 -1
- package/cli/cli-flags.js +5 -1
- package/cli/test/smokehouse/__snapshots__/report-assert-test.js.snap +2 -2
- 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/audits/byte-efficiency/legacy-javascript.js +2 -2
- package/core/audits/image-size-responsive.js +1 -1
- package/core/audits/layout-shift-elements.js +1 -1
- package/core/audits/lcp-lazy-loaded.js +2 -2
- package/core/audits/long-tasks.js +1 -1
- package/core/audits/metrics/cumulative-layout-shift.js +2 -2
- package/core/audits/metrics/interaction-to-next-paint.js +2 -2
- package/core/audits/metrics/largest-contentful-paint.js +1 -1
- package/core/audits/no-unload-listeners.js +1 -1
- package/core/audits/preload-fonts.js +1 -1
- package/core/audits/prioritize-lcp-image.js +1 -1
- package/core/audits/unsized-images.js +1 -1
- package/core/audits/work-during-interaction.js +1 -1
- 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 +4 -18
- package/core/config/default-config.js +8 -8
- 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 +21 -43
- package/core/gather/driver/storage.d.ts +2 -1
- package/core/gather/driver/storage.js +3 -12
- package/core/gather/gatherers/inspector-issues.js +1 -0
- package/core/gather/navigation-runner.d.ts +3 -31
- package/core/gather/navigation-runner.js +46 -113
- package/core/lib/navigation-error.d.ts +8 -3
- package/core/lib/navigation-error.js +19 -11
- 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 +8 -8
- package/report/renderer/performance-category-renderer.js +2 -1
- package/shared/localization/locales/ar-XB.json +78 -75
- package/shared/localization/locales/ar.json +78 -75
- package/shared/localization/locales/bg.json +78 -75
- package/shared/localization/locales/ca.json +78 -75
- package/shared/localization/locales/cs.json +78 -75
- package/shared/localization/locales/da.json +78 -75
- package/shared/localization/locales/de.json +81 -78
- package/shared/localization/locales/el.json +84 -81
- package/shared/localization/locales/en-GB.json +78 -75
- package/shared/localization/locales/en-US.json +26 -23
- package/shared/localization/locales/en-XA.json +78 -75
- package/shared/localization/locales/en-XL.json +26 -23
- package/shared/localization/locales/es-419.json +78 -75
- package/shared/localization/locales/es.json +78 -75
- package/shared/localization/locales/fi.json +79 -76
- package/shared/localization/locales/fil.json +78 -75
- package/shared/localization/locales/fr.json +78 -75
- package/shared/localization/locales/he.json +78 -75
- package/shared/localization/locales/hi.json +78 -75
- package/shared/localization/locales/hr.json +78 -75
- package/shared/localization/locales/hu.json +78 -75
- package/shared/localization/locales/id.json +78 -75
- package/shared/localization/locales/it.json +79 -76
- package/shared/localization/locales/ja.json +78 -75
- package/shared/localization/locales/ko.json +78 -75
- package/shared/localization/locales/lt.json +78 -75
- package/shared/localization/locales/lv.json +78 -75
- package/shared/localization/locales/nl.json +78 -75
- package/shared/localization/locales/no.json +78 -75
- package/shared/localization/locales/pl.json +78 -75
- package/shared/localization/locales/pt-PT.json +78 -75
- package/shared/localization/locales/pt.json +79 -76
- package/shared/localization/locales/ro.json +78 -75
- package/shared/localization/locales/ru.json +78 -75
- package/shared/localization/locales/sk.json +78 -75
- package/shared/localization/locales/sl.json +78 -75
- package/shared/localization/locales/sr-Latn.json +78 -75
- package/shared/localization/locales/sr.json +78 -75
- package/shared/localization/locales/sv.json +78 -75
- package/shared/localization/locales/ta.json +78 -75
- package/shared/localization/locales/te.json +78 -75
- package/shared/localization/locales/th.json +78 -75
- package/shared/localization/locales/tr.json +78 -75
- package/shared/localization/locales/uk.json +78 -75
- package/shared/localization/locales/vi.json +78 -75
- package/shared/localization/locales/zh-HK.json +78 -75
- package/shared/localization/locales/zh-TW.json +79 -76
- package/shared/localization/locales/zh.json +78 -75
- 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/rxjs.d.ts +4 -0
- package/types/internal/smokehouse.d.ts +10 -5
- package/types/lhr/settings.d.ts +13 -0
package/core/config/config.js
CHANGED
|
@@ -10,12 +10,11 @@ import log from 'lighthouse-logger';
|
|
|
10
10
|
|
|
11
11
|
import {Runner} from '../runner.js';
|
|
12
12
|
import defaultConfig from './default-config.js';
|
|
13
|
-
import {
|
|
13
|
+
import {nonSimulatedSettingsOverrides} from './constants.js'; // eslint-disable-line max-len
|
|
14
14
|
import {
|
|
15
15
|
throwInvalidDependencyOrder,
|
|
16
16
|
isValidArtifactDependency,
|
|
17
17
|
throwInvalidArtifactDependency,
|
|
18
|
-
assertArtifactTopologicalOrder,
|
|
19
18
|
assertValidConfig,
|
|
20
19
|
} from './validation.js';
|
|
21
20
|
import {filterConfigByGatherMode, filterConfigByExplicitFilters} from './filters.js';
|
|
@@ -192,66 +191,34 @@ function overrideSettingsForGatherMode(settings, gatherMode) {
|
|
|
192
191
|
/**
|
|
193
192
|
* Overrides the quiet windows when throttlingMethod requires observation.
|
|
194
193
|
*
|
|
195
|
-
* @param {LH.Config.NavigationDefn} navigation
|
|
196
194
|
* @param {LH.Config.Settings} settings
|
|
197
195
|
*/
|
|
198
|
-
function
|
|
199
|
-
if (navigation.disableThrottling) return;
|
|
196
|
+
function overrideThrottlingWindows(settings) {
|
|
200
197
|
if (settings.throttlingMethod === 'simulate') return;
|
|
201
198
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
199
|
+
settings.cpuQuietThresholdMs = Math.max(
|
|
200
|
+
settings.cpuQuietThresholdMs || 0,
|
|
201
|
+
nonSimulatedSettingsOverrides.cpuQuietThresholdMs
|
|
205
202
|
);
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
203
|
+
settings.networkQuietThresholdMs = Math.max(
|
|
204
|
+
settings.networkQuietThresholdMs || 0,
|
|
205
|
+
nonSimulatedSettingsOverrides.networkQuietThresholdMs
|
|
209
206
|
);
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
207
|
+
settings.pauseAfterFcpMs = Math.max(
|
|
208
|
+
settings.pauseAfterFcpMs || 0,
|
|
209
|
+
nonSimulatedSettingsOverrides.pauseAfterFcpMs
|
|
213
210
|
);
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
211
|
+
settings.pauseAfterLoadMs = Math.max(
|
|
212
|
+
settings.pauseAfterLoadMs || 0,
|
|
213
|
+
nonSimulatedSettingsOverrides.pauseAfterLoadMs
|
|
217
214
|
);
|
|
218
215
|
}
|
|
219
216
|
|
|
220
|
-
/**
|
|
221
|
-
* @param {LH.Config.AnyArtifactDefn[]|null|undefined} artifactDefns
|
|
222
|
-
* @param {LH.Config.Settings} settings
|
|
223
|
-
* @return {LH.Config.NavigationDefn[] | null}
|
|
224
|
-
*/
|
|
225
|
-
function resolveFakeNavigations(artifactDefns, settings) {
|
|
226
|
-
if (!artifactDefns) return null;
|
|
227
|
-
|
|
228
|
-
const status = {msg: 'Resolve navigation definitions', id: 'lh:config:resolveNavigationsToDefns'};
|
|
229
|
-
log.time(status, 'verbose');
|
|
230
|
-
|
|
231
|
-
const resolvedNavigation = {
|
|
232
|
-
...defaultNavigationConfig,
|
|
233
|
-
artifacts: artifactDefns,
|
|
234
|
-
pauseAfterFcpMs: settings.pauseAfterFcpMs,
|
|
235
|
-
pauseAfterLoadMs: settings.pauseAfterLoadMs,
|
|
236
|
-
networkQuietThresholdMs: settings.networkQuietThresholdMs,
|
|
237
|
-
cpuQuietThresholdMs: settings.cpuQuietThresholdMs,
|
|
238
|
-
blankPage: settings.blankPage,
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
overrideNavigationThrottlingWindows(resolvedNavigation, settings);
|
|
242
|
-
|
|
243
|
-
const navigations = [resolvedNavigation];
|
|
244
|
-
assertArtifactTopologicalOrder(navigations);
|
|
245
|
-
|
|
246
|
-
log.timeEnd(status);
|
|
247
|
-
return navigations;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
217
|
/**
|
|
251
218
|
* @param {LH.Gatherer.GatherMode} gatherMode
|
|
252
219
|
* @param {LH.Config=} config
|
|
253
220
|
* @param {LH.Flags=} flags
|
|
254
|
-
* @return {Promise<{resolvedConfig: LH.Config.ResolvedConfig
|
|
221
|
+
* @return {Promise<{resolvedConfig: LH.Config.ResolvedConfig}>}
|
|
255
222
|
*/
|
|
256
223
|
async function initializeConfig(gatherMode, config, flags = {}) {
|
|
257
224
|
const status = {msg: 'Initialize config', id: 'lh:config'};
|
|
@@ -264,28 +231,26 @@ async function initializeConfig(gatherMode, config, flags = {}) {
|
|
|
264
231
|
|
|
265
232
|
const settings = resolveSettings(configWorkingCopy.settings || {}, flags);
|
|
266
233
|
overrideSettingsForGatherMode(settings, gatherMode);
|
|
234
|
+
overrideThrottlingWindows(settings);
|
|
267
235
|
|
|
268
236
|
const artifacts = await resolveArtifactsToDefns(configWorkingCopy.artifacts, configDir);
|
|
269
237
|
|
|
270
|
-
const navigations = resolveFakeNavigations(artifacts, settings);
|
|
271
|
-
|
|
272
238
|
/** @type {LH.Config.ResolvedConfig} */
|
|
273
239
|
let resolvedConfig = {
|
|
274
240
|
artifacts,
|
|
275
|
-
navigations,
|
|
276
241
|
audits: await resolveAuditsToDefns(configWorkingCopy.audits, configDir),
|
|
277
242
|
categories: configWorkingCopy.categories || null,
|
|
278
243
|
groups: configWorkingCopy.groups || null,
|
|
279
244
|
settings,
|
|
280
245
|
};
|
|
281
246
|
|
|
282
|
-
|
|
247
|
+
assertValidConfig(resolvedConfig);
|
|
283
248
|
|
|
284
249
|
resolvedConfig = filterConfigByGatherMode(resolvedConfig, gatherMode);
|
|
285
250
|
resolvedConfig = filterConfigByExplicitFilters(resolvedConfig, settings);
|
|
286
251
|
|
|
287
252
|
log.timeEnd(status);
|
|
288
|
-
return {resolvedConfig
|
|
253
|
+
return {resolvedConfig};
|
|
289
254
|
}
|
|
290
255
|
|
|
291
256
|
/**
|
|
@@ -296,15 +261,6 @@ function getConfigDisplayString(resolvedConfig) {
|
|
|
296
261
|
/** @type {LH.Config.ResolvedConfig} */
|
|
297
262
|
const resolvedConfigCopy = JSON.parse(JSON.stringify(resolvedConfig));
|
|
298
263
|
|
|
299
|
-
if (resolvedConfigCopy.navigations) {
|
|
300
|
-
for (const navigation of resolvedConfigCopy.navigations) {
|
|
301
|
-
for (let i = 0; i < navigation.artifacts.length; ++i) {
|
|
302
|
-
// @ts-expect-error Breaking the Config.AnyArtifactDefn type.
|
|
303
|
-
navigation.artifacts[i] = navigation.artifacts[i].id;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
264
|
if (resolvedConfigCopy.artifacts) {
|
|
309
265
|
for (const artifactDefn of resolvedConfigCopy.artifacts) {
|
|
310
266
|
// @ts-expect-error Breaking the Config.AnyArtifactDefn type.
|
|
@@ -48,9 +48,7 @@ export namespace userAgents {
|
|
|
48
48
|
}
|
|
49
49
|
/** @type {LH.Config.Settings} */
|
|
50
50
|
export const defaultSettings: LH.Config.Settings;
|
|
51
|
-
|
|
52
|
-
export const defaultNavigationConfig: Required<LH.Config.NavigationJson>;
|
|
53
|
-
export namespace nonSimulatedPassConfigOverrides {
|
|
51
|
+
export namespace nonSimulatedSettingsOverrides {
|
|
54
52
|
const pauseAfterFcpMs: number;
|
|
55
53
|
const pauseAfterLoadMs: number;
|
|
56
54
|
const networkQuietThresholdMs: number;
|
package/core/config/constants.js
CHANGED
|
@@ -106,6 +106,7 @@ const defaultSettings = {
|
|
|
106
106
|
|
|
107
107
|
auditMode: false,
|
|
108
108
|
gatherMode: false,
|
|
109
|
+
clearStorageTypes: ['file_systems', 'shader_cache', 'service_workers', 'cache_storage'],
|
|
109
110
|
disableStorageReset: false,
|
|
110
111
|
debugNavigation: false,
|
|
111
112
|
channel: 'node',
|
|
@@ -113,6 +114,7 @@ const defaultSettings = {
|
|
|
113
114
|
disableFullPageScreenshot: false,
|
|
114
115
|
skipAboutBlank: false,
|
|
115
116
|
blankPage: 'about:blank',
|
|
117
|
+
ignoreStatusCode: false,
|
|
116
118
|
|
|
117
119
|
// the following settings have no defaults but we still want ensure that `key in settings`
|
|
118
120
|
// in config will work in a typechecked way
|
|
@@ -127,22 +129,7 @@ const defaultSettings = {
|
|
|
127
129
|
skipAudits: null,
|
|
128
130
|
};
|
|
129
131
|
|
|
130
|
-
|
|
131
|
-
const defaultNavigationConfig = {
|
|
132
|
-
id: 'defaultPass',
|
|
133
|
-
loadFailureMode: 'fatal',
|
|
134
|
-
disableThrottling: false,
|
|
135
|
-
disableStorageReset: false,
|
|
136
|
-
pauseAfterFcpMs: 0,
|
|
137
|
-
pauseAfterLoadMs: 0,
|
|
138
|
-
networkQuietThresholdMs: 0,
|
|
139
|
-
cpuQuietThresholdMs: 0,
|
|
140
|
-
blockedUrlPatterns: [],
|
|
141
|
-
blankPage: 'about:blank',
|
|
142
|
-
artifacts: [],
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
const nonSimulatedPassConfigOverrides = {
|
|
132
|
+
const nonSimulatedSettingsOverrides = {
|
|
146
133
|
pauseAfterFcpMs: 5250,
|
|
147
134
|
pauseAfterLoadMs: 5250,
|
|
148
135
|
networkQuietThresholdMs: 5250,
|
|
@@ -154,6 +141,5 @@ export {
|
|
|
154
141
|
screenEmulationMetrics,
|
|
155
142
|
userAgents,
|
|
156
143
|
defaultSettings,
|
|
157
|
-
|
|
158
|
-
nonSimulatedPassConfigOverrides,
|
|
144
|
+
nonSimulatedSettingsOverrides,
|
|
159
145
|
};
|
|
@@ -39,9 +39,9 @@ const UIStrings = {
|
|
|
39
39
|
/** Title of the Accessibility category of audits. This section contains audits focused on making web content accessible to all users. Also used as a label of a score gauge; try to limit to 20 characters. */
|
|
40
40
|
a11yCategoryTitle: 'Accessibility',
|
|
41
41
|
/** Description of the Accessibility category. This is displayed at the top of a list of audits focused on making web content accessible to all users. No character length limits. 'improve the accessibility of your web app' and 'manual testing' become link texts to additional documentation. */
|
|
42
|
-
a11yCategoryDescription: 'These checks highlight opportunities to [improve the accessibility of your web app](https://developer.chrome.com/docs/lighthouse/accessibility/). Automatic detection can only detect a subset of issues and does not guarantee the accessibility of your web app, so [manual testing](https://web.dev/how-to-review
|
|
42
|
+
a11yCategoryDescription: 'These checks highlight opportunities to [improve the accessibility of your web app](https://developer.chrome.com/docs/lighthouse/accessibility/). Automatic detection can only detect a subset of issues and does not guarantee the accessibility of your web app, so [manual testing](https://web.dev/articles/how-to-review) is also encouraged.',
|
|
43
43
|
/** Description of the Accessibility manual checks category. This description is displayed above a list of accessibility audits that currently have no automated test and so must be verified manually by the user. No character length limits. 'conducting an accessibility review' becomes link text to additional documentation. */
|
|
44
|
-
a11yCategoryManualDescription: 'These items address areas which an automated testing tool cannot cover. Learn more in our guide on [conducting an accessibility review](https://web.dev/how-to-review
|
|
44
|
+
a11yCategoryManualDescription: 'These items address areas which an automated testing tool cannot cover. Learn more in our guide on [conducting an accessibility review](https://web.dev/articles/how-to-review).',
|
|
45
45
|
/** Title of the best practices section of the Accessibility category. Within this section are audits with descriptive titles that highlight common accessibility best practices. */
|
|
46
46
|
a11yBestPracticesGroupTitle: 'Best practices',
|
|
47
47
|
/** Description of the best practices section within the Accessibility category. Within this section are audits with descriptive titles that highlight common accessibility best practices. */
|
|
@@ -79,7 +79,7 @@ const UIStrings = {
|
|
|
79
79
|
/** Description of the Search Engine Optimization (SEO) category. This is displayed at the top of a list of audits focused on optimizing a website for indexing by search engines. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
|
|
80
80
|
seoCategoryDescription: 'These checks ensure that your page is following basic search engine optimization advice. ' +
|
|
81
81
|
'There are many additional factors Lighthouse does not score here that may affect your search ranking, ' +
|
|
82
|
-
'including performance on [Core Web Vitals](https://web.dev/
|
|
82
|
+
'including performance on [Core Web Vitals](https://web.dev/explore/vitals). [Learn more about Google Search Essentials](https://support.google.com/webmasters/answer/35769).',
|
|
83
83
|
/** Description of the Search Engine Optimization (SEO) manual checks category, the additional validators must be run by hand in order to check all SEO best practices. This is displayed at the top of a list of manually run audits focused on optimizing a website for indexing by search engines. No character length limits. */
|
|
84
84
|
seoCategoryManualDescription: 'Run these additional validators on your site to check additional SEO best practices.',
|
|
85
85
|
/** Title of the navigation section within the Search Engine Optimization (SEO) category. Within this section are audits with descriptive titles that highlight opportunities to make a page more usable on mobile devices. */
|
|
@@ -99,10 +99,10 @@ const UIStrings = {
|
|
|
99
99
|
pwaCategoryTitle: 'PWA',
|
|
100
100
|
/** Description of the Progressive Web Application (PWA) category. This is displayed at the top of a list of audits focused on topics related to whether or not a site is a progressive web app, e.g. responds offline, uses a service worker, is on https, etc. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
|
|
101
101
|
pwaCategoryDescription: 'These checks validate the aspects of a Progressive Web App. ' +
|
|
102
|
-
'[Learn what makes a good Progressive Web App](https://web.dev/pwa-checklist
|
|
102
|
+
'[Learn what makes a good Progressive Web App](https://web.dev/articles/pwa-checklist).',
|
|
103
103
|
/** Description of the Progressive Web Application (PWA) manual checks category, containing a list of additional validators must be run by hand in order to check all PWA best practices. This is displayed at the top of a list of manually run audits focused on topics related to whether or not a site is a progressive web app, e.g. responds offline, uses a service worker, is on https, etc.. No character length limits. */
|
|
104
104
|
pwaCategoryManualDescription: 'These checks are required by the baseline ' +
|
|
105
|
-
'[PWA Checklist](https://web.dev/pwa-checklist
|
|
105
|
+
'[PWA Checklist](https://web.dev/articles/pwa-checklist) but are ' +
|
|
106
106
|
'not automatically checked by Lighthouse. They do not affect your score but it\'s important that you verify them manually.',
|
|
107
107
|
/** Title of the Best Practices category of audits. This is displayed at the top of a list of audits focused on topics related to following web development best practices and accepted guidelines. Also used as a label of a score gauge; try to limit to 20 characters. */
|
|
108
108
|
bestPracticesCategoryTitle: 'Best Practices',
|
|
@@ -549,7 +549,6 @@ const defaultConfig = {
|
|
|
549
549
|
{id: 'image-redundant-alt', weight: 1, group: 'a11y-names-labels'},
|
|
550
550
|
{id: 'input-button-name', weight: 10, group: 'a11y-names-labels'},
|
|
551
551
|
{id: 'input-image-alt', weight: 10, group: 'a11y-names-labels'},
|
|
552
|
-
{id: 'label-content-name-mismatch', weight: 7, group: 'a11y-names-labels'},
|
|
553
552
|
{id: 'label', weight: 7, group: 'a11y-names-labels'},
|
|
554
553
|
{id: 'link-in-text-block', weight: 7, group: 'a11y-color-contrast'},
|
|
555
554
|
{id: 'link-name', weight: 7, group: 'a11y-names-labels'},
|
|
@@ -562,8 +561,6 @@ const defaultConfig = {
|
|
|
562
561
|
{id: 'skip-link', weight: 3, group: 'a11y-names-labels'},
|
|
563
562
|
{id: 'tabindex', weight: 7, group: 'a11y-navigation'},
|
|
564
563
|
{id: 'table-duplicate-name', weight: 1, group: 'a11y-tables-lists'},
|
|
565
|
-
{id: 'table-fake-caption', weight: 7, group: 'a11y-tables-lists'},
|
|
566
|
-
{id: 'td-has-header', weight: 10, group: 'a11y-tables-lists'},
|
|
567
564
|
{id: 'td-headers-attr', weight: 7, group: 'a11y-tables-lists'},
|
|
568
565
|
{id: 'th-has-data-cells', weight: 7, group: 'a11y-tables-lists'},
|
|
569
566
|
{id: 'valid-lang', weight: 7, group: 'a11y-language'},
|
|
@@ -584,6 +581,9 @@ const defaultConfig = {
|
|
|
584
581
|
{id: 'identical-links-same-purpose', weight: 0, group: 'hidden'},
|
|
585
582
|
{id: 'landmark-one-main', weight: 0, group: 'hidden'},
|
|
586
583
|
{id: 'target-size', weight: 0, group: 'hidden'},
|
|
584
|
+
{id: 'label-content-name-mismatch', weight: 0, group: 'hidden'},
|
|
585
|
+
{id: 'table-fake-caption', weight: 0, group: 'hidden'},
|
|
586
|
+
{id: 'td-has-header', weight: 0, group: 'hidden'},
|
|
587
587
|
],
|
|
588
588
|
},
|
|
589
589
|
'best-practices': {
|
package/core/config/filters.d.ts
CHANGED
|
@@ -31,14 +31,6 @@ export function filterArtifactsByGatherMode(artifacts: LH.Config.ResolvedConfig[
|
|
|
31
31
|
* @return {LH.Config.ResolvedConfig['artifacts']}
|
|
32
32
|
*/
|
|
33
33
|
export function filterArtifactsByAvailableAudits(artifacts: LH.Config.ResolvedConfig['artifacts'], audits: LH.Config.ResolvedConfig['audits']): LH.Config.ResolvedConfig['artifacts'];
|
|
34
|
-
/**
|
|
35
|
-
* Filters an array of navigations down to the set supported by the available artifacts.
|
|
36
|
-
*
|
|
37
|
-
* @param {LH.Config.ResolvedConfig['navigations']} navigations
|
|
38
|
-
* @param {Array<LH.Config.AnyArtifactDefn>} availableArtifacts
|
|
39
|
-
* @return {LH.Config.ResolvedConfig['navigations']}
|
|
40
|
-
*/
|
|
41
|
-
export function filterNavigationsByAvailableArtifacts(navigations: LH.Config.ResolvedConfig['navigations'], availableArtifacts: Array<LH.Config.AnyArtifactDefn>): LH.Config.ResolvedConfig['navigations'];
|
|
42
34
|
/**
|
|
43
35
|
* Filters an array of audits down to the set that can be computed using only the specified artifacts.
|
|
44
36
|
*
|
package/core/config/filters.js
CHANGED
|
@@ -107,30 +107,6 @@ function filterArtifactsByGatherMode(artifacts, mode) {
|
|
|
107
107
|
});
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
/**
|
|
111
|
-
* Filters an array of navigations down to the set supported by the available artifacts.
|
|
112
|
-
*
|
|
113
|
-
* @param {LH.Config.ResolvedConfig['navigations']} navigations
|
|
114
|
-
* @param {Array<LH.Config.AnyArtifactDefn>} availableArtifacts
|
|
115
|
-
* @return {LH.Config.ResolvedConfig['navigations']}
|
|
116
|
-
*/
|
|
117
|
-
function filterNavigationsByAvailableArtifacts(navigations, availableArtifacts) {
|
|
118
|
-
if (!navigations) return navigations;
|
|
119
|
-
|
|
120
|
-
const availableArtifactIds = new Set(
|
|
121
|
-
availableArtifacts.map(artifact => artifact.id).concat(baseArtifactKeys)
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
return navigations
|
|
125
|
-
.map(navigation => {
|
|
126
|
-
return {
|
|
127
|
-
...navigation,
|
|
128
|
-
artifacts: navigation.artifacts.filter((artifact) => availableArtifactIds.has(artifact.id)),
|
|
129
|
-
};
|
|
130
|
-
})
|
|
131
|
-
.filter(navigation => navigation.artifacts.length);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
110
|
/**
|
|
135
111
|
* Filters an array of audits down to the set that can be computed using only the specified artifacts.
|
|
136
112
|
*
|
|
@@ -318,13 +294,10 @@ function filterConfigByExplicitFilters(resolvedConfig, filters) {
|
|
|
318
294
|
if (artifacts && resolvedConfig.settings.disableFullPageScreenshot) {
|
|
319
295
|
artifacts = artifacts.filter(({id}) => id !== 'FullPageScreenshot');
|
|
320
296
|
}
|
|
321
|
-
const navigations =
|
|
322
|
-
filterNavigationsByAvailableArtifacts(resolvedConfig.navigations, artifacts || []);
|
|
323
297
|
|
|
324
298
|
return {
|
|
325
299
|
...resolvedConfig,
|
|
326
300
|
artifacts,
|
|
327
|
-
navigations,
|
|
328
301
|
audits,
|
|
329
302
|
categories,
|
|
330
303
|
};
|
|
@@ -335,7 +308,6 @@ export {
|
|
|
335
308
|
filterConfigByExplicitFilters,
|
|
336
309
|
filterArtifactsByGatherMode,
|
|
337
310
|
filterArtifactsByAvailableAudits,
|
|
338
|
-
filterNavigationsByAvailableArtifacts,
|
|
339
311
|
filterAuditsByAvailableArtifacts,
|
|
340
312
|
filterAuditsByGatherMode,
|
|
341
313
|
filterCategoriesByAvailableAudits,
|
|
@@ -19,14 +19,6 @@ export function assertValidPluginName(config: LH.Config, pluginName: string): vo
|
|
|
19
19
|
* @param {LH.Config.AnyArtifactDefn} artifactDefn
|
|
20
20
|
*/
|
|
21
21
|
export function assertValidArtifact(artifactDefn: LH.Config.AnyArtifactDefn): void;
|
|
22
|
-
/**
|
|
23
|
-
* Throws an error if the provided object does not implement the required navigations interface.
|
|
24
|
-
* @param {LH.Config.ResolvedConfig['navigations']} navigationsDefn
|
|
25
|
-
* @return {{warnings: string[]}}
|
|
26
|
-
*/
|
|
27
|
-
export function assertValidNavigations(navigationsDefn: LH.Config.ResolvedConfig['navigations']): {
|
|
28
|
-
warnings: string[];
|
|
29
|
-
};
|
|
30
22
|
/**
|
|
31
23
|
* Throws an error if the provided object does not implement the required properties of an audit
|
|
32
24
|
* definition.
|
|
@@ -45,18 +37,15 @@ export function assertValidCategories(categories: LH.Config.ResolvedConfig['cate
|
|
|
45
37
|
*/
|
|
46
38
|
export function assertValidSettings(settings: LH.Config.Settings): void;
|
|
47
39
|
/**
|
|
48
|
-
* Asserts that artifacts are in a
|
|
40
|
+
* Asserts that artifacts are unique, valid and are in a dependency order that can be computed.
|
|
49
41
|
*
|
|
50
|
-
* @param {Array<LH.Config.
|
|
42
|
+
* @param {Array<LH.Config.AnyArtifactDefn>} artifactDefns
|
|
51
43
|
*/
|
|
52
|
-
export function
|
|
44
|
+
export function assertValidArtifacts(artifactDefns: Array<LH.Config.AnyArtifactDefn>): void;
|
|
53
45
|
/**
|
|
54
46
|
* @param {LH.Config.ResolvedConfig} resolvedConfig
|
|
55
|
-
* @return {{warnings: string[]}}
|
|
56
47
|
*/
|
|
57
|
-
export function assertValidConfig(resolvedConfig: LH.Config.ResolvedConfig):
|
|
58
|
-
warnings: string[];
|
|
59
|
-
};
|
|
48
|
+
export function assertValidConfig(resolvedConfig: LH.Config.ResolvedConfig): void;
|
|
60
49
|
/**
|
|
61
50
|
* @param {string} artifactId
|
|
62
51
|
* @param {string} dependencyKey
|
|
@@ -68,43 +68,6 @@ function assertValidArtifact(artifactDefn) {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
/**
|
|
72
|
-
* Throws an error if the provided object does not implement the required navigations interface.
|
|
73
|
-
* @param {LH.Config.ResolvedConfig['navigations']} navigationsDefn
|
|
74
|
-
* @return {{warnings: string[]}}
|
|
75
|
-
*/
|
|
76
|
-
function assertValidNavigations(navigationsDefn) {
|
|
77
|
-
if (!navigationsDefn || !navigationsDefn.length) return {warnings: []};
|
|
78
|
-
|
|
79
|
-
/** @type {string[]} */
|
|
80
|
-
const warnings = [];
|
|
81
|
-
|
|
82
|
-
// Assert that the first navigation has loadFailureMode fatal.
|
|
83
|
-
const firstNavigation = navigationsDefn[0];
|
|
84
|
-
if (firstNavigation.loadFailureMode !== 'fatal') {
|
|
85
|
-
const currentMode = firstNavigation.loadFailureMode;
|
|
86
|
-
const warning = [
|
|
87
|
-
`"${firstNavigation.id}" is the first navigation but had a failure mode of ${currentMode}.`,
|
|
88
|
-
`The first navigation will always be treated as loadFailureMode=fatal.`,
|
|
89
|
-
].join(' ');
|
|
90
|
-
|
|
91
|
-
warnings.push(warning);
|
|
92
|
-
firstNavigation.loadFailureMode = 'fatal';
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Assert that navigations have unique IDs.
|
|
96
|
-
const navigationIds = navigationsDefn.map(navigation => navigation.id);
|
|
97
|
-
const duplicateId = navigationIds.find(
|
|
98
|
-
(id, i) => navigationIds.slice(i + 1).some(other => id === other)
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
if (duplicateId) {
|
|
102
|
-
throw new Error(`Navigation must have unique identifiers, but "${duplicateId}" was repeated.`);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return {warnings};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
71
|
/**
|
|
109
72
|
* Throws an error if the provided object does not implement the required properties of an audit
|
|
110
73
|
* definition.
|
|
@@ -223,42 +186,36 @@ function assertValidSettings(settings) {
|
|
|
223
186
|
}
|
|
224
187
|
|
|
225
188
|
/**
|
|
226
|
-
* Asserts that artifacts are in a
|
|
189
|
+
* Asserts that artifacts are unique, valid and are in a dependency order that can be computed.
|
|
227
190
|
*
|
|
228
|
-
* @param {Array<LH.Config.
|
|
191
|
+
* @param {Array<LH.Config.AnyArtifactDefn>} artifactDefns
|
|
229
192
|
*/
|
|
230
|
-
function
|
|
193
|
+
function assertValidArtifacts(artifactDefns) {
|
|
194
|
+
/** @type {Set<string>} */
|
|
231
195
|
const availableArtifacts = new Set();
|
|
232
196
|
|
|
233
|
-
for (const
|
|
234
|
-
|
|
235
|
-
availableArtifacts.add(artifact.id);
|
|
236
|
-
if (!artifact.dependencies) continue;
|
|
197
|
+
for (const artifact of artifactDefns) {
|
|
198
|
+
assertValidArtifact(artifact);
|
|
237
199
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
200
|
+
if (availableArtifacts.has(artifact.id)) {
|
|
201
|
+
throw new Error(`Config defined multiple artifacts with id '${artifact.id}'`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
availableArtifacts.add(artifact.id);
|
|
205
|
+
if (!artifact.dependencies) continue;
|
|
206
|
+
|
|
207
|
+
for (const [dependencyKey, {id: dependencyId}] of Object.entries(artifact.dependencies)) {
|
|
208
|
+
if (availableArtifacts.has(dependencyId)) continue;
|
|
209
|
+
throwInvalidDependencyOrder(artifact.id, dependencyKey);
|
|
242
210
|
}
|
|
243
211
|
}
|
|
244
212
|
}
|
|
245
213
|
|
|
246
214
|
/**
|
|
247
215
|
* @param {LH.Config.ResolvedConfig} resolvedConfig
|
|
248
|
-
* @return {{warnings: string[]}}
|
|
249
216
|
*/
|
|
250
217
|
function assertValidConfig(resolvedConfig) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
/** @type {Set<string>} */
|
|
254
|
-
const artifactIds = new Set();
|
|
255
|
-
for (const artifactDefn of resolvedConfig.artifacts || []) {
|
|
256
|
-
if (artifactIds.has(artifactDefn.id)) {
|
|
257
|
-
throw new Error(`Config defined multiple artifacts with id '${artifactDefn.id}'`);
|
|
258
|
-
}
|
|
259
|
-
artifactIds.add(artifactDefn.id);
|
|
260
|
-
assertValidArtifact(artifactDefn);
|
|
261
|
-
}
|
|
218
|
+
assertValidArtifacts(resolvedConfig.artifacts || []);
|
|
262
219
|
|
|
263
220
|
for (const auditDefn of resolvedConfig.audits || []) {
|
|
264
221
|
assertValidAudit(auditDefn);
|
|
@@ -266,7 +223,6 @@ function assertValidConfig(resolvedConfig) {
|
|
|
266
223
|
|
|
267
224
|
assertValidCategories(resolvedConfig.categories, resolvedConfig.audits, resolvedConfig.groups);
|
|
268
225
|
assertValidSettings(resolvedConfig.settings);
|
|
269
|
-
return {warnings};
|
|
270
226
|
}
|
|
271
227
|
|
|
272
228
|
/**
|
|
@@ -303,11 +259,10 @@ export {
|
|
|
303
259
|
isValidArtifactDependency,
|
|
304
260
|
assertValidPluginName,
|
|
305
261
|
assertValidArtifact,
|
|
306
|
-
assertValidNavigations,
|
|
307
262
|
assertValidAudit,
|
|
308
263
|
assertValidCategories,
|
|
309
264
|
assertValidSettings,
|
|
310
|
-
|
|
265
|
+
assertValidArtifacts,
|
|
311
266
|
assertValidConfig,
|
|
312
267
|
throwInvalidDependencyOrder,
|
|
313
268
|
throwInvalidArtifactDependency,
|
|
@@ -9,8 +9,8 @@ export function getBaseArtifacts(resolvedConfig: LH.Config.ResolvedConfig, drive
|
|
|
9
9
|
}): Promise<LH.BaseArtifacts>;
|
|
10
10
|
/**
|
|
11
11
|
* @param {LH.BaseArtifacts} baseArtifacts
|
|
12
|
-
* @param {Partial<LH.
|
|
12
|
+
* @param {Partial<LH.GathererArtifacts>} gathererArtifacts
|
|
13
13
|
* @return {LH.Artifacts}
|
|
14
14
|
*/
|
|
15
|
-
export function finalizeArtifacts(baseArtifacts: LH.BaseArtifacts, gathererArtifacts: Partial<LH.
|
|
15
|
+
export function finalizeArtifacts(baseArtifacts: LH.BaseArtifacts, gathererArtifacts: Partial<LH.GathererArtifacts>): LH.Artifacts;
|
|
16
16
|
//# sourceMappingURL=base-artifacts.d.ts.map
|
|
@@ -60,20 +60,20 @@ function deduplicateWarnings(warnings) {
|
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* @param {LH.BaseArtifacts} baseArtifacts
|
|
63
|
-
* @param {Partial<LH.
|
|
63
|
+
* @param {Partial<LH.GathererArtifacts>} gathererArtifacts
|
|
64
64
|
* @return {LH.Artifacts}
|
|
65
65
|
*/
|
|
66
66
|
function finalizeArtifacts(baseArtifacts, gathererArtifacts) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
baseArtifacts.LighthouseRunWarnings.push(
|
|
68
|
+
...getEnvironmentWarnings({settings: baseArtifacts.settings, baseArtifacts})
|
|
69
|
+
);
|
|
70
70
|
|
|
71
71
|
// Cast to remove the partial from gathererArtifacts.
|
|
72
72
|
const artifacts = /** @type {LH.Artifacts} */ ({...baseArtifacts, ...gathererArtifacts});
|
|
73
73
|
|
|
74
74
|
// Set the post-run meta artifacts.
|
|
75
75
|
artifacts.Timing = log.getTimeEntries();
|
|
76
|
-
artifacts.LighthouseRunWarnings = deduplicateWarnings(
|
|
76
|
+
artifacts.LighthouseRunWarnings = deduplicateWarnings(baseArtifacts.LighthouseRunWarnings);
|
|
77
77
|
|
|
78
78
|
if (artifacts.PageLoadError && !artifacts.URL.finalDisplayedUrl) {
|
|
79
79
|
artifacts.URL.finalDisplayedUrl = artifacts.URL.requestedUrl || '';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type NavigationOptions = {
|
|
2
2
|
waitUntil: Array<'fcp' | 'load' | 'navigated'>;
|
|
3
|
-
} &
|
|
3
|
+
} & Partial<LH.Config.Settings>;
|
|
4
4
|
/**
|
|
5
5
|
* Navigates to the given URL, assuming that the page is not already on this URL.
|
|
6
6
|
* Resolves on the url of the loaded page, taking into account any redirects.
|
|
@@ -39,7 +39,7 @@ const DEFAULT_NETWORK_QUIET_THRESHOLD = 5000;
|
|
|
39
39
|
// Controls how long to wait between longtasks before determining the CPU is idle, off by default
|
|
40
40
|
const DEFAULT_CPU_QUIET_THRESHOLD = 0;
|
|
41
41
|
|
|
42
|
-
/** @typedef {{waitUntil: Array<'fcp'|'load'|'navigated'>} &
|
|
42
|
+
/** @typedef {{waitUntil: Array<'fcp'|'load'|'navigated'>} & Partial<LH.Config.Settings>} NavigationOptions */
|
|
43
43
|
|
|
44
44
|
/** @param {NavigationOptions} options */
|
|
45
45
|
function resolveWaitForFullyLoadedOptions(options) {
|
|
@@ -5,12 +5,8 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @param {LH.Gatherer.ProtocolSession} session
|
|
7
7
|
* @param {LH.Config.Settings} settings
|
|
8
|
-
* @param {{disableThrottling: boolean, blockedUrlPatterns?: string[]}} options
|
|
9
8
|
*/
|
|
10
|
-
export function prepareThrottlingAndNetwork(session: LH.Gatherer.ProtocolSession, settings: LH.Config.Settings
|
|
11
|
-
disableThrottling: boolean;
|
|
12
|
-
blockedUrlPatterns?: string[];
|
|
13
|
-
}): Promise<void>;
|
|
9
|
+
export function prepareThrottlingAndNetwork(session: LH.Gatherer.ProtocolSession, settings: LH.Config.Settings): Promise<void>;
|
|
14
10
|
/**
|
|
15
11
|
* Prepares a target to be analyzed in timespan mode by enabling protocol domains, emulation, and throttling.
|
|
16
12
|
*
|
|
@@ -26,21 +22,10 @@ export function prepareTargetForTimespanMode(driver: LH.Gatherer.Driver, setting
|
|
|
26
22
|
*
|
|
27
23
|
* @param {LH.Gatherer.Driver} driver
|
|
28
24
|
* @param {LH.Config.Settings} settings
|
|
29
|
-
|
|
30
|
-
export function prepareTargetForNavigationMode(driver: LH.Gatherer.Driver, settings: LH.Config.Settings): Promise<void>;
|
|
31
|
-
/**
|
|
32
|
-
* Prepares a target for a particular navigation by resetting storage and setting network.
|
|
33
|
-
*
|
|
34
|
-
* This method assumes `prepareTargetForNavigationMode` has already been invoked.
|
|
35
|
-
*
|
|
36
|
-
* @param {LH.Gatherer.ProtocolSession} session
|
|
37
|
-
* @param {LH.Config.Settings} settings
|
|
38
|
-
* @param {Pick<LH.Config.NavigationDefn, 'disableThrottling'|'disableStorageReset'|'blockedUrlPatterns'> & {requestor: LH.NavigationRequestor}} navigation
|
|
25
|
+
* @param {LH.NavigationRequestor} requestor
|
|
39
26
|
* @return {Promise<{warnings: Array<LH.IcuMessage>}>}
|
|
40
27
|
*/
|
|
41
|
-
export function
|
|
42
|
-
requestor: LH.NavigationRequestor;
|
|
43
|
-
}): Promise<{
|
|
28
|
+
export function prepareTargetForNavigationMode(driver: LH.Gatherer.Driver, settings: LH.Config.Settings, requestor: LH.NavigationRequestor): Promise<{
|
|
44
29
|
warnings: Array<LH.IcuMessage>;
|
|
45
30
|
}>;
|
|
46
31
|
/**
|