lighthouse 8.6.0-dev.20211023 → 8.6.0-dev.20211027

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 (77) hide show
  1. package/dist/report/flow.js +10 -10
  2. package/dist/report/standalone.js +2 -2
  3. package/flow-report/assets/styles.css +57 -1
  4. package/flow-report/src/i18n/ui-strings.js +2 -0
  5. package/flow-report/src/summary/category.tsx +73 -4
  6. package/flow-report/src/summary/summary.tsx +1 -0
  7. package/flow-report/src/wrappers/markdown.tsx +27 -0
  8. package/flow-report/test/summary/category-test.tsx +111 -19
  9. package/flow-report/test/wrappers/markdown-test.tsx +29 -0
  10. package/jest.config.js +2 -2
  11. package/lighthouse-core/audits/byte-efficiency/modern-image-formats.js +4 -2
  12. package/lighthouse-core/audits/byte-efficiency/offscreen-images.js +11 -10
  13. package/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js +5 -3
  14. package/lighthouse-core/audits/byte-efficiency/uses-responsive-images-snapshot.js +2 -1
  15. package/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +2 -1
  16. package/lighthouse-core/audits/image-aspect-ratio.js +4 -3
  17. package/lighthouse-core/audits/image-size-responsive.js +3 -2
  18. package/lighthouse-core/audits/preload-lcp-image.js +7 -5
  19. package/lighthouse-core/audits/script-treemap-data.js +1 -1
  20. package/lighthouse-core/audits/unsized-images.js +1 -2
  21. package/package.json +6 -5
  22. package/report/renderer/category-renderer.js +7 -0
  23. package/report/renderer/pwa-category-renderer.js +0 -10
  24. package/report/renderer/report-renderer.js +1 -1
  25. package/report/test/renderer/category-renderer-test.js +41 -0
  26. package/report/test/renderer/pwa-category-renderer-test.js +4 -4
  27. package/report/test/renderer/text-encoding-test.js +1 -1
  28. package/shared/localization/locales/ar-XB.json +8 -8
  29. package/shared/localization/locales/ar.json +8 -8
  30. package/shared/localization/locales/bg.json +8 -8
  31. package/shared/localization/locales/ca.json +8 -8
  32. package/shared/localization/locales/cs.json +8 -8
  33. package/shared/localization/locales/da.json +8 -8
  34. package/shared/localization/locales/de.json +8 -8
  35. package/shared/localization/locales/el.json +8 -8
  36. package/shared/localization/locales/en-GB.json +8 -8
  37. package/shared/localization/locales/en-US.json +27 -24
  38. package/shared/localization/locales/en-XA.json +8 -8
  39. package/shared/localization/locales/en-XL.json +27 -24
  40. package/shared/localization/locales/es-419.json +8 -8
  41. package/shared/localization/locales/es.json +8 -8
  42. package/shared/localization/locales/fi.json +8 -8
  43. package/shared/localization/locales/fil.json +8 -8
  44. package/shared/localization/locales/fr.json +8 -8
  45. package/shared/localization/locales/he.json +8 -8
  46. package/shared/localization/locales/hi.json +8 -8
  47. package/shared/localization/locales/hr.json +8 -8
  48. package/shared/localization/locales/hu.json +8 -8
  49. package/shared/localization/locales/id.json +8 -8
  50. package/shared/localization/locales/it.json +8 -8
  51. package/shared/localization/locales/ja.json +8 -8
  52. package/shared/localization/locales/ko.json +8 -8
  53. package/shared/localization/locales/lt.json +8 -8
  54. package/shared/localization/locales/lv.json +8 -8
  55. package/shared/localization/locales/nl.json +8 -8
  56. package/shared/localization/locales/no.json +8 -8
  57. package/shared/localization/locales/pl.json +8 -8
  58. package/shared/localization/locales/pt-PT.json +8 -8
  59. package/shared/localization/locales/pt.json +8 -8
  60. package/shared/localization/locales/ro.json +8 -8
  61. package/shared/localization/locales/ru.json +8 -8
  62. package/shared/localization/locales/sk.json +8 -8
  63. package/shared/localization/locales/sl.json +8 -8
  64. package/shared/localization/locales/sr-Latn.json +8 -8
  65. package/shared/localization/locales/sr.json +8 -8
  66. package/shared/localization/locales/sv.json +8 -8
  67. package/shared/localization/locales/ta.json +8 -8
  68. package/shared/localization/locales/te.json +8 -8
  69. package/shared/localization/locales/th.json +8 -8
  70. package/shared/localization/locales/tr.json +8 -8
  71. package/shared/localization/locales/uk.json +8 -8
  72. package/shared/localization/locales/vi.json +8 -8
  73. package/shared/localization/locales/zh-HK.json +8 -8
  74. package/shared/localization/locales/zh-TW.json +8 -8
  75. package/shared/localization/locales/zh.json +8 -8
  76. package/tsconfig-all.json +2 -2
  77. package/types/lhr/audit-details.d.ts +5 -5
@@ -37,7 +37,7 @@ const IGNORE_THRESHOLD_IN_BYTES = 2048;
37
37
  const IGNORE_THRESHOLD_IN_PERCENT = 75;
