lighthouse 10.0.0-dev.20230213 → 10.0.1

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.
Files changed (75) hide show
  1. package/core/audits/dobetterweb/doctype.d.ts +3 -2
  2. package/core/audits/dobetterweb/doctype.js +15 -4
  3. package/core/audits/dobetterweb/paste-preventing-inputs.js +2 -2
  4. package/core/gather/driver/network-monitor.js +1 -3
  5. package/core/gather/gatherers/bf-cache-failures.js +7 -8
  6. package/package.json +1 -1
  7. package/shared/localization/locales/en-US.json +1 -1
  8. package/shared/localization/locales/en-XL.json +1 -1
  9. package/.codecov.yml +0 -22
  10. package/.cz-config.js +0 -24
  11. package/.gitattributes +0 -5
  12. package/.mailmap +0 -6
  13. package/CODE_OF_CONDUCT.md +0 -93
  14. package/eslint-local-rules.cjs +0 -106
  15. package/flow-report/test/app-test.d.ts +0 -7
  16. package/flow-report/test/app-test.tsx +0 -52
  17. package/flow-report/test/common-test.d.ts +0 -7
  18. package/flow-report/test/common-test.tsx +0 -103
  19. package/flow-report/test/flow-report-pptr-test.d.ts +0 -7
  20. package/flow-report/test/flow-report-pptr-test.ts +0 -59
  21. package/flow-report/test/header-test.d.ts +0 -7
  22. package/flow-report/test/header-test.tsx +0 -55
  23. package/flow-report/test/run-flow-report-tests.sh +0 -20
  24. package/flow-report/test/sample-flow.d.ts +0 -7
  25. package/flow-report/test/sample-flow.ts +0 -17
  26. package/flow-report/test/setup/env-setup.d.ts +0 -11
  27. package/flow-report/test/setup/env-setup.ts +0 -55
  28. package/flow-report/test/sidebar/flow-test.d.ts +0 -7
  29. package/flow-report/test/sidebar/flow-test.tsx +0 -65
  30. package/flow-report/test/sidebar/sidebar-test.d.ts +0 -7
  31. package/flow-report/test/sidebar/sidebar-test.tsx +0 -116
  32. package/flow-report/test/summary/category-test.d.ts +0 -7
  33. package/flow-report/test/summary/category-test.tsx +0 -206
  34. package/flow-report/test/summary/summary-test.d.ts +0 -7
  35. package/flow-report/test/summary/summary-test.tsx +0 -124
  36. package/flow-report/test/topbar-test.d.ts +0 -7
  37. package/flow-report/test/topbar-test.tsx +0 -84
  38. package/flow-report/test/util-test.d.ts +0 -7
  39. package/flow-report/test/util-test.tsx +0 -133
  40. package/flow-report/test/wrappers/category-score-test.d.ts +0 -7
  41. package/flow-report/test/wrappers/category-score-test.tsx +0 -84
  42. package/flow-report/test/wrappers/markdown-test.d.ts +0 -7
  43. package/flow-report/test/wrappers/markdown-test.tsx +0 -17
  44. package/report/test/clients/bundle-test.js +0 -65
  45. package/report/test/generator/file-namer-test.js +0 -27
  46. package/report/test/generator/report-generator-test.js +0 -160
  47. package/report/test/renderer/__snapshots__/report-renderer-axe-test.js.snap +0 -15
  48. package/report/test/renderer/category-renderer-test.js +0 -575
  49. package/report/test/renderer/components-test.js +0 -124
  50. package/report/test/renderer/crc-details-renderer-test.js +0 -116
  51. package/report/test/renderer/details-renderer-test.js +0 -882
  52. package/report/test/renderer/dom-test.js +0 -257
  53. package/report/test/renderer/element-screenshot-renderer-test.js +0 -183
  54. package/report/test/renderer/i18n-formatter-test.js +0 -179
  55. package/report/test/renderer/performance-category-renderer-test.js +0 -417
  56. package/report/test/renderer/pwa-category-renderer-test.js +0 -301
  57. package/report/test/renderer/report-renderer-axe-test.js +0 -85
  58. package/report/test/renderer/report-renderer-test.js +0 -268
  59. package/report/test/renderer/report-ui-features-test.js +0 -773
  60. package/report/test/renderer/report-utils-test.js +0 -219
  61. package/report/test/renderer/snippet-renderer-test.js +0 -291
  62. package/report/test/renderer/text-encoding-test.js +0 -43
  63. package/report/test-assets/faux-psi-template.html +0 -177
  64. package/report/test-assets/faux-psi.d.ts +0 -34
  65. package/report/test-assets/faux-psi.js +0 -168
  66. package/report/test-assets/lhr-3.0.0.json +0 -2332
  67. package/report/test-assets/lhr-4.3.0.json +0 -4754
  68. package/report/test-assets/lhr-5.0.0.json +0 -5994
  69. package/report/test-assets/lhr-6.0.0.json +0 -7222
  70. package/report/test-assets/lhr-8.5.0.json +0 -8679
  71. package/shared/test/localization/format-test.js +0 -430
  72. package/shared/test/localization/locales-test.js +0 -45
  73. package/shared/test/localization/swap-locale-test.js +0 -127
  74. package/shared/test/util-test.js +0 -214
  75. package/vercel.json +0 -6
