lighthouse 8.5.1-dev.20211009 → 8.5.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 (164) hide show
  1. package/dist/report/flow.js +149 -0
  2. package/dist/report/standalone.js +228 -0
  3. package/flow-report/assets/styles.css +9 -272
  4. package/flow-report/jest.config.js +1 -1
  5. package/flow-report/src/app.tsx +9 -31
  6. package/flow-report/src/common.tsx +7 -86
  7. package/flow-report/src/icons.tsx +3 -20
  8. package/flow-report/src/sidebar/sidebar.tsx +16 -11
  9. package/flow-report/src/summary/category.tsx +24 -42
  10. package/flow-report/src/summary/summary.tsx +29 -32
  11. package/flow-report/src/topbar.tsx +4 -54
  12. package/flow-report/src/util.ts +1 -26
  13. package/flow-report/src/wrappers/report-renderer.tsx +1 -1
  14. package/flow-report/src/wrappers/report.tsx +20 -7
  15. package/flow-report/test/app-test.tsx +13 -17
  16. package/flow-report/test/setup/env-setup.ts +0 -1
  17. package/flow-report/test/sidebar/flow-test.tsx +12 -6
  18. package/flow-report/test/sidebar/sidebar-test.tsx +13 -7
  19. package/flow-report/test/summary/category-test.tsx +34 -79
  20. package/flow-report/test/summary/summary-test.tsx +17 -11
  21. package/flow-report/test/util-test.tsx +12 -1
  22. package/flow-report/tsconfig.json +0 -1
  23. package/flow-report/types/flow-report.d.ts +1 -2
  24. package/jest.config.js +15 -1
  25. package/lighthouse-cli/cli-flags.js +1 -3
  26. package/lighthouse-cli/run.js +2 -2
  27. package/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +0 -0
  28. package/lighthouse-cli/test/smokehouse/report-assert.js +4 -20
  29. package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +1 -2
  30. package/lighthouse-core/audits/byte-efficiency/unused-javascript.js +1 -1
  31. package/lighthouse-core/computed/js-bundles.js +2 -1
  32. package/lighthouse-core/computed/unused-javascript-summary.js +3 -3
  33. package/lighthouse-core/config/config.js +2 -2
  34. package/lighthouse-core/config/default-config.js +0 -5
  35. package/lighthouse-core/fraggle-rock/api.js +0 -10
  36. package/lighthouse-core/fraggle-rock/config/filters.js +3 -22
  37. package/lighthouse-core/fraggle-rock/gather/driver.js +0 -4
  38. package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +2 -2
  39. package/lighthouse-core/fraggle-rock/user-flow.js +6 -35
  40. package/lighthouse-core/gather/driver/navigation.js +0 -5
  41. package/lighthouse-core/gather/driver/prepare.js +0 -14
  42. package/lighthouse-core/gather/driver/storage.js +0 -5
  43. package/lighthouse-core/gather/gather-runner.js +2 -2
  44. package/lighthouse-core/gather/gatherers/dobetterweb/response-compression.js +1 -5
  45. package/lighthouse-core/gather/gatherers/full-page-screenshot.js +24 -30
  46. package/{shared/localization/i18n-module.js → lighthouse-core/lib/cdt/Common.js} +8 -3
  47. package/lighthouse-core/lib/cdt/SDK.js +123 -3
  48. package/lighthouse-core/lib/cdt/generated/SourceMap.js +312 -148
  49. package/lighthouse-core/lib/csp-evaluator.js +1 -2
  50. package/lighthouse-core/lib/i18n/README.md +6 -6
  51. package/lighthouse-core/lib/i18n/i18n.js +342 -9
  52. package/{shared/localization → lighthouse-core/lib/i18n}/locales/ar-XB.json +0 -0
  53. package/{shared/localization → lighthouse-core/lib/i18n}/locales/ar.json +0 -0
  54. package/{shared/localization → lighthouse-core/lib/i18n}/locales/bg.json +0 -0
  55. package/{shared/localization → lighthouse-core/lib/i18n}/locales/ca.json +0 -0
  56. package/{shared/localization → lighthouse-core/lib/i18n}/locales/cs.json +0 -0
  57. package/{shared/localization → lighthouse-core/lib/i18n}/locales/da.json +0 -0
  58. package/{shared/localization → lighthouse-core/lib/i18n}/locales/de.json +0 -0
  59. package/{shared/localization → lighthouse-core/lib/i18n}/locales/el.json +0 -0
  60. package/{shared/localization → lighthouse-core/lib/i18n}/locales/en-GB.json +0 -0
  61. package/{shared/localization → lighthouse-core/lib/i18n}/locales/en-US.json +0 -111
  62. package/{shared/localization → lighthouse-core/lib/i18n}/locales/en-XA.json +0 -0
  63. package/{shared/localization → lighthouse-core/lib/i18n}/locales/en-XL.json +0 -111
  64. package/{shared/localization → lighthouse-core/lib/i18n}/locales/es-419.json +0 -0
  65. package/{shared/localization → lighthouse-core/lib/i18n}/locales/es.json +0 -0
  66. package/{shared/localization → lighthouse-core/lib/i18n}/locales/fi.json +0 -0
  67. package/{shared/localization → lighthouse-core/lib/i18n}/locales/fil.json +0 -0
  68. package/{shared/localization → lighthouse-core/lib/i18n}/locales/fr.json +0 -0
  69. package/{shared/localization → lighthouse-core/lib/i18n}/locales/he.json +0 -0
  70. package/{shared/localization → lighthouse-core/lib/i18n}/locales/hi.json +0 -0
  71. package/{shared/localization → lighthouse-core/lib/i18n}/locales/hr.json +0 -0
  72. package/{shared/localization → lighthouse-core/lib/i18n}/locales/hu.json +0 -0
  73. package/{shared/localization → lighthouse-core/lib/i18n}/locales/id.json +0 -0
  74. package/{shared/localization → lighthouse-core/lib/i18n}/locales/it.json +0 -0
  75. package/{shared/localization → lighthouse-core/lib/i18n}/locales/ja.json +0 -0
  76. package/{shared/localization → lighthouse-core/lib/i18n}/locales/ko.json +0 -0
  77. package/{shared/localization → lighthouse-core/lib/i18n}/locales/lt.json +0 -0
  78. package/{shared/localization → lighthouse-core/lib/i18n}/locales/lv.json +0 -0
  79. package/{shared/localization → lighthouse-core/lib/i18n}/locales/nl.json +0 -0
  80. package/{shared/localization → lighthouse-core/lib/i18n}/locales/no.json +0 -0
  81. package/{shared/localization → lighthouse-core/lib/i18n}/locales/pl.json +0 -0
  82. package/{shared/localization → lighthouse-core/lib/i18n}/locales/pt-PT.json +0 -0
  83. package/{shared/localization → lighthouse-core/lib/i18n}/locales/pt.json +0 -0
  84. package/{shared/localization → lighthouse-core/lib/i18n}/locales/ro.json +0 -0
  85. package/{shared/localization → lighthouse-core/lib/i18n}/locales/ru.json +0 -0
  86. package/{shared/localization → lighthouse-core/lib/i18n}/locales/sk.json +0 -0
  87. package/{shared/localization → lighthouse-core/lib/i18n}/locales/sl.json +0 -0
  88. package/{shared/localization → lighthouse-core/lib/i18n}/locales/sr-Latn.json +0 -0
  89. package/{shared/localization → lighthouse-core/lib/i18n}/locales/sr.json +0 -0
  90. package/{shared/localization → lighthouse-core/lib/i18n}/locales/sv.json +0 -0
  91. package/{shared/localization → lighthouse-core/lib/i18n}/locales/ta.json +0 -0
  92. package/{shared/localization → lighthouse-core/lib/i18n}/locales/te.json +0 -0
  93. package/{shared/localization → lighthouse-core/lib/i18n}/locales/th.json +0 -0
  94. package/{shared/localization → lighthouse-core/lib/i18n}/locales/tr.json +0 -0
  95. package/{shared/localization → lighthouse-core/lib/i18n}/locales/uk.json +0 -0
  96. package/{shared/localization → lighthouse-core/lib/i18n}/locales/vi.json +0 -0
  97. package/{shared/localization → lighthouse-core/lib/i18n}/locales/zh-HK.json +0 -0
  98. package/{shared/localization → lighthouse-core/lib/i18n}/locales/zh-TW.json +0 -0
  99. package/{shared/localization → lighthouse-core/lib/i18n}/locales/zh.json +0 -0
  100. package/{shared/localization → lighthouse-core/lib/i18n}/locales.js +1 -2
  101. package/{shared/localization → lighthouse-core/lib/i18n}/swap-locale.js +7 -9
  102. package/lighthouse-core/lib/page-functions.js +4 -4
  103. package/lighthouse-core/lib/stack-packs.js +13 -1
  104. package/{shared → lighthouse-core/lib}/type-verifiers.js +0 -0
  105. package/lighthouse-core/runner.js +6 -6
  106. package/lighthouse-core/scripts/manual-chrome-launcher.js +1 -4
  107. package/lighthouse-core/util-commonjs.js +4 -20
  108. package/package.json +15 -18
  109. package/readme.md +1 -1
  110. package/report/assets/standalone-template.html +1 -0
  111. package/report/assets/styles.css +1 -8
  112. package/report/assets/templates.html +2 -40
  113. package/report/clients/psi.js +0 -1
  114. package/report/generator/file-namer.js +8 -17
  115. package/report/generator/report-generator.js +1 -0
  116. package/report/renderer/category-renderer.js +4 -3
  117. package/report/renderer/components.js +69 -106
  118. package/report/renderer/dom.js +0 -19
  119. package/report/renderer/performance-category-renderer.js +20 -22
  120. package/report/renderer/report-renderer.js +0 -7
  121. package/report/renderer/report-ui-features.js +19 -7
  122. package/report/renderer/util.js +4 -20
  123. package/report/test/clients/psi-test.js +3 -2
  124. package/report/test/generator/file-namer-test.js +2 -2
  125. package/report/test/renderer/category-renderer-test.js +1 -1
  126. package/report/test/renderer/performance-category-renderer-test.js +0 -12
  127. package/report/test/renderer/report-renderer-test.js +55 -0
  128. package/report/test/renderer/util-test.js +8 -68
  129. package/report/test-assets/faux-psi-template.html +1 -0
  130. package/report/tsconfig.json +1 -2
  131. package/report/types/html-renderer.d.ts +1 -2
  132. package/root.js +0 -18
  133. package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +3 -5
  134. package/third-party/chromium-synchronization/installability-errors-test.js +1 -2
  135. package/tsconfig-all.json +0 -1
  136. package/tsconfig-base.json +1 -1
  137. package/tsconfig.json +3 -2
  138. package/types/config.d.ts +0 -1
  139. package/types/lhr/flow.d.ts +0 -7
  140. package/types/lhr/i18n.d.ts +3 -0
  141. package/changelog.md +0 -5395
  142. package/flow-report/.eslintrc.cjs +0 -49
  143. package/flow-report/package.json +0 -4
  144. package/flow-report/src/header.tsx +0 -88
  145. package/flow-report/src/help-dialog.tsx +0 -120
  146. package/flow-report/src/i18n/i18n.tsx +0 -44
  147. package/flow-report/src/i18n/localized-strings.js +0 -11
  148. package/flow-report/src/i18n/ui-strings.js +0 -86
  149. package/flow-report/test/common-test.tsx +0 -89
  150. package/flow-report/test/header-test.tsx +0 -55
  151. package/flow-report/test/sample-flow.ts +0 -17
  152. package/flow-report/test/topbar-test.tsx +0 -68
  153. package/lighthouse-core/lib/cdt/Platform.js +0 -55
  154. package/lighthouse-core/scripts/package.json +0 -4
  155. package/report/renderer/swap-locale-feature.js +0 -82
  156. package/report/test/renderer/report-renderer-axe-test.js +0 -86
  157. package/shared/localization/format.js +0 -422
  158. package/shared/localization/swap-flow-locale.js +0 -20
  159. package/shared/test/localization/format-test.js +0 -377
  160. package/shared/test/localization/locales-test.js +0 -47
  161. package/shared/test/localization/swap-locale-test.js +0 -140
  162. package/shared/tsconfig.json +0 -22
  163. package/shared/types/shared.d.ts +0 -24
  164. package/types/es-main.d.ts +0 -18