38
38
  const IGNORE_THRESHOLD_IN_MS = 50;
39
39
 
40
- /** @typedef {{url: string, requestStartTime: number, totalBytes: number, wastedBytes: number, wastedPercent: number}} WasteResult */
40
+ /** @typedef {{node: LH.Audit.Details.NodeValue, url: string, requestStartTime: number, totalBytes: number, wastedBytes: number, wastedPercent: number}} WasteResult */
41
41
 
42
42
  class OffscreenImages extends ByteEfficiencyAudit {
43
43
  /**
@@ -100,6 +100,7 @@ class OffscreenImages extends ByteEfficiencyAudit {
100
100
  }
101
101
 
102
102
  return {
103
+ node: ByteEfficiencyAudit.makeNodeItem(image.node),
103
104
  url,
104
105
  requestStartTime: networkRecord.startTime,
105
106
  totalBytes,
@@ -184,26 +185,26 @@ class OffscreenImages extends ByteEfficiencyAudit {
184
185
 
185
186
  /** @type {string[]} */
186
187
  const warnings = [];
187
- const resultsMap = images.reduce((results, image) => {
188
+ /** @type {Map<string, WasteResult>} */
189
+ const resultsMap = new Map();
190
+ for (const image of images) {
188
191
  const processed = OffscreenImages.computeWaste(image, viewportDimensions, networkRecords);
189
192
  if (processed === null) {
190
- return results;
193
+ continue;
191
194
  }
192
195
 
193
196
  if (processed instanceof Error) {
194
197
  warnings.push(processed.message);
195
198
  Sentry.captureException(processed, {tags: {audit: this.meta.id}, level: 'warning'});
196
- return results;
199
+ continue;
197
200
  }
198
201
 
199
202
  // If an image was used more than once, warn only about its least wasteful usage
200
- const existing = results.get(processed.url);
203
+ const existing = resultsMap.get(processed.url);
201
204
  if (!existing || existing.wastedBytes > processed.wastedBytes) {
202
- results.set(processed.url, processed);
205
+ resultsMap.set(processed.url, processed);
203
206
  }
204
-
205
- return results;
206
- }, /** @type {Map<string, WasteResult>} */ (new Map()));
207
+ }
207
208
 
208
209
  const settings = context.settings;
209
210
 
@@ -233,7 +234,7 @@ class OffscreenImages extends ByteEfficiencyAudit {
233
234
 
234
235
  /** @type {LH.Audit.Details.Opportunity['headings']} */
235
236
  const headings = [
236
- {key: 'url', valueType: 'thumbnail', label: ''},
237
+ {key: 'node', valueType: 'node', label: ''},
237
238
  {key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL)},
238
239
  {key: 'totalBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnResourceSize)},
239
240
  {key: 'wastedBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnWastedBytes)},
@@ -76,10 +76,12 @@ class UsesOptimizedImages extends ByteEfficiencyAudit {
76
76
  const imageElementsByURL = new Map();
77
77
  imageElements.forEach(img => imageElementsByURL.set(img.src, img));
78
78
 
79
- /** @type {Array<{url: string, fromProtocol: boolean, isCrossOrigin: boolean, totalBytes: number, wastedBytes: number}>} */
79
+ /** @type {Array<{node?: LH.Audit.Details.NodeValue, url: string, fromProtocol: boolean, isCrossOrigin: boolean, totalBytes: number, wastedBytes: number}>} */
80
80
  const items = [];
81
81
  const warnings = [];
82
82
  for (const image of images) {
83
+ const imageElement = imageElementsByURL.get(image.url);
84
+
83
85
  if (image.failed) {
84
86
  warnings.push(`Unable to decode ${URL.getURLDisplayName(image.url)}`);
85
87
  continue;
@@ -91,7 +93,6 @@ class UsesOptimizedImages extends ByteEfficiencyAudit {
91
93
  let fromProtocol = true;
92
94
 
93
95
  if (typeof jpegSize === 'undefined') {
94
- const imageElement = imageElementsByURL.get(image.url);
95
96
  if (!imageElement) {
96
97
  warnings.push(`Unable to locate resource ${URL.getURLDisplayName(image.url)}`);
97
98
  continue;
@@ -115,6 +116,7 @@ class UsesOptimizedImages extends ByteEfficiencyAudit {
115
116
  const jpegSavings = UsesOptimizedImages.computeSavings({...image, jpegSize});
116
117
 
117
118
  items.push({
119
+ node: imageElement ? ByteEfficiencyAudit.makeNodeItem(imageElement.node) : undefined,
118
120
  url,
119
121
  fromProtocol,
120
122
  isCrossOrigin,
@@ -125,7 +127,7 @@ class UsesOptimizedImages extends ByteEfficiencyAudit {
125
127
 
126
128
  /** @type {LH.Audit.Details.Opportunity['headings']} */
127
129
  const headings = [
128
- {key: 'url', valueType: 'thumbnail', label: ''},
130
+ {key: 'node', valueType: 'node', label: ''},
129
131
  {key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL)},
130
132
  {key: 'totalBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnResourceSize)},
131
133
  {key: 'wastedBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnWastedBytes)},
@@ -70,6 +70,7 @@ class UsesResponsiveImagesSnapshot extends Audit {
70
70
  if (actualPixels - usedPixels > IGNORE_THRESHOLD_IN_PIXELS) score = 0;
71
71
 
72
72
  items.push({
73
+ node: Audit.makeNodeItem(image.node),
73
74
  url: URL.elideDataURI(image.src),
74
75
  displayedDimensions: `${displayed.width}x${displayed.height}`,
75
76
  actualDimensions: `${actual.width}x${actual.height}`,
@@ -79,7 +80,7 @@ class UsesResponsiveImagesSnapshot extends Audit {
79
80
  /** @type {LH.Audit.Details.Table['headings']} */
80
81
  const headings = [
81
82
  /* eslint-disable max-len */
82
- {key: 'url', itemType: 'thumbnail', text: ''},
83
+ {key: 'node', itemType: 'node', text: ''},
83
84
  {key: 'url', itemType: 'url', text: str_(i18n.UIStrings.columnURL)},
84
85
  {key: 'displayedDimensions', itemType: 'text', text: str_(UIStrings.columnDisplayedDimensions)},
85
86
  {key: 'actualDimensions', itemType: 'text', text: str_(UIStrings.columnActualDimensions)},
@@ -104,6 +104,7 @@ class UsesResponsiveImages extends ByteEfficiencyAudit {
104
104
  const wastedBytes = Math.round(totalBytes * wastedRatio);
105
105
 
106
106
  return {
107
+ node: ByteEfficiencyAudit.makeNodeItem(image.node),
107
108
  url,
108
109
  totalBytes,
109
110
  wastedBytes,
@@ -158,7 +159,7 @@ class UsesResponsiveImages extends ByteEfficiencyAudit {
158
159
 
159
160
  /** @type {LH.Audit.Details.Opportunity['headings']} */
160
161
  const headings = [
161
- {key: 'url', valueType: 'thumbnail', label: ''},
162
+ {key: 'node', valueType: 'node', label: ''},
162
163
  {key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL)},
163
164
  {key: 'totalBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnResourceSize)},
164
165
  {key: 'wastedBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnWastedBytes)},
@@ -51,7 +51,7 @@ class ImageAspectRatio extends Audit {
51
51
 
52
52
  /**
53
53
  * @param {WellDefinedImage} image
54
- * @return {{url: string, displayedAspectRatio: string, actualAspectRatio: string, doRatiosMatch: boolean}}
54
+ * @return {{url: string, node: LH.Audit.Details.NodeValue, displayedAspectRatio: string, actualAspectRatio: string, doRatiosMatch: boolean}}
55
55
  */
56
56
  static computeAspectRatios(image) {
57
57
  const url = URL.elideDataURI(image.src);
@@ -63,6 +63,7 @@ class ImageAspectRatio extends Audit {
63
63
 
64
64
  return {
65
65
  url,
66
+ node: Audit.makeNodeItem(image.node),
66
67
  displayedAspectRatio: `${image.displayedWidth} x ${image.displayedHeight}
67
68
  (${displayedAspectRatio.toFixed(2)})`,
68
69
  actualAspectRatio: `${image.naturalDimensions.width} x ${image.naturalDimensions.height}
@@ -78,7 +79,7 @@ class ImageAspectRatio extends Audit {
78
79
  static audit(artifacts) {
79
80
  const images = artifacts.ImageElements;
80
81
 
81
- /** @type {Array<{url: string, displayedAspectRatio: string, actualAspectRatio: string, doRatiosMatch: boolean}>} */
82
+ /** @type {Array<{url: string, node: LH.Audit.Details.NodeValue, displayedAspectRatio: string, actualAspectRatio: string, doRatiosMatch: boolean}>} */
82
83
  const results = [];
83
84
  images.filter(image => {
84
85
  // - filter out css background images since we don't have a reliable way to tell if it's a
@@ -105,7 +106,7 @@ class ImageAspectRatio extends Audit {
105
106
 
106
107
  /** @type {LH.Audit.Details.Table['headings']} */
107
108
  const headings = [
108
- {key: 'url', itemType: 'thumbnail', text: ''},
109
+ {key: 'node', itemType: 'node', text: ''},
109
110
  {key: 'url', itemType: 'url', text: str_(i18n.UIStrings.columnURL)},
110
111
  {key: 'displayedAspectRatio', itemType: 'text', text: str_(UIStrings.columnDisplayed)},
111
112
  {key: 'actualAspectRatio', itemType: 'text', text: str_(UIStrings.columnActual)},
@@ -45,7 +45,7 @@ const LARGE_IMAGE_FACTOR = 0.75;
45
45
  // considered SMALL.
46
46
  const SMALL_IMAGE_THRESHOLD = 64;
47
47
 
48
- /** @typedef {{url: string, elidedUrl: string, displayedSize: string, actualSize: string, actualPixels: number, expectedSize: string, expectedPixels: number}} Result */
48
+ /** @typedef {{url: string, node: LH.Audit.Details.NodeValue, elidedUrl: string, displayedSize: string, actualSize: string, actualPixels: number, expectedSize: string, expectedPixels: number}} Result */
49
49
 
50
50
  /**
51
51
  * @param {{top: number, bottom: number, left: number, right: number}} imageRect
@@ -147,6 +147,7 @@ function getResult(image, DPR) {
147
147
  expectedImageSize(image.displayedWidth, image.displayedHeight, DPR);
148
148
  return {
149
149
  url: image.src,
150
+ node: Audit.makeNodeItem(image.node),
150
151
  elidedUrl: URL.elideDataURI(image.src),
151
152
  displayedSize: `${image.displayedWidth} x ${image.displayedHeight}`,
152
153
  actualSize: `${image.naturalDimensions.width} x ${image.naturalDimensions.height}`,
@@ -263,7 +264,7 @@ class ImageSizeResponsive extends Audit {
263
264
 
264
265
  /** @type {LH.Audit.Details.Table['headings']} */
265
266
  const headings = [
266
- {key: 'url', itemType: 'thumbnail', text: ''},
267
+ {key: 'node', itemType: 'node', text: ''},
267
268
  {key: 'elidedUrl', itemType: 'url', text: str_(i18n.UIStrings.columnURL)},
268
269
  {key: 'displayedSize', itemType: 'text', text: str_(UIStrings.columnDisplayed)},
269
270
  {key: 'actualSize', itemType: 'text', text: str_(UIStrings.columnActual)},
@@ -106,13 +106,14 @@ class PreloadLCPImageAudit extends Audit {
106
106
 
107
107
  /**
108
108
  * Computes the estimated effect of preloading the LCP image.
109
+ * @param {LH.Artifacts.TraceElement|undefined} lcpElement
109
110
  * @param {LH.Gatherer.Simulation.GraphNetworkNode|undefined} lcpNode
110
111
  * @param {LH.Gatherer.Simulation.GraphNode} graph
111
112
  * @param {LH.Gatherer.Simulation.Simulator} simulator
112
- * @return {{wastedMs: number, results: Array<{url: string, wastedMs: number}>}}
113
+ * @return {{wastedMs: number, results: Array<{node: LH.Audit.Details.NodeValue, url: string, wastedMs: number}>}}
113
114
  */
114
- static computeWasteWithGraph(lcpNode, graph, simulator) {
115
- if (!lcpNode) {
115
+ static computeWasteWithGraph(lcpElement, lcpNode, graph, simulator) {
116
+ if (!lcpElement || !lcpNode) {
116
117
  return {
117
118
  wastedMs: 0,
118
119
  results: [],
@@ -185,6 +186,7 @@ class PreloadLCPImageAudit extends Audit {
185
186
  return {
186
187
  wastedMs,
187
188
  results: [{
189
+ node: Audit.makeNodeItem(lcpElement.node),
188
190
  url: lcpNode.record.url,
189
191
  wastedMs,
190
192
  }],
@@ -216,11 +218,11 @@ class PreloadLCPImageAudit extends Audit {
216
218
  const lcpNode = PreloadLCPImageAudit.getLCPNodeToPreload(mainResource, graph, lcpElement, artifacts.ImageElements);
217
219
 
218
220
  const {results, wastedMs} =
219
- PreloadLCPImageAudit.computeWasteWithGraph(lcpNode, graph, simulator);
221
+ PreloadLCPImageAudit.computeWasteWithGraph(lcpElement, lcpNode, graph, simulator);
220
222
 
221
223
  /** @type {LH.Audit.Details.Opportunity['headings']} */
222
224
  const headings = [
223
- {key: 'url', valueType: 'thumbnail', label: ''},
225
+ {key: 'node', valueType: 'node', label: ''},
224
226
  {key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL)},
225
227
  {key: 'wastedMs', valueType: 'timespanMs', label: str_(i18n.UIStrings.columnWastedMs)},
226
228
  ];
@@ -8,7 +8,7 @@
8
8
  /**
9
9
  * @fileoverview
10
10
  * Creates nodes for treemap app.
11
- * Example output: lighthouse-treemap/app/debug.json
11
+ * Example output: treemap/app/debug.json
12
12
  */
13
13
 
14
14
  /**
@@ -147,9 +147,8 @@ class UnsizedImages extends Audit {
147
147
 
148
148
  /** @type {LH.Audit.Details.Table['headings']} */
149
149
  const headings = [
150
- {key: 'url', itemType: 'thumbnail', text: ''},
150
+ {key: 'node', itemType: 'node', text: ''},
151
151
  {key: 'url', itemType: 'url', text: str_(i18n.UIStrings.columnURL)},
152
- {key: 'node', itemType: 'node', text: str_(i18n.UIStrings.columnFailingElem)},
153
152
  ];
154
153
 
155
154
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lighthouse",
3
- "version": "8.6.0-dev.20211023",
3
+ "version": "8.6.0-dev.20211027",
4
4
  "description": "Automated auditing, performance metrics, and best practices for the web.",
5
5
  "main": "./lighthouse-core/index.js",
6
6
  "bin": {
@@ -12,6 +12,7 @@
12
12
  "node": ">=14.15"
13
13
  },
14
14
  "scripts": {
15
+ "prepack": "yarn build-report --standalone --flow",
15
16
  "build-all": "npm-run-posix-or-windows build-all:task",
16
17
  "build-all:task": "yarn build-report && yarn build-cdt-lib && yarn build-devtools && (yarn build-extension & yarn build-lr & yarn build-viewer & yarn build-treemap & yarn build-smokehouse-bundle & wait) && yarn build-pack",
17
18
  "build-all:task:windows": "yarn build-report && yarn build-cdt-lib && yarn build-extension && yarn build-devtools && yarn build-lr && yarn build-viewer && yarn build-treemap && yarn build-smokehouse-bundle",
@@ -38,8 +39,8 @@
38
39
  "test": "yarn diff:sample-json && yarn lint --quiet && yarn unit && yarn type-check",
39
40
  "test-bundle": "yarn smoke --runner bundle -j=1 --retries=2 --invert-match forms",
40
41
  "test-clients": "yarn jest \"$PWD/clients/\" && yarn jest --testMatch=\"**/clients/test/**/*-test-pptr.js\"",
41
- "test-viewer": "yarn unit-viewer && yarn jest --testMatch=\"**/lighthouse-viewer/**/*-test-pptr.js\"",
42
- "test-treemap": "yarn unit-treemap && yarn jest --testMatch=\"**/lighthouse-treemap/**/*-test-pptr.js\"",
42
+ "test-viewer": "yarn unit-viewer && yarn jest --testMatch=\"**/viewer/**/*-test-pptr.js\"",
43
+ "test-treemap": "yarn unit-treemap && yarn jest --testMatch=\"**/treemap/**/*-test-pptr.js\"",
43
44
  "test-lantern": "bash lighthouse-core/scripts/test-lantern.sh",
44
45
  "test-legacy-javascript": "bash lighthouse-core/scripts/test-legacy-javascript.sh",
45
46
  "test-docs": "yarn --cwd docs/recipes/ test",
@@ -47,8 +48,8 @@
47
48
  "unit-core": "yarn jest \"lighthouse-core\"",
48
49
  "unit-cli": "yarn jest \"lighthouse-cli/\"",
49
50
  "unit-report": "yarn jest \"report/\"",
50
- "unit-treemap": "yarn jest \"lighthouse-treemap/.*-test.js\"",
51
- "unit-viewer": "yarn jest \"lighthouse-viewer/.*-test.js\"",
51
+ "unit-treemap": "yarn jest \"treemap/.*-test.js\"",
52
+ "unit-viewer": "yarn jest \"viewer/.*-test.js\"",
52
53
  "unit-flow": "yarn jest \"flow-report/.*-test.[tj]s[x]?\"",
53
54
  "unit": "yarn jest",
54
55
  "unit:ci": "NODE_OPTIONS=--max-old-space-size=8192 npm run jest --ci .",
@@ -532,6 +532,13 @@ export class CategoryRenderer {
532
532
  clumps.set(clumpId, clump);
533
533
  }
534
534
 
535
+ // Sort audits by weight.
536
+ for (const auditRefs of clumps.values()) {
537
+ auditRefs.sort((a, b) => {
538
+ return b.weight - a.weight;
539
+ });
540
+ }
541
+
535
542
  // Render each clump.
536
543
  for (const [clumpId, auditRefs] of clumps) {
537
544
  if (auditRefs.length === 0) continue;
@@ -47,16 +47,6 @@ export class PwaCategoryRenderer extends CategoryRenderer {
47
47
  return categoryElem;
48
48
  }
49
49
 
50
- /**
51
- * Alias for backcompat.
52
- * @param {LH.ReportResult.Category} category
53
- * @param {Record<string, LH.Result.ReportGroup>} groupDefinitions
54
- * @return {DocumentFragment}
55
- */
56
- renderScoreGauge(category, groupDefinitions) {
57
- return this.renderCategoryScore(category, groupDefinitions);
58
- }
59
-
60
50
  /**
61
51
  * @param {LH.ReportResult.Category} category
62
52
  * @param {Record<string, LH.Result.ReportGroup>} groupDefinitions
@@ -212,7 +212,7 @@ export class ReportRenderer {
212
212
  // The renderer for default categories is just the default CategoryRenderer.
213
213
  // If the functions are equal, then renderer is an instance of CategoryRenderer.
214
214
  // For example, the PWA category uses PwaCategoryRenderer, which overrides
215
- // CategoryRenderer.renderScoreGauge, so it would fail this check and be placed
215
+ // CategoryRenderer.renderCategoryScore, so it would fail this check and be placed
216
216
  // in the customGauges bucket.
217
217
  defaultGauges.push(categoryGauge);
218
218
  } else {
@@ -499,4 +499,45 @@ describe('CategoryRenderer', () => {
499
499
  assert.ok(shouldBeWarning[0].textContent.includes(passingWarning));
500
500
  });
501
501
  });
502
+
503
+ it('renders audits by weight', () => {
504
+ const defaultAuditRef = {
505
+ title: '',
506
+ description: '',
507
+ scoreDisplayMode: 'numeric',
508
+ score: 0,
509
+ warnings: [],
510
+ };
511
+ const category = {
512
+ id: 'test',
513
+ title: 'Test',
514
+ score: 0,
515
+ auditRefs: [{
516
+ id: 'audit-1',
517
+ weight: 0,
518
+ result: {
519
+ id: 'audit-1',
520
+ ...defaultAuditRef,
521
+ },
522
+ }, {
523
+ id: 'audit-2',
524
+ weight: 1,
525
+ result: {
526
+ id: 'audit-2',
527
+ ...defaultAuditRef,
528
+ },
529
+ }, {
530
+ id: 'audit-3',
531
+ weight: 0.5,
532
+ result: {
533
+ id: 'audit-3',
534
+ ...defaultAuditRef,
535
+ },
536
+ }],
537
+ };
538
+ const categoryDOM = renderer.render(category);
539
+
540
+ const auditEls = [...categoryDOM.querySelectorAll('.lh-audit')];
541
+ expect(auditEls.map(el => el.id)).toEqual(['audit-2', 'audit-3', 'audit-1']);
542
+ });
502
543
  });
@@ -249,10 +249,10 @@ describe('PwaCategoryRenderer', () => {
249
249
  });
250
250
  });
251
251
 
252
- describe('#renderScoreGauge', () => {
252
+ describe('#renderCategoryScore', () => {
253
253
  it('renders an error score gauge in case of category error', () => {
254
254
  category.score = null;
255
- const badgeGauge = pwaRenderer.renderScoreGauge(category, sampleResults.categoryGroups);
255
+ const badgeGauge = pwaRenderer.renderCategoryScore(category, sampleResults.categoryGroups);
256
256
 
257
257
  // Not a PWA gauge.
258
258
  assert.strictEqual(badgeGauge.querySelector('.lh-gauge--pwa__wrapper'), null);
@@ -263,11 +263,11 @@ describe('PwaCategoryRenderer', () => {
263
263
  });
264
264
 
265
265
  it('renders score gauges with unique ids for items in <defs>', () => {
266
- const gauge1 = pwaRenderer.renderScoreGauge(category, sampleResults.categoryGroups);
266
+ const gauge1 = pwaRenderer.renderCategoryScore(category, sampleResults.categoryGroups);
267
267
  const gauge1Ids = [...gauge1.querySelectorAll('defs [id]')].map(el => el.id);
268
268
  assert.ok(gauge1Ids.length > 2);
269
269
 
270
- const gauge2 = pwaRenderer.renderScoreGauge(category, sampleResults.categoryGroups);
270
+ const gauge2 = pwaRenderer.renderCategoryScore(category, sampleResults.categoryGroups);
271
271
  const gauge2Ids = [...gauge2.querySelectorAll('defs [id]')].map(el => el.id);
272
272
  assert.ok(gauge2Ids.length === gauge1Ids.length);
273
273
 
@@ -41,6 +41,6 @@ describe('TextEncoding', () => {
41
41
  await test('Some examples of emoji are 😃, 🧘🏻‍♂️, 🌍, 🍞, 🚗, 📞, 🎉, ♥️, 🍆, and 🏁.');
42
42
  await test('.'.repeat(125183));
43
43
  await test('😃'.repeat(125183));
44
- await test(fs.readFileSync(LH_ROOT + '/lighthouse-treemap/app/debug.json', 'utf-8'));
44
+ await test(fs.readFileSync(LH_ROOT + '/treemap/app/debug.json', 'utf-8'));
45
45
  });
46
46
  });
@@ -2069,28 +2069,28 @@
2069
2069
  "lighthouse-core/lib/lh-error.js | urlInvalid": {
2070
2070
  "message": "‏‮The‬‏ ‏‮URL‬‏ ‏‮you‬‏ ‏‮have‬‏ ‏‮provided‬‏ ‏‮appears‬‏ ‏‮to‬‏ ‏‮be‬‏ ‏‮invalid‬‏."
2071
2071
  },
2072
- "lighthouse-treemap/app/src/util.js | allLabel": {
2072
+ "treemap/app/src/util.js | allLabel": {
2073
2073
  "message": "‏‮All‬‏"
2074
2074
  },
2075
- "lighthouse-treemap/app/src/util.js | allScriptsDropdownLabel": {
2075
+ "treemap/app/src/util.js | allScriptsDropdownLabel": {
2076
2076
  "message": "‏‮All‬‏ ‏‮Scripts‬‏"
2077
2077
  },
2078
- "lighthouse-treemap/app/src/util.js | coverageColumnName": {
2078
+ "treemap/app/src/util.js | coverageColumnName": {
2079
2079
  "message": "‏‮Coverage‬‏"
2080
2080
  },
2081
- "lighthouse-treemap/app/src/util.js | duplicateModulesLabel": {
2081
+ "treemap/app/src/util.js | duplicateModulesLabel": {
2082
2082
  "message": "‏‮Duplicate‬‏ ‏‮Modules‬‏"
2083
2083
  },
2084
- "lighthouse-treemap/app/src/util.js | resourceBytesLabel": {
2084
+ "treemap/app/src/util.js | resourceBytesLabel": {
2085
2085
  "message": "‏‮Resource‬‏ ‏‮Bytes‬‏"
2086
2086
  },
2087
- "lighthouse-treemap/app/src/util.js | tableColumnName": {
2087
+ "treemap/app/src/util.js | tableColumnName": {
2088
2088
  "message": "‏‮Name‬‏"
2089
2089
  },
2090
- "lighthouse-treemap/app/src/util.js | toggleTableButtonLabel": {
2090
+ "treemap/app/src/util.js | toggleTableButtonLabel": {
2091
2091
  "message": "‏‮Toggle‬‏ ‏‮Table‬‏"
2092
2092
  },
2093
- "lighthouse-treemap/app/src/util.js | unusedBytesLabel": {
2093
+ "treemap/app/src/util.js | unusedBytesLabel": {
2094
2094
  "message": "‏‮Unused‬‏ ‏‮Bytes‬‏"
2095
2095
  },
2096
2096
  "node_modules/lighthouse-stack-packs/packs/amp.js | efficient-animated-content": {
@@ -2069,28 +2069,28 @@
2069
2069
  "lighthouse-core/lib/lh-error.js | urlInvalid": {
2070
2070
  "message": "يبدو أن عنوان URL الذي قدمته غير صحيح."
2071
2071
  },
2072
- "lighthouse-treemap/app/src/util.js | allLabel": {
2072
+ "treemap/app/src/util.js | allLabel": {
2073
2073
  "message": "الكل"
2074
2074
  },
2075
- "lighthouse-treemap/app/src/util.js | allScriptsDropdownLabel": {
2075
+ "treemap/app/src/util.js | allScriptsDropdownLabel": {
2076
2076
  "message": "جميع النصوص البرمجية"
2077
2077
  },
2078
- "lighthouse-treemap/app/src/util.js | coverageColumnName": {
2078
+ "treemap/app/src/util.js | coverageColumnName": {
2079
2079
  "message": "التغطية"
2080
2080
  },
2081
- "lighthouse-treemap/app/src/util.js | duplicateModulesLabel": {
2081
+ "treemap/app/src/util.js | duplicateModulesLabel": {
2082
2082
  "message": "الوحدات المكرَّرة"
2083
2083
  },
2084
- "lighthouse-treemap/app/src/util.js | resourceBytesLabel": {
2084
+ "treemap/app/src/util.js | resourceBytesLabel": {
2085
2085
  "message": "حجم الموارد بوحدة البايت"
2086
2086
  },
2087
- "lighthouse-treemap/app/src/util.js | tableColumnName": {
2087
+ "treemap/app/src/util.js | tableColumnName": {
2088
2088
  "message": "الاسم"
2089
2089
  },
2090
- "lighthouse-treemap/app/src/util.js | toggleTableButtonLabel": {
2090
+ "treemap/app/src/util.js | toggleTableButtonLabel": {
2091
2091
  "message": "تبديل الجدول"
2092
2092
  },
2093
- "lighthouse-treemap/app/src/util.js | unusedBytesLabel": {
2093
+ "treemap/app/src/util.js | unusedBytesLabel": {
2094
2094
  "message": "وحدات بايت غير المستخدمة"
2095
2095
  },
2096
2096
  "node_modules/lighthouse-stack-packs/packs/amp.js | efficient-animated-content": {
@@ -2069,28 +2069,28 @@
2069
2069
  "lighthouse-core/lib/lh-error.js | urlInvalid": {
2070
2070
  "message": "Предоставеният от вас URL адрес изглежда невалиден."
2071
2071
  },
2072
- "lighthouse-treemap/app/src/util.js | allLabel": {
2072
+ "treemap/app/src/util.js | allLabel": {
2073
2073
  "message": "Всички"
2074
2074
  },
2075
- "lighthouse-treemap/app/src/util.js | allScriptsDropdownLabel": {
2075
+ "treemap/app/src/util.js | allScriptsDropdownLabel": {
2076
2076
  "message": "Всички скриптове"
2077
2077
  },
2078
- "lighthouse-treemap/app/src/util.js | coverageColumnName": {
2078
+ "treemap/app/src/util.js | coverageColumnName": {
2079
2079
  "message": "Обхват"
2080
2080
  },
2081
- "lighthouse-treemap/app/src/util.js | duplicateModulesLabel": {
2081
+ "treemap/app/src/util.js | duplicateModulesLabel": {
2082
2082
  "message": "Дублиращи се модули"
2083
2083
  },
2084
- "lighthouse-treemap/app/src/util.js | resourceBytesLabel": {
2084
+ "treemap/app/src/util.js | resourceBytesLabel": {
2085
2085
  "message": "Байтове на ресурсите"
2086
2086
  },
2087
- "lighthouse-treemap/app/src/util.js | tableColumnName": {
2087
+ "treemap/app/src/util.js | tableColumnName": {
2088
2088
  "message": "Име"
2089
2089
  },
2090
- "lighthouse-treemap/app/src/util.js | toggleTableButtonLabel": {
2090
+ "treemap/app/src/util.js | toggleTableButtonLabel": {
2091
2091
  "message": "Превключване на таблицата"
2092
2092
  },
2093
- "lighthouse-treemap/app/src/util.js | unusedBytesLabel": {
2093
+ "treemap/app/src/util.js | unusedBytesLabel": {
2094
2094
  "message": "Неизползвани байтове"
2095
2095
  },
2096
2096
  "node_modules/lighthouse-stack-packs/packs/amp.js | efficient-animated-content": {
@@ -2069,28 +2069,28 @@
2069
2069
  "lighthouse-core/lib/lh-error.js | urlInvalid": {
2070
2070
  "message": "Sembla que l'URL que has proporcionat no és vàlid."
2071
2071
  },
2072
- "lighthouse-treemap/app/src/util.js | allLabel": {
2072
+ "treemap/app/src/util.js | allLabel": {
2073
2073
  "message": "Tot"
2074
2074
  },
2075
- "lighthouse-treemap/app/src/util.js | allScriptsDropdownLabel": {
2075
+ "treemap/app/src/util.js | allScriptsDropdownLabel": {
2076
2076
  "message": "Tots els scripts"
2077
2077
  },
2078
- "lighthouse-treemap/app/src/util.js | coverageColumnName": {
2078
+ "treemap/app/src/util.js | coverageColumnName": {
2079
2079
  "message": "Cobertura"
2080
2080
  },
2081
- "lighthouse-treemap/app/src/util.js | duplicateModulesLabel": {
2081
+ "treemap/app/src/util.js | duplicateModulesLabel": {
2082
2082
  "message": "Mòduls duplicats"
2083
2083
  },
2084
- "lighthouse-treemap/app/src/util.js | resourceBytesLabel": {
2084
+ "treemap/app/src/util.js | resourceBytesLabel": {
2085
2085
  "message": "Bytes del recurs"
2086
2086
  },
2087
- "lighthouse-treemap/app/src/util.js | tableColumnName": {
2087
+ "treemap/app/src/util.js | tableColumnName": {
2088
2088
  "message": "Nom"
2089
2089
  },
2090
- "lighthouse-treemap/app/src/util.js | toggleTableButtonLabel": {
2090
+ "treemap/app/src/util.js | toggleTableButtonLabel": {
2091
2091
  "message": "Commuta la taula"
2092
2092
  },
2093
- "lighthouse-treemap/app/src/util.js | unusedBytesLabel": {
2093
+ "treemap/app/src/util.js | unusedBytesLabel": {
2094
2094
  "message": "Bytes no utilitzats"
2095
2095
  },
2096
2096
  "node_modules/lighthouse-stack-packs/packs/amp.js | efficient-animated-content": {
@@ -2069,28 +2069,28 @@
2069
2069
  "lighthouse-core/lib/lh-error.js | urlInvalid": {
2070
2070
  "message": "Adresa URL, kterou jste poskytli, se zdá být neplatná."
2071
2071
  },
2072
- "lighthouse-treemap/app/src/util.js | allLabel": {
2072
+ "treemap/app/src/util.js | allLabel": {
2073
2073
  "message": "Vše"
2074
2074
  },
2075
- "lighthouse-treemap/app/src/util.js | allScriptsDropdownLabel": {
2075
+ "treemap/app/src/util.js | allScriptsDropdownLabel": {
2076
2076
  "message": "Všechna písma"
2077
2077
  },
2078
- "lighthouse-treemap/app/src/util.js | coverageColumnName": {
2078
+ "treemap/app/src/util.js | coverageColumnName": {
2079
2079
  "message": "Pokrytí"
2080
2080
  },
2081
- "lighthouse-treemap/app/src/util.js | duplicateModulesLabel": {
2081
+ "treemap/app/src/util.js | duplicateModulesLabel": {
2082
2082
  "message": "Duplicitní moduly"
2083
2083
  },
2084
- "lighthouse-treemap/app/src/util.js | resourceBytesLabel": {
2084
+ "treemap/app/src/util.js | resourceBytesLabel": {
2085
2085
  "message": "Počet bajtů zdroje"
2086
2086
  },
2087
- "lighthouse-treemap/app/src/util.js | tableColumnName": {
2087
+ "treemap/app/src/util.js | tableColumnName": {
2088
2088
  "message": "Název"
2089
2089
  },
2090
- "lighthouse-treemap/app/src/util.js | toggleTableButtonLabel": {
2090
+ "treemap/app/src/util.js | toggleTableButtonLabel": {
2091
2091
  "message": "Zobrazit nebo skrýt tabulku"
2092
2092
  },
2093
- "lighthouse-treemap/app/src/util.js | unusedBytesLabel": {
2093
+ "treemap/app/src/util.js | unusedBytesLabel": {
2094
2094
  "message": "Nevyužité bajty"
2095
2095
  },
2096
2096
  "node_modules/lighthouse-stack-packs/packs/amp.js | efficient-animated-content": {