@@ -1,417 +0,0 @@
1
- /**
2
- * @license Copyright 2017 The Lighthouse Authors. All Rights Reserved.
3
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
5
- */
6
-
7
- import assert from 'assert/strict';
8
-
9
- import jsdom from 'jsdom';
10
-
11
- import {ReportUtils} from '../../renderer/report-utils.js';
12
- import {I18nFormatter} from '../../renderer/i18n-formatter.js';
13
- import {DOM} from '../../renderer/dom.js';
14
- import {DetailsRenderer} from '../../renderer/details-renderer.js';
15
- import {PerformanceCategoryRenderer} from '../../renderer/performance-category-renderer.js';
16
- import {readJson} from '../../../core/test/test-utils.js';
17
- import {Globals} from '../../renderer/report-globals.js';
18
-
19
- const sampleResultsOrig = readJson('../../../core/test/results/sample_v2.json', import.meta);
20
-
21
- describe('PerfCategoryRenderer', () => {
22
- let category;
23
- let renderer;
24
- let sampleResults;
25
-
26
- before(() => {
27
- Globals.apply({
28
- providedStrings: {},
29
- i18n: new I18nFormatter('en'),
30
- reportJson: null,
31
- });
32
-
33
- const {document} = new jsdom.JSDOM().window;
34
- const dom = new DOM(document);
35
- const detailsRenderer = new DetailsRenderer(dom);
36
- renderer = new PerformanceCategoryRenderer(dom, detailsRenderer);
37
-
38
- // TODO: don't call a LH.ReportResult `sampleResults`, which is typically always LH.Result
39
- sampleResults = ReportUtils.prepareReportResult(sampleResultsOrig);
40
- category = sampleResults.categories.performance;
41
- });
42
-
43
- after(() => {
44
- Globals.i18n = undefined;
45
- });
46
-
47
- it('renders the category header', () => {
48
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
49
- const score = categoryDOM.querySelector('.lh-category-header');
50
- const value = categoryDOM.querySelector('.lh-category-header .lh-gauge__percentage');
51
- const title = score.querySelector('.lh-gauge__label');
52
-
53
- assert.deepEqual(score, score.firstElementChild, 'first child is a score');
54
- const scoreInDom = Number(value.textContent);
55
- assert.ok(Number.isInteger(scoreInDom) && scoreInDom > 10, 'category score is rounded');
56
- assert.equal(title.textContent, category.title, 'title is set');
57
- });
58
-
59
- it('renders the sections', () => {
60
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
61
- const sections = categoryDOM.querySelectorAll('.lh-category > .lh-audit-group');
62
- assert.equal(sections.length, 5);
63
- });
64
-
65
- it('renders the metrics', () => {
66
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
67
- const metricsSection = categoryDOM.querySelectorAll('.lh-category > .lh-audit-group')[0];
68
-
69
- const metricAudits = category.auditRefs.filter(audit => audit.group === 'metrics');
70
- const timelineElements = metricsSection.querySelectorAll('.lh-metric');
71
- const nontimelineElements = metricsSection.querySelectorAll('.lh-audit');
72
- assert.equal(timelineElements.length + nontimelineElements.length, metricAudits.length);
73
- assert.deepStrictEqual(
74
- Array.from(timelineElements).map(el => el.id),
75
- [
76
- 'first-contentful-paint',
77
- 'largest-contentful-paint',
78
- 'total-blocking-time',
79
- 'cumulative-layout-shift',
80
- 'speed-index',
81
- ]
82
- );
83
- });
84
-
85
- it('renders notApplicable metrics with n/a text', () => {
86
- const perfWithNaMetric = JSON.parse(JSON.stringify(category));
87
- const tbt = perfWithNaMetric.auditRefs.find(audit => audit.id === 'total-blocking-time');
88
- assert(tbt);
89
- const {id, title, description} = tbt.result;
90
- tbt.result = {
91
- id,
92
- title,
93
- description,
94
- scoreDisplayMode: 'notApplicable',
95
- score: null,
96
- };
97
-
98
- const perfDom = renderer.render(perfWithNaMetric, sampleResults.categoryGroups);
99
- const tbtElement = perfDom.querySelector('.lh-metric#total-blocking-time');
100
- assert(tbtElement);
101
- assert.equal(tbtElement.querySelector('.lh-metric__title').textContent, 'Total Blocking Time');
102
- assert.equal(tbtElement.querySelector('.lh-metric__value').textContent, '--');
103
- });
104
-
105
- it('does not render metrics section if no metric group audits', () => {
106
- // Remove metrics from category
107
- const newCategory = JSON.parse(JSON.stringify(category));
108
- newCategory.auditRefs = category.auditRefs.filter(audit => audit.group !== 'metrics');
109
-
110
- const categoryDOM = renderer.render(newCategory, sampleResults.categoryGroups);
111
- const sections = categoryDOM.querySelectorAll('.lh-category > .lh-audit-group');
112
- const metricSection = categoryDOM.querySelector('.lh-audit-group--metrics');
113
- assert.ok(!metricSection);
114
- assert.equal(sections.length, 4);
115
- });
116
-
117
- it('renders the metrics variance disclaimer as markdown', () => {
118
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
119
- const disclaimerEl =
120
- categoryDOM.querySelector('.lh-category-header__description > .lh-metrics__disclaimer');
121
-
122
- assert.ok(disclaimerEl.textContent.includes('Values are estimated'));
123
- const disclamerLink = disclaimerEl.querySelector('a');
124
- assert.ok(disclamerLink, 'disclaimer contains coverted markdown link');
125
- const disclamerUrl = new URL(disclamerLink.href);
126
- assert.strictEqual(disclamerUrl.hostname, 'developer.chrome.com');
127
- const calcLink = disclaimerEl.querySelector('a.lh-calclink');
128
- assert.ok(calcLink, 'disclaimer contains scorecalc link');
129
- assert.strictEqual(new URL(calcLink.href).hostname, 'googlechrome.github.io');
130
- });
131
-
132
- it('does not render disclaimer if there is no category gauge', () => {
133
- // Timespan mode uses a category fraction instead of a gauge.
134
- const categoryDOM = renderer.render(
135
- category,
136
- sampleResults.categoryGroups,
137
- {gatherMode: 'timespan'}
138
- );
139
- const disclaimerEl = categoryDOM.querySelector('.lh-metrics__disclaimer');
140
- assert.ok(!disclaimerEl);
141
- });
142
-
143
- it('ignores hidden audits', () => {
144
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
145
-
146
- const hiddenAudits = category.auditRefs.filter(audit => audit.group === 'hidden');
147
- const auditElements = [...categoryDOM.querySelectorAll('.lh-audit')];
148
- const matchingElements = auditElements
149
- .filter(el => hiddenAudits.some(audit => audit.id === el.id));
150
- expect(matchingElements).toHaveLength(0);
151
- });
152
-
153
- it('renders the failing performance opportunities', () => {
154
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
155
-
156
- const oppAudits = category.auditRefs.filter(audit =>
157
- audit.result.details &&
158
- audit.result.details.type === 'opportunity' &&
159
- !ReportUtils.showAsPassed(audit.result));
160
- const oppElements = [...categoryDOM.querySelectorAll('.lh-audit--load-opportunity')];
161
- expect(oppElements.map(e => e.id).sort()).toEqual(oppAudits.map(a => a.id).sort());
162
- expect(oppElements.length).toBeGreaterThan(0);
163
- expect(oppElements.length).toMatchInlineSnapshot('6');
164
-
165
- const oppElement = oppElements[0];
166
- const oppSparklineBarElement = oppElement.querySelector('.lh-sparkline__bar');
167
- const oppSparklineElement = oppElement.querySelector('.lh-load-opportunity__sparkline');
168
- const oppTitleElement = oppElement.querySelector('.lh-audit__title');
169
- const oppWastedElement = oppElement.querySelector('.lh-audit__display-text');
170
- assert.ok(oppTitleElement.textContent, 'did not render title');
171
- assert.ok(oppSparklineBarElement.style.width, 'did not set sparkline width');
172
- assert.ok(oppWastedElement.textContent, 'did not render stats');
173
- assert.ok(oppSparklineElement.title, 'did not set tooltip on sparkline');
174
- });
175
-
176
- it('renders performance opportunities with an errorMessage', () => {
177
- const auditWithError = {
178
- score: 0,
179
- result: {
180
- score: null, scoreDisplayMode: 'error', errorMessage: 'Yikes!!', title: 'Bug #2',
181
- description: '',
182
- details: {
183
- overallSavingsMs: 0,
184
- items: [],
185
- type: 'opportunity',
186
- },
187
- },
188
- };
189
-
190
- const fakeCategory = Object.assign({}, category, {auditRefs: [auditWithError]});
191
- const categoryDOM = renderer.render(fakeCategory, sampleResults.categoryGroups);
192
- const tooltipEl = categoryDOM.querySelector('.lh-audit--load-opportunity .lh-tooltip--error');
193
- assert.ok(tooltipEl, 'did not render error message');
194
- assert.ok(/Yikes!!/.test(tooltipEl.textContent));
195
- });
196
-
197
- it('renders performance opportunities\' explanation', () => {
198
- const auditWithExplanation = {
199
- score: 0,
200
- result: {
201
- score: 0, scoreDisplayMode: 'numeric',
202
- numericValue: 100, explanation: 'Yikes!!', title: 'Bug #2', description: '',
203
- details: {
204
- overallSavingsMs: 0,
205
- items: [],
206
- type: 'opportunity',
207
- },
208
- },
209
- };
210
-
211
- const fakeCategory = Object.assign({}, category, {auditRefs: [auditWithExplanation]});
212
- const categoryDOM = renderer.render(fakeCategory, sampleResults.categoryGroups);
213
-
214
- const selector = '.lh-audit--load-opportunity .lh-audit-explanation';
215
- const tooltipEl = categoryDOM.querySelector(selector);
216
- assert.ok(tooltipEl, 'did not render explanation text');
217
- assert.ok(/Yikes!!/.test(tooltipEl.textContent));
218
- });
219
-
220
- it('renders the failing diagnostics', () => {
221
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
222
- const diagnosticSection = categoryDOM.querySelector(
223
- '.lh-category > .lh-audit-group.lh-audit-group--diagnostics');
224
-
225
- const diagnosticAuditIds = category.auditRefs.filter(audit => {
226
- return !audit.group &&
227
- !(audit.result.details && audit.result.details.type === 'opportunity') &&
228
- !ReportUtils.showAsPassed(audit.result);
229
- }).map(audit => audit.id).sort();
230
- assert.ok(diagnosticAuditIds.length > 0);
231
-
232
- const diagnosticElementIds = [...diagnosticSection.querySelectorAll('.lh-audit')]
233
- .map(el => el.id).sort();
234
- assert.deepStrictEqual(diagnosticElementIds, diagnosticAuditIds);
235
- });
236
-
237
- it('renders the passed audits', () => {
238
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
239
- const passedSection = categoryDOM.querySelector('.lh-clump--passed');
240
-
241
- const passedAudits = category.auditRefs.filter(audit =>
242
- !audit.group &&
243
- ReportUtils.showAsPassed(audit.result));
244
- const passedElements = passedSection.querySelectorAll('.lh-audit');
245
- assert.equal(passedElements.length, passedAudits.length);
246
- });
247
-
248
- // Unsupported by perf cat renderer right now.
249
- it.skip('renders any manual audits', () => {
250
- });
251
-
252
- describe('getWastedMs', () => {
253
- it('handles erroring opportunities', () => {
254
- const auditWithDebug = {
255
- score: 0,
256
- result: {
257
- error: true, score: 0,
258
- numericValue: 100, explanation: 'Yikes!!', title: 'Bug #2',
259
- details: {
260
- overallSavingsMs: 0,
261
- items: [],
262
- type: 'opportunity',
263
- },
264
- },
265
- };
266
- const wastedMs = renderer._getWastedMs(auditWithDebug);
267
- assert.ok(Number.isFinite(wastedMs), 'Finite number not returned by wastedMs');
268
- });
269
- });
270
-
271
- describe('budgets', () => {
272
- it('renders the group and header', () => {
273
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
274
-
275
- const budgetsGroup = categoryDOM.querySelector('.lh-audit-group.lh-audit-group--budgets');
276
- assert.ok(budgetsGroup);
277
-
278
- const header = budgetsGroup.querySelector('.lh-audit-group__header');
279
- assert.ok(header);
280
- });
281
-
282
- it('renders the performance budget table', () => {
283
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
284
- const budgetTable = categoryDOM.querySelector('#performance-budget.lh-table');
285
- assert.ok(budgetTable);
286
-
287
- const lhrBudgetEntries = sampleResults.audits['performance-budget'].details.items;
288
- const tableRows = budgetTable.querySelectorAll('tbody > tr');
289
- assert.strictEqual(tableRows.length, lhrBudgetEntries.length);
290
- });
291
-
292
- it('renders the timing budget table', () => {
293
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
294
- const budgetTable = categoryDOM.querySelector('#timing-budget.lh-table');
295
- assert.ok(budgetTable);
296
-
297
- const lhrBudgetEntries = sampleResults.audits['timing-budget'].details.items;
298
- const tableRows = budgetTable.querySelectorAll('tbody > tr');
299
- assert.strictEqual(tableRows.length, lhrBudgetEntries.length);
300
- });
301
-
302
- it('does not render the budgets section when all budget audits are notApplicable', () => {
303
- const budgetlessCategory = JSON.parse(JSON.stringify(category));
304
- ['performance-budget', 'timing-budget'].forEach((id) => {
305
- const budgetRef = budgetlessCategory.auditRefs.find(a => a.id === id);
306
- budgetRef.result.scoreDisplayMode = 'notApplicable';
307
- delete budgetRef.result.details;
308
- });
309
-
310
- const categoryDOM = renderer.render(budgetlessCategory, sampleResults.categoryGroups);
311
- const budgetsGroup = categoryDOM.querySelector('.lh-audit-group.lh-audit-group--budgets');
312
- assert.strictEqual(budgetsGroup, null);
313
- });
314
- });
315
-
316
- describe('_getScoringCalculatorHref', () => {
317
- it('creates a working link given some auditRefs', () => {
318
- const categoryClone = JSON.parse(JSON.stringify(category));
319
-
320
- // CLS of 0 is both valid and falsy. Make sure it doesn't become 'null'
321
- const cls = categoryClone.auditRefs.find(audit => audit.id === 'cumulative-layout-shift');
322
- cls.result.numericValue = 0;
323
-
324
- const href = renderer._getScoringCalculatorHref(categoryClone.auditRefs);
325
- const url = new URL(href);
326
- expect(url.hash.split('&')).toMatchInlineSnapshot(`
327
- Array [
328
- "#FCP=6844",
329
- "LCP=9320",
330
- "TBT=1221",
331
- "CLS=0",
332
- "SI=8114",
333
- "TTI=8191",
334
- "FMP=6844",
335
- ]
336
- `);
337
- });
338
-
339
- it('also appends device and version number', () => {
340
- Globals.reportJson = {
341
- configSettings: {formFactor: 'mobile'},
342
- lighthouseVersion: '6.0.0',
343
- };
344
- const href = renderer._getScoringCalculatorHref(category.auditRefs);
345
- const url = new URL(href);
346
- try {
347
- expect(url.hash.split('&')).toMatchInlineSnapshot(`
348
- Array [
349
- "#FCP=6844",
350
- "LCP=9320",
351
- "TBT=1221",
352
- "CLS=0.14",
353
- "SI=8114",
354
- "TTI=8191",
355
- "FMP=6844",
356
- "device=mobile",
357
- "version=6.0.0",
358
- ]
359
- `);
360
- } finally {
361
- Globals.reportJson = null;
362
- }
363
- });
364
-
365
- it('uses null if the metric\'s value is undefined', () => {
366
- const categoryClone = JSON.parse(JSON.stringify(category));
367
- const lcp = categoryClone.auditRefs.find(audit => audit.id === 'largest-contentful-paint');
368
- lcp.result.numericValue = undefined;
369
- lcp.result.score = null;
370
- const href = renderer._getScoringCalculatorHref(categoryClone.auditRefs);
371
- expect(href).toContain('LCP=null');
372
- });
373
-
374
- it('uses null if the metric\'s value is null (LR)', () => {
375
- const categoryClone = JSON.parse(JSON.stringify(category));
376
- const lcp = categoryClone.auditRefs.find(audit => audit.id === 'largest-contentful-paint');
377
- // In LR, we think there might be some case where undefined becomes null, but we can't prove it.
378
- lcp.result.numericValue = null;
379
- lcp.result.score = null;
380
- const href = renderer._getScoringCalculatorHref(categoryClone.auditRefs);
381
- expect(href).toContain('LCP=null');
382
- });
383
- });
384
-
385
- // This is done all in CSS, but tested here.
386
- describe('metric description toggles', () => {
387
- let container;
388
- let toggle;
389
- const metricsSelector = '.lh-audit-group--metrics';
390
- const toggleSelector = '.lh-metrics-toggle__input';
391
- const magicSelector =
392
- '.lh-metrics-toggle__input:checked ~ .lh-metrics-container .lh-metric__description';
393
- let getDescriptionsAfterCheckedToggle;
394
-
395
- describe('works if there is a performance category', () => {
396
- before(() => {
397
- container = renderer.render(category, sampleResults.categoryGroups);
398
- const metricsAuditGroup = container.querySelector(metricsSelector);
399
- toggle = metricsAuditGroup.querySelector(toggleSelector);
400
- // In the CSS, our magicSelector will flip display from `none` to `block`
401
- getDescriptionsAfterCheckedToggle = _ => metricsAuditGroup.querySelectorAll(magicSelector);
402
- });
403
-
404
- it('descriptions hidden by default', () => {
405
- assert.ok(getDescriptionsAfterCheckedToggle().length === 0);
406
- });
407
-
408
- it('can toggle description visibility', () => {
409
- assert.ok(getDescriptionsAfterCheckedToggle().length === 0);
410
- toggle.click();
411
- assert.ok(getDescriptionsAfterCheckedToggle().length > 2);
412
- toggle.click();
413
- assert.ok(getDescriptionsAfterCheckedToggle().length === 0);
414
- });
415
- });
416
- });
417
- });