@@ -172,35 +172,33 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
172
172
  }
173
173
 
174
174
  // Metrics.
175
- const metricAudits = category.auditRefs.filter(audit => audit.group === 'metrics');
176
- if (metricAudits.length) {
177
- const metricAuditsEl = this.renderAuditGroup(groups.metrics);
175
+ const metricAuditsEl = this.renderAuditGroup(groups.metrics);
178
176
 
179
- // Metric descriptions toggle.
180
- const toggleTmpl = this.dom.createComponent('metricsToggle');
181
- const _toggleEl = this.dom.find('.lh-metrics-toggle', toggleTmpl);
182
- metricAuditsEl.append(..._toggleEl.childNodes);
177
+ // Metric descriptions toggle.
178
+ const toggleTmpl = this.dom.createComponent('metricsToggle');
179
+ const _toggleEl = this.dom.find('.lh-metrics-toggle', toggleTmpl);
180
+ metricAuditsEl.append(..._toggleEl.childNodes);
183
181
 
184
- const metricsBoxesEl = this.dom.createChildOf(metricAuditsEl, 'div', 'lh-metrics-container');
182
+ const metricAudits = category.auditRefs.filter(audit => audit.group === 'metrics');
183
+ const metricsBoxesEl = this.dom.createChildOf(metricAuditsEl, 'div', 'lh-metrics-container');
185
184
 
186
- metricAudits.forEach(item => {
187
- metricsBoxesEl.appendChild(this._renderMetric(item));
188
- });
185
+ metricAudits.forEach(item => {
186
+ metricsBoxesEl.appendChild(this._renderMetric(item));
187
+ });
189
188
 
190
- const estValuesEl = this.dom.createChildOf(metricAuditsEl, 'div', 'lh-metrics__disclaimer');
191
- const disclaimerEl = this.dom.convertMarkdownLinkSnippets(strings.varianceDisclaimer);
192
- estValuesEl.appendChild(disclaimerEl);
189
+ const estValuesEl = this.dom.createChildOf(metricAuditsEl, 'div', 'lh-metrics__disclaimer');
190
+ const disclaimerEl = this.dom.convertMarkdownLinkSnippets(strings.varianceDisclaimer);
191
+ estValuesEl.appendChild(disclaimerEl);
193
192
 
194
- // Add link to score calculator.
195
- const calculatorLink = this.dom.createChildOf(estValuesEl, 'a', 'lh-calclink');
196
- calculatorLink.target = '_blank';
197
- calculatorLink.textContent = strings.calculatorLink;
198
- this.dom.safelySetHref(calculatorLink, this._getScoringCalculatorHref(category.auditRefs));
193
+ // Add link to score calculator.
194
+ const calculatorLink = this.dom.createChildOf(estValuesEl, 'a', 'lh-calclink');
195
+ calculatorLink.target = '_blank';
196
+ calculatorLink.textContent = strings.calculatorLink;
197
+ this.dom.safelySetHref(calculatorLink, this._getScoringCalculatorHref(category.auditRefs));
199
198
 
200
199
 
201
- metricAuditsEl.classList.add('lh-audit-group--metrics');
202
- element.appendChild(metricAuditsEl);
203
- }
200
+ metricAuditsEl.classList.add('lh-audit-group--metrics');
201
+ element.appendChild(metricAuditsEl);
204
202
 
205
203
  // Filmstrip
206
204
  const timelineEl = this.dom.createChildOf(element, 'div', 'lh-filmstrip-container');
@@ -166,12 +166,6 @@ export class ReportRenderer {
166
166
  {gatherMode: report.gatherMode}
167
167
  );
168
168
 
169
- // For normal score gauges (not the fraction gauge), set the gauge href
170
- // to link to the category.
171
- const gaugeWrapperEl = /** @type {HTMLAnchorElement} */ (
172
- categoryGauge.querySelector('a.lh-gauge__wrapper'));
173
- if (gaugeWrapperEl) this._dom.safelySetHref(gaugeWrapperEl, `#${category.id}`);
174
-
175
169
  if (Util.isPluginCategory(category.id)) {
176
170
  pluginGauges.push(categoryGauge);
177
171
  } else if (renderer.renderCategoryScore === categoryRenderer.renderCategoryScore) {
@@ -262,7 +256,6 @@ export class ReportRenderer {
262
256
  }
263
257
 
264
258
  const reportFragment = this._dom.createFragment();
265
- reportFragment.append(this._dom.createComponent('styles'));
266
259
  const topbarDocumentFragment = this._renderReportTopbar(report);
267
260
 
268
261
  reportFragment.appendChild(topbarDocumentFragment);
@@ -28,7 +28,7 @@ import {toggleDarkTheme} from './features-util.js';
28
28
  import {openTreemap} from './open-tab.js';
29
29
  import {TopbarFeatures} from './topbar-features.js';
30
30
  import {Util} from './util.js';
31
- import {getLhrFilenamePrefix} from '../generator/file-namer.js';
31
+ import {getFilenamePrefix} from '../generator/file-namer.js';
32
32
 
33
33
  /**
34
34
  * @param {HTMLTableElement} tableEl
@@ -324,13 +324,25 @@ export class ReportUIFeatures {
324
324
  }
325
325
 
326
326
  /**
327
- * DevTools uses its own file manager to download files, so it redefines this function.
328
- * Wrapper is necessary so DevTools can still override this function.
329
- *
330
- * @param {Blob|File} blob
327
+ * Downloads a file (blob) using a[download].
328
+ * @param {Blob|File} blob The file to save.
331
329
  */
332
330
  _saveFile(blob) {
333
- const filename = getLhrFilenamePrefix(this.json);
334
- this._dom.saveFile(blob, filename);
331
+ const filename = getFilenamePrefix({
332
+ finalUrl: this.json.finalUrl,
333
+ fetchTime: this.json.fetchTime,
334
+ });
335
+
336
+ const ext = blob.type.match('json') ? '.json' : '.html';
337
+
338
+ const a = this._dom.createElement('a');
339
+ a.download = `${filename}${ext}`;
340
+ this._dom.safelySetBlobHref(a, blob);
341
+ this._document.body.appendChild(a); // Firefox requires anchor to be in the DOM.
342
+ a.click();
343
+
344
+ // cleanup.
345
+ this._document.body.removeChild(a);
346
+ setTimeout(() => URL.revokeObjectURL(a.href), 500);
335
347
  }
336
348
  }
@@ -518,31 +518,15 @@ export class Util {
518
518
  * @param {LH.ReportResult.Category} category
519
519
  */
520
520
  static calculateCategoryFraction(category) {
521
- let numPassableAudits = 0;
521
+ const numAudits = category.auditRefs.length;
522
+
522
523
  let numPassed = 0;
523
- let numInformative = 0;
524
524
  let totalWeight = 0;
525
525
  for (const auditRef of category.auditRefs) {
526
- const auditPassed = Util.showAsPassed(auditRef.result);
527
- const notDisplayed = !auditRef.group && category.id === 'performance';
528
-
529
- // Don't count the audit if it's manual, N/A, or isn't displayed.
530
- if (notDisplayed ||
531
- auditRef.result.scoreDisplayMode === 'manual' ||
532
- auditRef.result.scoreDisplayMode === 'notApplicable') {
533
- continue;
534
- } else if (auditRef.result.scoreDisplayMode === 'informative') {
535
- if (!auditPassed) {
536
- ++numInformative;
537
- }
538
- continue;
539
- }
540
-
541
- ++numPassableAudits;
542
526
  totalWeight += auditRef.weight;
543
- if (auditPassed) numPassed++;
527
+ if (Util.showAsPassed(auditRef.result)) numPassed++;
544
528
  }
545
- return {numPassed, numPassableAudits, numInformative, totalWeight};
529
+ return {numPassed, numAudits, totalWeight};
546
530
  }
547
531
  }
548
532
 
@@ -67,6 +67,8 @@ describe('PSI', () => {
67
67
  // Check that the report exists and has some content.
68
68
  assert.ok(result.perfCategoryEl instanceof document.defaultView.Element);
69
69
  assert.ok(result.perfCategoryEl.outerHTML.length > 50000, 'perfCategory HTML is populated');
70
+ assert.ok(!result.perfCategoryEl.outerHTML.includes('lh-permalink'),
71
+ 'PSI\'s perfCategory HTML doesn\'t include a lh-permalink element');
70
72
  // Assume using default locale.
71
73
  const title = result.perfCategoryEl.querySelector('.lh-audit-group--metrics')
72
74
  .querySelector('.lh-audit-group__title').textContent;
@@ -81,8 +83,7 @@ describe('PSI', () => {
81
83
 
82
84
  assert.ok(result.perfCategoryEl instanceof document.defaultView.Element);
83
85
  assert.ok(result.perfCategoryEl.outerHTML.length > 50000, 'perfCategory HTML is populated');
84
- // styles for .lh-permalink are ok, but not the HTML
85
- assert.ok(!result.perfCategoryEl.outerHTML.includes('class="lh-permalink'),
86
+ assert.ok(!result.perfCategoryEl.outerHTML.includes('lh-permalink'),
86
87
  'PSI\'s perfCategory HTML doesn\'t include a lh-permalink element');
87
88
 
88
89
  assert.equal(typeof result.finalScreenshotDataUri, 'string');
@@ -7,7 +7,7 @@
7
7
 
8
8
  const assert = require('assert').strict;
9
9
 
10
- const getLhrFilenamePrefix = require('../../generator/file-namer.js').getLhrFilenamePrefix;
10
+ const getFilenamePrefix = require('../../generator/file-namer.js').getFilenamePrefix;
11
11
 
12
12
  /* eslint-env jest */
13
13
  describe('file-namer helper', () => {
@@ -16,7 +16,7 @@ describe('file-namer helper', () => {
16
16
  finalUrl: 'https://testexample.com',
17
17
  fetchTime: '2017-01-06T02:34:56.217Z',
18
18
  };
19
- const str = getLhrFilenamePrefix(results);
19
+ const str = getFilenamePrefix(results);
20
20
  // we want the filename to match user timezone, however these tests will run on multiple TZs
21
21
  assert.ok(str.startsWith('testexample.com'), 'hostname is missing');
22
22
  assert.ok(str.includes('2017-'), 'full year is missing');
@@ -297,7 +297,7 @@ describe('CategoryRenderer', () => {
297
297
  );
298
298
 
299
299
  const gauge = categoryDOM.querySelector('.lh-fraction__content');
300
- assert.equal(gauge.textContent.trim(), '13/18', 'fraction is included');
300
+ assert.equal(gauge.textContent.trim(), '49/54', 'fraction is included');
301
301
 
302
302
  const score = categoryDOM.querySelector('.lh-category-header');
303
303
  const title = score.querySelector('.lh-fraction__label');
@@ -69,18 +69,6 @@ describe('PerfCategoryRenderer', () => {
69
69
  assert.equal(timelineElements.length + nontimelineElements.length, metricAudits.length);
70
70
  });
71
71
 
72
- it('does not render metrics section if no metric group audits', () => {
73
- // Remove metrics from category
74
- const newCategory = JSON.parse(JSON.stringify(category));
75
- newCategory.auditRefs = category.auditRefs.filter(audit => audit.group !== 'metrics');
76
-
77
- const categoryDOM = renderer.render(newCategory, sampleResults.categoryGroups);
78
- const sections = categoryDOM.querySelectorAll('.lh-category > .lh-audit-group');
79
- const metricSection = categoryDOM.querySelector('.lh-audit-group--metrics');
80
- assert.ok(!metricSection);
81
- assert.equal(sections.length, 4);
82
- });
83
-
84
72
  it('renders the metrics variance disclaimer as markdown', () => {
85
73
  const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
86
74
  const disclaimerEl =
@@ -233,4 +233,59 @@ describe('ReportRenderer', () => {
233
233
  .querySelectorAll('.lh-audit--notapplicable').length;
234
234
  assert.strictEqual(notApplicableCount, notApplicableElementCount);
235
235
  });
236
+
237
+ describe('axe-core', () => {
238
+ let axe;
239
+
240
+ beforeAll(async () =>{
241
+ // Needed by axe-core
242
+ // https://github.com/dequelabs/axe-core/blob/581c441c/doc/examples/jsdom/test/a11y.js#L24
243
+ global.window = global.self;
244
+ global.Node = global.self.Node;
245
+ global.Element = global.self.Element;
246
+
247
+ // axe-core must be imported after the global polyfills
248
+ axe = (await import('axe-core')).default;
249
+ });
250
+
251
+ afterAll(() => {
252
+ global.window = undefined;
253
+ global.Node = undefined;
254
+ global.Element = undefined;
255
+ });
256
+
257
+ it('renders without axe violations', () => {
258
+ const container = renderer._dom._document.createElement('main');
259
+ const output = renderer.renderReport(sampleResults, container);
260
+ renderer._dom._document.body.appendChild(container);
261
+
262
+ const config = {
263
+ rules: {
264
+ // Reports may have duplicate ids
265
+ // https://github.com/GoogleChrome/lighthouse/issues/9432
266
+ 'duplicate-id': {enabled: false},
267
+ 'duplicate-id-aria': {enabled: false},
268
+ 'landmark-no-duplicate-contentinfo': {enabled: false},
269
+ // The following rules are disable for axe-core + jsdom compatibility
270
+ // https://github.com/dequelabs/axe-core/tree/b573b1c1/doc/examples/jest_react#to-run-the-example
271
+ 'color-contrast': {enabled: false},
272
+ 'link-in-text-block': {enabled: false},
273
+ // Report has empty links prior to i18n-ing.
274
+ 'link-name': {enabled: false},
275
+ // May not be a real issue. https://github.com/dequelabs/axe-core/issues/2958
276
+ 'nested-interactive': {enabled: false},
277
+ },
278
+ };
279
+
280
+ return new Promise(resolve => {
281
+ axe.run(output, config, (error, {violations}) => {
282
+ expect(error).toBeNull();
283
+ expect(violations).toEqual([]);
284
+ resolve();
285
+ });
286
+ });
287
+ // This test takes 40s on fast hardware, and 50-60s on GHA.
288
+ // https://github.com/dequelabs/axe-core/tree/b573b1c1/doc/examples/jest_react#timeout-issues
289
+ }, /* timeout= */ 100 * 1000);
290
+ });
236
291
  });
@@ -399,77 +399,17 @@ describe('util helpers', () => {
399
399
  describe('#calculateCategoryFraction', () => {
400
400
  it('returns passed audits and total audits', () => {
401
401
  const category = {
402
- id: 'performance',
403
402
  auditRefs: [
404
- {weight: 3, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'diagnostics'},
405
- {weight: 2, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'diagnostics'},
406
- {weight: 0, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'diagnostics'},
407
- {weight: 1, result: {score: 0, scoreDisplayMode: 'binary'}, group: 'diagnostics'},
403
+ {weight: 3, result: {score: 1, scoreDisplayMode: 'binary'}},
404
+ {weight: 2, result: {score: 1, scoreDisplayMode: 'binary'}},
405
+ {weight: 0, result: {score: 1, scoreDisplayMode: 'binary'}},
406
+ {weight: 1, result: {score: 0, scoreDisplayMode: 'binary'}},
408
407
  ],
409
408
  };
410
- const fraction = Util.calculateCategoryFraction(category);
411
- expect(fraction).toEqual({
412
- numPassableAudits: 4,
413
- numPassed: 3,
414
- numInformative: 0,
415
- totalWeight: 6,
416
- });
417
- });
418
-
419
- it('ignores manual audits, N/A audits, and performance audits with no group', () => {
420
- const category = {
421
- id: 'performance',
422
- auditRefs: [
423
- {weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'diagnostics'},
424
- {weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}},
425
- {weight: 1, result: {score: 0, scoreDisplayMode: 'manual'}, group: 'diagnostics'},
426
- {weight: 1, result: {score: 0, scoreDisplayMode: 'notApplicable'}, group: 'diagnostics'},
427
- ],
428
- };
429
- const fraction = Util.calculateCategoryFraction(category);
430
- expect(fraction).toEqual({
431
- numPassableAudits: 1,
432
- numPassed: 1,
433
- numInformative: 0,
434
- totalWeight: 1,
435
- });
436
- });
437
-
438
- it('does not ignore audits with no group in non-performance category', () => {
439
- const category = {
440
- id: 'seo',
441
- auditRefs: [
442
- {weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'diagnostics'},
443
- {weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}},
444
- {weight: 1, result: {score: 0, scoreDisplayMode: 'manual'}, group: 'diagnostics'},
445
- ],
446
- };
447
- const fraction = Util.calculateCategoryFraction(category);
448
- expect(fraction).toEqual({
449
- numPassableAudits: 2,
450
- numPassed: 2,
451
- numInformative: 0,
452
- totalWeight: 2,
453
- });
454
- });
455
-
456
- it('tracks informative audits separately', () => {
457
- const category = {
458
- id: 'performance',
459
- auditRefs: [
460
- {weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'diagnostics'},
461
- {weight: 1, result: {score: 1, scoreDisplayMode: 'binary'}, group: 'diagnostics'},
462
- {weight: 0, result: {score: 1, scoreDisplayMode: 'informative'}, group: 'diagnostics'},
463
- {weight: 1, result: {score: 0, scoreDisplayMode: 'informative'}, group: 'diagnostics'},
464
- ],
465
- };
466
- const fraction = Util.calculateCategoryFraction(category);
467
- expect(fraction).toEqual({
468
- numPassableAudits: 2,
469
- numPassed: 2,
470
- numInformative: 2,
471
- totalWeight: 2,
472
- });
409
+ const {numPassed, numAudits, totalWeight} = Util.calculateCategoryFraction(category);
410
+ expect(numPassed).toEqual(3);
411
+ expect(numAudits).toEqual(4);
412
+ expect(totalWeight).toEqual(6);
473
413
  });
474
414
  });
475
415
  });
@@ -16,6 +16,7 @@
16
16
  <meta charset="utf-8">
17
17
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
18
18
  <title>Faux PageSpeed Report</title>
19
+ <style>/*%%LIGHTHOUSE_CSS%%*/</style>
19
20
 
20
21
  <style>
21
22
  /* Inspired by https://codepen.io/markcaron/pen/MvGRYV?editors=1100 but improved. s*/
@@ -10,8 +10,7 @@
10
10
  },
11
11
  "references": [
12
12
  {"path": "../types/lhr/"},
13
- {"path": "./generator/"},
14
- {"path": "../shared/"}
13
+ {"path": "./generator/"}
15
14
  ],
16
15
  "include": [
17
16
  "**/*.js",
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import AuditDetails from '../../types/lhr/audit-details';
8
- import {FormattedIcu as FormattedIcu_, IcuMessage as IcuMessage_} from '../../types/lhr/i18n';
8
+ import {FormattedIcu as FormattedIcu_} from '../../types/lhr/i18n';
9
9
  import LHResult from '../../types/lhr/lhr';
10
10
  import ReportResult_ from './report-result';
11
11
  import * as Settings from '../../types/lhr/settings';
@@ -17,7 +17,6 @@ declare global {
17
17
  export import Result = LHResult;
18
18
  export import ReportResult = ReportResult_;
19
19
  export import Locale = Settings.Locale;
20
- export type IcuMessage = IcuMessage_;
21
20
  export type FormattedIcu<T> = FormattedIcu_<T>;
22
21
 
23
22
  module Audit {
package/root.js CHANGED
@@ -5,24 +5,6 @@
5
5
  */
6
6
  'use strict';
7
7
 
8
- const fs = require('fs');
9
- const path = require('path');
10
- const url = require('url');
11
-
12
- // import {dirname} from 'path';
13
- // import {fileURLToPath} from 'url';
14
-
15
8
  module.exports = {
16
9
  LH_ROOT: __dirname,
17
- /**
18
- * Return parsed json object.
19
- * Resolves path relative to importMeta.url (if provided) or LH_ROOT (if not provided).
20
- * @param {string} filePath Can be an absolute or relative path.
21
- * @param {ImportMeta=} importMeta
22
- */
23
- readJson(filePath, importMeta) {
24
- const dir = importMeta ? path.dirname(url.fileURLToPath(importMeta.url)) : __dirname;
25
- filePath = path.resolve(dir, filePath);
26
- return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
27
- },
28
10
  };
@@ -7,7 +7,7 @@
7
7
 
8
8
  const fs = require('fs');
9
9
  const fetch = require('node-fetch');
10
- const {LH_ROOT} = require('../../root.js');
10
+ const {LH_ROOT} = require('../../../root.js');
11
11
 
12
12
  const inspectorIssuesGathererPath = LH_ROOT +
13
13
  '/lighthouse-core/gather/gatherers/inspector-issues.js';
@@ -31,8 +31,7 @@ describe('issueAdded types', () => {
31
31
  .sort();
32
32
  });
33
33
 
34
- // TODO: https://github.com/GoogleChrome/lighthouse/issues/13147
35
- it.skip('should notify us if something changed', () => {
34
+ it('should notify us if something changed', () => {
36
35
  expect(inspectorIssueDetailsTypes).toMatchInlineSnapshot(`
37
36
  Array [
38
37
  "blockedByResponseIssueDetails",
@@ -45,8 +44,7 @@ describe('issueAdded types', () => {
45
44
  `);
46
45
  });
47
46
 
48
- // TODO: https://github.com/GoogleChrome/lighthouse/issues/13147
49
- it.skip('are each handled explicitly in the gatherer', () => {
47
+ it('are each handled explicitly in the gatherer', () => {
50
48
  // Regex relies on the typecasts
51
49
  const sourceTypeMatches = inspectorIssuesGathererSource.matchAll(
52
50
  /LH\.Crdp\.Audits\.(.*?Details)>/g
@@ -74,8 +74,7 @@ Array [
74
74
  `);
75
75
  });
76
76
 
77
- // TODO: https://github.com/GoogleChrome/lighthouse/issues/13147
78
- it.skip('are each handled explicitly in the gatherer', () => {
77
+ it('are each handled explicitly in the gatherer', () => {
79
78
  const errorStrings = Object.keys(InstallableManifestAudit.UIStrings)
80
79
  .filter(key => chromiumErrorIds.includes(key))
81
80
  .sort();
package/tsconfig-all.json CHANGED
@@ -9,7 +9,6 @@
9
9
  {"path": "./lighthouse-viewer/"},
10
10
  {"path": "./lighthouse-treemap/"},
11
11
  {"path": "./flow-report/"},
12
- {"path": "./shared/"},
13
12
  ],
14
13
  "files": [],
15
14
  "include": [],
@@ -19,6 +19,6 @@
19
19
 
20
20
  // "listFiles": true,
21
21
  // "noErrorTruncation": true,
22
- // "extendedDiagnostics": true,
22
+ "extendedDiagnostics": true,
23
23
  },
24
24
  }
package/tsconfig.json CHANGED
@@ -10,7 +10,6 @@
10
10
  {"path": "./types/lhr/"},
11
11
  {"path": "./report/"},
12
12
  {"path": "./report/generator/"},
13
- {"path": "./shared/"},
14
13
  ],
15
14
  "include": [
16
15
  "root.js",
@@ -23,13 +22,13 @@
23
22
 
24
23
  // TODO(esmodules): JSON files included via resolveJsonModule. Removable on the switch to ES Modules.
25
24
  "package.json",
25
+ "lighthouse-core/lib/i18n/locales/en-US.json",
26
26
  "lighthouse-core/test/results/sample_v2.json",
27
27
  "lighthouse-core/lib/sd-validation/assets/*.json",
28
28
  "lighthouse-core/test/fixtures/unresolved-perflog.json",
29
29
  "lighthouse-core/test/fixtures/traces/lcp-m78.devtools.log.json",
30
30
  "third-party/snyk/snapshot.json",
31
31
  "lighthouse-core/audits/byte-efficiency/polyfill-graph-data.json",
32
- "shared/localization/locales/en-US.json",
33
32
  ],
34
33
  "exclude": [
35
34
  "lighthouse-core/test/audits/**/*.js",
@@ -80,6 +79,8 @@
80
79
  "lighthouse-core/test/lib/dependency-graph/simulator/simulator-test.js",
81
80
  "lighthouse-core/test/lib/emulation-test.js",
82
81
  "lighthouse-core/test/lib/i18n/i18n-test.js",
82
+ "lighthouse-core/test/lib/i18n/locales-test.js",
83
+ "lighthouse-core/test/lib/i18n/swap-locale-test.js",
83
84
  "lighthouse-core/test/lib/icons-test.js",
84
85
  "lighthouse-core/test/lib/lh-element-test.js",
85
86
  "lighthouse-core/test/lib/manifest-parser-test.js",
package/types/config.d.ts CHANGED
@@ -134,7 +134,6 @@ declare module Config {
134
134
  auditRefs: AuditRefJson[];
135
135
  description?: string | IcuMessage;
136
136
  manualDescription?: string | IcuMessage;
137
- supportedModes?: Gatherer.GatherMode[];
138
137
  }
139
138
 
140
139
  interface GroupJson {
@@ -11,11 +11,6 @@ declare module FlowResult {
11
11
  lhr: Result;
12
12
  name: string;
13
13
  }
14
-
15
- interface LhrRef {
16
- value: Result;
17
- index: number;
18
- }
19
14
  }
20
15
 
21
16
  /**
@@ -24,8 +19,6 @@ declare module FlowResult {
24
19
  interface FlowResult {
25
20
  /** Ordered list of flow steps, each corresponding to a navigation, timespan, or snapshot. */
26
21
  steps: FlowResult.Step[];
27
- /** Name given to this user flow. */
28
- name: string;
29
22
  }
30
23
 
31
24
  export default FlowResult;
@@ -4,6 +4,9 @@
4
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
5
  */
6
6
 
7
+ // TODO(bckenny): i18n types should not be necessary for the LHR, but too difficult
8
+ // to unravel from audit-details right now.
9
+
7
10
  export type IcuMessage = {
8
11
  // NOTE: `i18nId` rather than just `id` to make tsc typing easier (vs type branding which won't survive JSON roundtrip).
9
12
  /** The id locating this message in the locale message json files. */