lighthouse 12.3.0 → 12.4.0

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 (142) hide show
  1. package/cli/test/smokehouse/core-tests.js +4 -0
  2. package/core/audits/audit.d.ts +5 -0
  3. package/core/audits/audit.js +12 -0
  4. package/core/audits/bootup-time.js +0 -2
  5. package/core/audits/byte-efficiency/duplicated-javascript.d.ts +4 -5
  6. package/core/audits/byte-efficiency/duplicated-javascript.js +9 -5
  7. package/core/audits/byte-efficiency/legacy-javascript.d.ts +2 -2
  8. package/core/audits/byte-efficiency/legacy-javascript.js +17 -5
  9. package/core/audits/byte-efficiency/polyfill-graph-data.json +48 -49
  10. package/core/audits/byte-efficiency/total-byte-weight.js +0 -2
  11. package/core/audits/clickjacking-mitigation.d.ts +42 -0
  12. package/core/audits/clickjacking-mitigation.js +139 -0
  13. package/core/audits/dobetterweb/dom-size.js +0 -2
  14. package/core/audits/insights/README.md +3 -0
  15. package/core/audits/insights/cls-culprits-insight.d.ts +25 -0
  16. package/core/audits/insights/cls-culprits-insight.js +137 -0
  17. package/core/audits/insights/document-latency-insight.d.ts +11 -0
  18. package/core/audits/insights/document-latency-insight.js +48 -0
  19. package/core/audits/insights/dom-size-insight.d.ts +11 -0
  20. package/core/audits/insights/dom-size-insight.js +85 -0
  21. package/core/audits/insights/font-display-insight.d.ts +11 -0
  22. package/core/audits/insights/font-display-insight.js +53 -0
  23. package/core/audits/insights/forced-reflow-insight.d.ts +11 -0
  24. package/core/audits/insights/forced-reflow-insight.js +52 -0
  25. package/core/audits/insights/image-delivery-insight.d.ts +11 -0
  26. package/core/audits/insights/image-delivery-insight.js +83 -0
  27. package/core/audits/insights/insight-audit.d.ts +23 -0
  28. package/core/audits/insights/insight-audit.js +133 -0
  29. package/core/audits/insights/interaction-to-next-paint-insight.d.ts +11 -0
  30. package/core/audits/insights/interaction-to-next-paint-insight.js +71 -0
  31. package/core/audits/insights/lcp-discovery-insight.d.ts +11 -0
  32. package/core/audits/insights/lcp-discovery-insight.js +48 -0
  33. package/core/audits/insights/lcp-phases-insight.d.ts +16 -0
  34. package/core/audits/insights/lcp-phases-insight.js +87 -0
  35. package/core/audits/insights/long-critical-network-tree-insight.d.ts +11 -0
  36. package/core/audits/insights/long-critical-network-tree-insight.js +53 -0
  37. package/core/audits/insights/render-blocking-insight.d.ts +11 -0
  38. package/core/audits/insights/render-blocking-insight.js +57 -0
  39. package/core/audits/insights/slow-css-selector-insight.d.ts +11 -0
  40. package/core/audits/insights/slow-css-selector-insight.js +52 -0
  41. package/core/audits/insights/third-parties-insight.d.ts +28 -0
  42. package/core/audits/insights/third-parties-insight.js +90 -0
  43. package/core/audits/insights/viewport-insight.d.ts +11 -0
  44. package/core/audits/insights/viewport-insight.js +54 -0
  45. package/core/audits/layout-shifts.d.ts +0 -1
  46. package/core/audits/layout-shifts.js +18 -21
  47. package/core/audits/mainthread-work-breakdown.js +0 -2
  48. package/core/audits/seo/is-crawlable.d.ts +1 -0
  49. package/core/audits/server-response-time.js +0 -1
  50. package/core/computed/metrics/lantern-metric.js +5 -1
  51. package/core/computed/trace-engine-result.js +71 -17
  52. package/core/config/default-config.js +37 -1
  53. package/core/gather/gatherers/inspector-issues.js +3 -0
  54. package/core/gather/gatherers/trace-elements.d.ts +10 -2
  55. package/core/gather/gatherers/trace-elements.js +89 -12
  56. package/core/lib/bf-cache-strings.d.ts +7 -4
  57. package/core/lib/bf-cache-strings.js +174 -140
  58. package/core/lib/cdt/generated/ParsedURL.d.ts +1 -0
  59. package/core/lib/cdt/generated/ParsedURL.js +16 -4
  60. package/core/lib/cdt/generated/SourceMap.d.ts +32 -5
  61. package/core/lib/cdt/generated/SourceMap.js +192 -100
  62. package/core/lib/deprecations-strings.d.ts +78 -98
  63. package/core/lib/deprecations-strings.js +23 -41
  64. package/core/lib/i18n/i18n.d.ts +1 -0
  65. package/core/lib/i18n/i18n.js +2 -0
  66. package/core/lib/trace-engine.d.ts +1 -0
  67. package/core/lib/trace-engine.js +2 -0
  68. package/core/runner.js +2 -0
  69. package/dist/report/bundle.esm.js +196 -9
  70. package/dist/report/flow.js +197 -10
  71. package/dist/report/standalone.js +197 -10
  72. package/flow-report/src/i18n/i18n.d.ts +2 -0
  73. package/package.json +15 -13
  74. package/readme.md +3 -0
  75. package/report/assets/styles.css +179 -5
  76. package/report/assets/templates.html +14 -0
  77. package/report/renderer/components.js +9 -3
  78. package/report/renderer/details-renderer.d.ts +5 -0
  79. package/report/renderer/details-renderer.js +24 -0
  80. package/report/renderer/dom.d.ts +12 -1
  81. package/report/renderer/dom.js +26 -1
  82. package/report/renderer/i18n-formatter.d.ts +1 -1
  83. package/report/renderer/performance-category-renderer.d.ts +10 -0
  84. package/report/renderer/performance-category-renderer.js +81 -20
  85. package/report/renderer/report-utils.d.ts +1 -0
  86. package/report/renderer/report-utils.js +2 -0
  87. package/report/renderer/topbar-features.js +7 -0
  88. package/shared/localization/locales/ar-XB.json +74 -26
  89. package/shared/localization/locales/ar.json +76 -28
  90. package/shared/localization/locales/bg.json +74 -26
  91. package/shared/localization/locales/ca.json +74 -26
  92. package/shared/localization/locales/cs.json +74 -26
  93. package/shared/localization/locales/da.json +74 -26
  94. package/shared/localization/locales/de.json +75 -27
  95. package/shared/localization/locales/el.json +74 -26
  96. package/shared/localization/locales/en-GB.json +74 -26
  97. package/shared/localization/locales/en-US.json +288 -30
  98. package/shared/localization/locales/en-XA.json +48 -24
  99. package/shared/localization/locales/en-XL.json +288 -30
  100. package/shared/localization/locales/es-419.json +74 -26
  101. package/shared/localization/locales/es.json +74 -26
  102. package/shared/localization/locales/fi.json +74 -26
  103. package/shared/localization/locales/fil.json +75 -27
  104. package/shared/localization/locales/fr.json +74 -26
  105. package/shared/localization/locales/he.json +82 -34
  106. package/shared/localization/locales/hi.json +74 -26
  107. package/shared/localization/locales/hr.json +75 -27
  108. package/shared/localization/locales/hu.json +74 -26
  109. package/shared/localization/locales/id.json +74 -26
  110. package/shared/localization/locales/it.json +85 -37
  111. package/shared/localization/locales/ja.json +75 -27
  112. package/shared/localization/locales/ko.json +75 -27
  113. package/shared/localization/locales/lt.json +75 -27
  114. package/shared/localization/locales/lv.json +74 -26
  115. package/shared/localization/locales/nl.json +74 -26
  116. package/shared/localization/locales/no.json +75 -27
  117. package/shared/localization/locales/pl.json +74 -26
  118. package/shared/localization/locales/pt-PT.json +74 -26
  119. package/shared/localization/locales/pt.json +74 -26
  120. package/shared/localization/locales/ro.json +74 -26
  121. package/shared/localization/locales/ru.json +74 -26
  122. package/shared/localization/locales/sk.json +74 -26
  123. package/shared/localization/locales/sl.json +74 -26
  124. package/shared/localization/locales/sr-Latn.json +74 -26
  125. package/shared/localization/locales/sr.json +74 -26
  126. package/shared/localization/locales/sv.json +74 -26
  127. package/shared/localization/locales/ta.json +74 -26
  128. package/shared/localization/locales/te.json +74 -26
  129. package/shared/localization/locales/th.json +76 -28
  130. package/shared/localization/locales/tr.json +74 -26
  131. package/shared/localization/locales/uk.json +74 -26
  132. package/shared/localization/locales/vi.json +74 -26
  133. package/shared/localization/locales/zh-HK.json +75 -27
  134. package/shared/localization/locales/zh-TW.json +74 -26
  135. package/shared/localization/locales/zh.json +74 -26
  136. package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +3 -0
  137. package/types/artifacts.d.ts +5 -3
  138. package/types/audit.d.ts +2 -0
  139. package/types/lhr/audit-details.d.ts +13 -1
  140. package/types/lhr/audit-result.d.ts +2 -0
  141. package/core/gather/gatherers/root-causes.d.ts +0 -19
  142. package/core/gather/gatherers/root-causes.js +0 -144
@@ -7,6 +7,8 @@
7
7
  import a11y from './test-definitions/a11y.js';
8
8
  import byteEfficiency from './test-definitions/byte-efficiency.js';
9
9
  import byteGzip from './test-definitions/byte-gzip.js';
10
+ import clickjackingMissingHeaders from './test-definitions/clickjacking-missing-headers.js';
11
+ import clickjackingMitigationPresent from './test-definitions/clickjacking-mitigation-headers-present.js';
10
12
  import crash from './test-definitions/crash.js';
11
13
  import cspAllowAll from './test-definitions/csp-allow-all.js';
12
14
  import cspBlockAll from './test-definitions/csp-block-all.js';
@@ -69,6 +71,8 @@ const smokeTests = [
69
71
  a11y,
70
72
  byteEfficiency,
71
73
  byteGzip,
74
+ clickjackingMissingHeaders,
75
+ clickjackingMitigationPresent,
72
76
  crash,
73
77
  cspAllowAll,
74
78
  cspBlockAll,
@@ -66,6 +66,11 @@ export class Audit {
66
66
  * @param {LH.Audit.Details.Opportunity['items']|LH.Audit.Details.Table['items']} items
67
67
  */
68
68
  static assertHeadingKeysExist(headings: LH.Audit.Details.Table["headings"] | LH.Audit.Details.Opportunity["headings"], items: LH.Audit.Details.Opportunity["items"] | LH.Audit.Details.Table["items"]): void;
69
+ /**
70
+ * @param {LH.Audit.Details.Checklist['items']} items
71
+ * @return {LH.Audit.Details.Checklist}
72
+ */
73
+ static makeChecklistDetails(items: LH.Audit.Details.Checklist["items"]): LH.Audit.Details.Checklist;
69
74
  /**
70
75
  * @param {LH.Audit.Details.Table['headings']} headings
71
76
  * @param {LH.Audit.Details.Table['items']} results
@@ -140,6 +140,17 @@ class Audit {
140
140
  }
141
141
  }
142
142
 
143
+ /**
144
+ * @param {LH.Audit.Details.Checklist['items']} items
145
+ * @return {LH.Audit.Details.Checklist}
146
+ */
147
+ static makeChecklistDetails(items) {
148
+ return {
149
+ type: 'checklist',
150
+ items,
151
+ };
152
+ }
153
+
143
154
  /**
144
155
  * @param {LH.Audit.Details.Table['headings']} headings
145
156
  * @param {LH.Audit.Details.Table['items']} results
@@ -467,6 +478,7 @@ class Audit {
467
478
 
468
479
  details: product.details,
469
480
  guidanceLevel: audit.meta.guidanceLevel,
481
+ replacesAudits: audit.meta.replacesAudits,
470
482
  };
471
483
  }
472
484
 
@@ -14,7 +14,6 @@ import {MainThreadTasks} from '../computed/main-thread-tasks.js';
14
14
  import {getExecutionTimingsByURL} from '../lib/tracehouse/task-summary.js';
15
15
  import {TBTImpactTasks} from '../computed/tbt-impact-tasks.js';
16
16
  import {Sentry} from '../lib/sentry.js';
17
- import {Util} from '../../shared/util.js';
18
17
 
19
18
  const UIStrings = {
20
19
  /** Title of a diagnostic audit that provides detail on the time spent executing javascript files during the load. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
@@ -173,7 +172,6 @@ class BootupTime extends Audit {
173
172
 
174
173
  return {
175
174
  score,
176
- scoreDisplayMode: score >= Util.PASS_THRESHOLD ? Audit.SCORING_MODES.INFORMATIVE : undefined,
177
175
  notApplicable: !results.length,
178
176
  numericValue: totalBootupTime,
179
177
  numericUnit: 'millisecond',
@@ -26,11 +26,10 @@ declare class DuplicatedJavascript extends ByteEfficiencyAudit {
26
26
  resourceSize: number;
27
27
  }[]>>;
28
28
  /**
29
- * This audit highlights JavaScript modules that appear to be duplicated across all resources,
30
- * either within the same bundle or between different bundles. Each details item returned is
31
- * a module with subItems for each resource that includes it. The wastedBytes for the details
32
- * item is the number of bytes occupied by the sum of all but the largest copy of the module.
33
- * wastedBytesByUrl attributes the cost of the bytes to a specific resource, for use by lantern.
29
+ * Each details item returned is a module with subItems for each resource that
30
+ * includes it. The wastedBytes for the details item is the number of bytes
31
+ * occupied by the sum of all but the largest copy of the module. wastedBytesByUrl
32
+ * attributes the cost of the bytes to a specific resource, for use by lantern.
34
33
  * @param {LH.Artifacts} artifacts
35
34
  * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
36
35
  * @param {LH.Audit.Context} context
@@ -4,6 +4,11 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
+ /**
8
+ * @fileoverview This audit highlights JavaScript modules that appear to be duplicated across
9
+ * all resources, either within the same bundle or between different bundles.
10
+ */
11
+
7
12
  /** @typedef {import('./byte-efficiency-audit.js').ByteEfficiencyProduct} ByteEfficiencyProduct */
8
13
  /** @typedef {LH.Audit.ByteEfficiencyItem & {source: string, subItems: {type: 'subitems', items: SubItem[]}}} Item */
9
14
  /** @typedef {{url: string, sourceTransferBytes?: number}} SubItem */
@@ -104,11 +109,10 @@ class DuplicatedJavascript extends ByteEfficiencyAudit {
104
109
  }
105
110
 
106
111
  /**
107
- * This audit highlights JavaScript modules that appear to be duplicated across all resources,
108
- * either within the same bundle or between different bundles. Each details item returned is
109
- * a module with subItems for each resource that includes it. The wastedBytes for the details
110
- * item is the number of bytes occupied by the sum of all but the largest copy of the module.
111
- * wastedBytesByUrl attributes the cost of the bytes to a specific resource, for use by lantern.
112
+ * Each details item returned is a module with subItems for each resource that
113
+ * includes it. The wastedBytes for the details item is the number of bytes
114
+ * occupied by the sum of all but the largest copy of the module. wastedBytesByUrl
115
+ * attributes the cost of the bytes to a specific resource, for use by lantern.
112
116
  * @param {LH.Artifacts} artifacts
113
117
  * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
114
118
  * @param {LH.Audit.Context} context
@@ -50,11 +50,10 @@ declare class LegacyJavascript extends ByteEfficiencyAudit {
50
50
  *
51
51
  * @param {CodePatternMatcher} matcher
52
52
  * @param {LH.Artifacts['Scripts']} scripts
53
- * @param {LH.Artifacts.NetworkRequest[]} networkRecords
54
53
  * @param {LH.Artifacts.Bundle[]} bundles
55
54
  * @return {Map<LH.Artifacts.Script, PatternMatchResult[]>}
56
55
  */
57
- static detectAcrossScripts(matcher: CodePatternMatcher, scripts: LH.Artifacts["Scripts"], networkRecords: LH.Artifacts.NetworkRequest[], bundles: LH.Artifacts.Bundle[]): Map<LH.Artifacts.Script, PatternMatchResult[]>;
56
+ static detectAcrossScripts(matcher: CodePatternMatcher, scripts: LH.Artifacts["Scripts"], bundles: LH.Artifacts.Bundle[]): Map<LH.Artifacts.Script, PatternMatchResult[]>;
58
57
  /**
59
58
  * @param {PatternMatchResult[]} matches
60
59
  * @return {number}
@@ -71,6 +70,7 @@ declare class LegacyJavascript extends ByteEfficiencyAudit {
71
70
  export namespace UIStrings {
72
71
  let title: string;
73
72
  let description: string;
73
+ let detectedCoreJs2Warning: string;
74
74
  }
75
75
  import { ByteEfficiencyAudit } from './byte-efficiency-audit.js';
76
76
  /**
@@ -39,7 +39,10 @@ const UIStrings = {
39
39
  // eslint-disable-next-line max-len
40
40
  // TODO: developer.chrome.com article. this codelab is good starting place: https://web.dev/articles/codelab-serve-modern-code
41
41
  /** Description of a Lighthouse audit that tells the user about old JavaScript that is no longer needed. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
42
- description: 'Polyfills and transforms enable legacy browsers to use new JavaScript features. However, many aren\'t necessary for modern browsers. For your bundled JavaScript, adopt a modern script deployment strategy using module/nomodule feature detection to reduce the amount of code shipped to modern browsers, while retaining support for legacy browsers. [Learn how to use modern JavaScript](https://web.dev/articles/publish-modern-javascript)',
42
+ description: 'Polyfills and transforms enable legacy browsers to use new JavaScript features. However, many aren\'t necessary for modern browsers. For your bundled JavaScript, adopt a modern script deployment strategy using [module/nomodule feature detection](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) to reduce the amount of code shipped to modern browsers, while retaining support for legacy browsers. [Learn how to serve modern JavaScript](https://web.dev/articles/codelab-serve-modern-code)',
43
+ /** Warning text that an outdated version of the library "core-js" was found, and the developer should upgrade. */
44
+ // eslint-disable-next-line max-len
45
+ detectedCoreJs2Warning: 'Version 2 of core-js was detected on the page. You should upgrade to version 3 for many performance improvements.',
43
46
  };
44
47
 
45
48
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -231,7 +234,6 @@ class LegacyJavascript extends ByteEfficiencyAudit {
231
234
  ['Reflect.preventExtensions', 'es6.reflect.prevent-extensions'],
232
235
  ['Reflect.setPrototypeOf', 'es6.reflect.set-prototype-of'],
233
236
  ['String.prototype.codePointAt', 'es6.string.code-point-at'],
234
- ['String.fromCodePoint', 'es6.string.from-code-point'],
235
237
  ['String.raw', 'es6.string.raw'],
236
238
  ['String.prototype.repeat', 'es6.string.repeat'],
237
239
  ['Object.entries', 'es7.object.entries'],
@@ -321,11 +323,10 @@ class LegacyJavascript extends ByteEfficiencyAudit {
321
323
  *
322
324
  * @param {CodePatternMatcher} matcher
323
325
  * @param {LH.Artifacts['Scripts']} scripts
324
- * @param {LH.Artifacts.NetworkRequest[]} networkRecords
325
326
  * @param {LH.Artifacts.Bundle[]} bundles
326
327
  * @return {Map<LH.Artifacts.Script, PatternMatchResult[]>}
327
328
  */
328
- static detectAcrossScripts(matcher, scripts, networkRecords, bundles) {
329
+ static detectAcrossScripts(matcher, scripts, bundles) {
329
330
  /** @type {Map<LH.Artifacts.Script, PatternMatchResult[]>} */
330
331
  const scriptToMatchResults = new Map();
331
332
  const polyfillData = this.getPolyfillData();
@@ -426,7 +427,7 @@ class LegacyJavascript extends ByteEfficiencyAudit {
426
427
  const compressionRatioByUrl = new Map();
427
428
 
428
429
  const scriptToMatchResults =
429
- this.detectAcrossScripts(matcher, artifacts.Scripts, networkRecords, bundles);
430
+ this.detectAcrossScripts(matcher, artifacts.Scripts, bundles);
430
431
  for (const [script, matches] of scriptToMatchResults.entries()) {
431
432
  const compressionRatio = estimateCompressionRatioForContent(
432
433
  compressionRatioByUrl, script.url, artifacts, networkRecords);
@@ -456,6 +457,16 @@ class LegacyJavascript extends ByteEfficiencyAudit {
456
457
  items.push(item);
457
458
  }
458
459
 
460
+ const warnings = [];
461
+ for (const bundle of bundles) {
462
+ if (classifiedEntities.isFirstParty(bundle.script.url)) {
463
+ if (bundle.rawMap.sources.some(s => s.match(/node_modules\/core-js\/modules\/es[67]/))) {
464
+ warnings.push(str_(UIStrings.detectedCoreJs2Warning));
465
+ break;
466
+ }
467
+ }
468
+ }
469
+
459
470
  /** @type {Map<string, number>} */
460
471
  const wastedBytesByUrl = new Map();
461
472
  for (const item of items) {
@@ -478,6 +489,7 @@ class LegacyJavascript extends ByteEfficiencyAudit {
478
489
  items,
479
490
  headings,
480
491
  wastedBytesByUrl,
492
+ warnings,
481
493
  };
482
494
  }
483
495
  }
@@ -1,54 +1,53 @@
1
1
  {
2
- "moduleSizes": [11897, 498, 265, 277, 263, 453, 219, 216, 546, 339, 1608, 671, 1525, 420, 214, 504, 98, 524, 196, 268, 642, 204, 742, 618, 169, 394, 127, 433, 1473, 779, 239, 144, 182, 254, 77, 508, 124, 1388, 75, 133, 301, 362, 170, 1078, 182, 490, 195, 321, 316, 447, 551, 216, 284, 253, 17, 107, 295, 356, 345, 1939, 1596, 291, 139, 259, 1291, 179, 528, 174, 61, 326, 20, 444, 522, 104, 1945, 120, 1943, 680, 1409, 850, 630, 288, 38, 695, 569, 106, 587, 208, 370, 606, 766, 535, 616, 200, 170, 224, 422, 970, 978, 498, 284, 241, 210, 151, 194, 178, 814, 205, 189, 215, 111, 236, 147, 237, 191, 691, 212, 432, 499, 445, 176, 333, 129, 414, 617, 380, 251, 199, 524, 515, 681, 160, 259, 295, 283, 178, 472, 786, 520, 202, 575, 575, 349, 549, 458, 166, 173, 508, 1522, 743, 414, 431, 393, 899, 137, 270, 131, 472, 457, 205, 778, 801, 133, 3000],
2
+ "moduleSizes": [17302, 498, 282, 294, 281, 467, 236, 229, 546, 339, 1608, 723, 1545, 438, 214, 111, 537, 209, 281, 685, 217, 757, 631, 182, 407, 140, 366, 1478, 359, 792, 269, 158, 280, 137, 189, 543, 1436, 88, 146, 314, 375, 183, 1083, 195, 503, 269, 208, 334, 350, 460, 568, 229, 334, 266, 30, 120, 309, 370, 358, 1952, 1638, 304, 153, 274, 1288, 192, 543, 187, 74, 144, 137, 33, 457, 535, 117, 1961, 133, 1956, 693, 1426, 863, 637, 301, 51, 708, 583, 119, 600, 221, 370, 728, 1085, 552, 629, 217, 183, 546, 137, 983, 992, 503, 402, 254, 223, 164, 214, 191, 831, 218, 202, 232, 124, 249, 160, 251, 217, 717, 225, 432, 499, 445, 177, 346, 142, 414, 617, 380, 264, 212, 524, 529, 708, 173, 272, 308, 296, 191, 485, 799, 533, 215, 589, 589, 362, 562, 471, 179, 186, 521, 1536, 756, 427, 444, 406, 912, 150, 283, 144, 485, 470, 205, 814, 146, 3000],
3
3
  "dependencies": {
4
- "Array.prototype.fill": [0, 5, 8, 11, 21, 23, 25, 26, 29, 36, 37, 54, 55, 57, 58, 60, 66, 73, 74, 75, 76, 77, 79, 81, 82, 86, 87, 88, 92, 94, 101, 102, 103, 104, 114, 116],
5
- "Array.prototype.filter": [0, 11, 12, 13, 17, 18, 21, 22, 23, 25, 26, 29, 36, 37, 41, 46, 54, 57, 58, 60, 62, 64, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 108, 114, 117],
6
- "Array.prototype.find": [0, 5, 11, 12, 17, 18, 21, 22, 23, 25, 26, 29, 36, 37, 41, 46, 54, 55, 57, 58, 60, 62, 64, 66, 73, 74, 75, 76, 77, 79, 81, 82, 86, 87, 88, 92, 94, 101, 102, 103, 104, 108, 114, 119],
7
- "Array.prototype.findIndex": [0, 5, 11, 12, 17, 18, 21, 22, 23, 25, 26, 29, 36, 37, 41, 46, 54, 55, 57, 58, 60, 62, 64, 66, 73, 74, 75, 76, 77, 79, 81, 82, 86, 87, 88, 92, 94, 101, 102, 103, 104, 108, 114, 118],
8
- "Array.prototype.forEach": [0, 9, 11, 12, 14, 17, 18, 21, 22, 23, 25, 26, 29, 36, 37, 41, 46, 54, 57, 58, 60, 62, 64, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 108, 114, 120],
9
- "Array.from": [0, 10, 11, 19, 20, 21, 22, 23, 25, 26, 27, 29, 36, 37, 41, 46, 49, 50, 54, 57, 58, 60, 61, 64, 66, 72, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 108, 114, 121],
10
- "Array.isArray": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 62, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 122],
11
- "Array.prototype.map": [0, 11, 12, 13, 17, 18, 21, 22, 23, 25, 26, 29, 36, 37, 41, 46, 54, 57, 58, 60, 62, 64, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 108, 114, 123],
12
- "Array.of": [0, 11, 21, 22, 23, 25, 26, 27, 29, 36, 37, 54, 57, 58, 60, 64, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 108, 114, 124],
13
- "Array.prototype.some": [0, 11, 12, 14, 17, 18, 21, 22, 23, 25, 26, 29, 36, 37, 41, 46, 54, 57, 58, 60, 62, 64, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 108, 114, 125],
14
- "Date.now": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 126],
15
- "Date.prototype.toISOString": [0, 11, 21, 22, 23, 25, 26, 28, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 98, 99, 101, 102, 103, 104, 108, 109, 114, 127],
16
- "Date.prototype.toJSON": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 128],
17
- "Date.prototype.toString": [0, 25, 26, 29, 54, 58, 60, 74, 94, 114, 129],
18
- "Function.prototype.name": [0, 130],
19
- "Number.isInteger": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 67, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 131],
20
- "Number.isSafeInteger": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 67, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 132],
21
- "Object.defineProperties": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 77, 79, 81, 82, 86, 87, 88, 92, 94, 101, 102, 103, 104, 114, 133],
22
- "Object.defineProperty": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 134],
23
- "Object.freeze": [0, 7, 11, 15, 21, 23, 25, 26, 27, 29, 36, 37, 39, 54, 57, 58, 59, 60, 66, 73, 74, 75, 79, 80, 81, 82, 84, 86, 88, 92, 94, 101, 102, 103, 104, 114, 136],
24
- "Object.getPrototypeOf": [0, 11, 21, 23, 24, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 83, 86, 88, 92, 94, 101, 102, 103, 104, 114, 138],
25
- "Object.isExtensible": [0, 7, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 84, 86, 88, 92, 94, 101, 102, 103, 104, 114, 139],
26
- "Object.isFrozen": [0, 7, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 140],
27
- "Object.isSealed": [0, 7, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 141],
28
- "Object.keys": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 87, 88, 92, 94, 101, 102, 103, 104, 114, 142],
29
- "Object.preventExtensions": [0, 7, 11, 15, 21, 23, 25, 26, 27, 29, 36, 37, 39, 54, 57, 58, 59, 60, 66, 73, 74, 75, 79, 80, 81, 82, 84, 86, 88, 92, 94, 101, 102, 103, 104, 114, 143],
30
- "Object.seal": [0, 7, 11, 15, 21, 23, 25, 26, 27, 29, 36, 37, 39, 54, 57, 58, 59, 60, 66, 73, 74, 75, 79, 80, 81, 82, 84, 86, 88, 92, 94, 101, 102, 103, 104, 114, 144],
31
- "Object.setPrototypeOf": [0, 4, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 89, 92, 94, 101, 102, 103, 104, 114, 145],
32
- "Reflect.apply": [0, 11, 21, 23, 25, 26, 29, 36, 37, 40, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 147],
33
- "Reflect.construct": [0, 3, 11, 16, 21, 22, 23, 25, 26, 29, 36, 37, 40, 43, 54, 55, 57, 58, 60, 64, 66, 73, 74, 75, 76, 77, 79, 81, 82, 86, 87, 88, 92, 94, 101, 102, 103, 104, 108, 114, 148],
34
- "Reflect.defineProperty": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 149],
35
- "Reflect.deleteProperty": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 150],
36
- "Reflect.get": [0, 11, 21, 23, 24, 25, 26, 29, 36, 37, 54, 57, 58, 60, 65, 66, 73, 74, 75, 79, 81, 82, 83, 86, 88, 92, 94, 101, 102, 103, 104, 114, 153],
37
- "Reflect.getOwnPropertyDescriptor": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 151],
38
- "Reflect.getPrototypeOf": [0, 11, 21, 23, 24, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 83, 86, 88, 92, 94, 101, 102, 103, 104, 114, 152],
39
- "Reflect.has": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 154],
40
- "Reflect.isExtensible": [0, 7, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 84, 86, 88, 92, 94, 101, 102, 103, 104, 114, 155],
41
- "Reflect.ownKeys": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 156],
42
- "Reflect.preventExtensions": [0, 11, 21, 23, 25, 26, 29, 36, 37, 39, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 157],
43
- "Reflect.setPrototypeOf": [0, 4, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 89, 92, 94, 101, 102, 103, 104, 114, 158],
44
- "String.prototype.codePointAt": [0, 11, 21, 22, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 97, 101, 102, 103, 104, 108, 109, 114, 159],
45
- "String.fromCodePoint": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 160],
46
- "String.raw": [0, 11, 21, 22, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 108, 109, 114, 161],
47
- "String.prototype.repeat": [0, 11, 21, 22, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 99, 101, 102, 103, 104, 108, 109, 114, 162],
48
- "Object.entries": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 87, 88, 90, 92, 94, 101, 102, 103, 104, 114, 135],
49
- "Object.getOwnPropertyDescriptors": [0, 11, 21, 23, 25, 26, 27, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 88, 92, 94, 101, 102, 103, 104, 114, 137],
50
- "Object.values": [0, 11, 21, 23, 25, 26, 29, 36, 37, 54, 57, 58, 60, 66, 73, 74, 75, 79, 81, 82, 86, 87, 88, 90, 92, 94, 101, 102, 103, 104, 114, 146],
4
+ "Array.prototype.fill": [0, 5, 8, 11, 20, 22, 29, 33, 36, 55, 57, 66, 74, 76, 77, 78, 80, 82, 83, 87, 88, 89, 93, 102, 103, 104, 105, 117],
5
+ "Array.prototype.filter": [0, 11, 12, 13, 16, 17, 20, 21, 22, 29, 33, 36, 40, 46, 57, 62, 64, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 109, 118],
6
+ "Array.prototype.find": [0, 5, 11, 12, 16, 17, 20, 21, 22, 29, 33, 36, 40, 46, 55, 57, 62, 64, 66, 74, 76, 77, 78, 80, 82, 83, 87, 88, 89, 93, 102, 103, 104, 105, 109, 120],
7
+ "Array.prototype.findIndex": [0, 5, 11, 12, 16, 17, 20, 21, 22, 29, 33, 36, 40, 46, 55, 57, 62, 64, 66, 74, 76, 77, 78, 80, 82, 83, 87, 88, 89, 93, 102, 103, 104, 105, 109, 119],
8
+ "Array.prototype.forEach": [0, 9, 11, 12, 14, 16, 17, 20, 21, 22, 29, 33, 36, 40, 46, 57, 62, 64, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 109, 121],
9
+ "Array.from": [0, 10, 11, 18, 19, 20, 21, 22, 26, 29, 33, 36, 40, 46, 49, 50, 57, 61, 64, 66, 73, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 109, 122],
10
+ "Array.isArray": [0, 11, 20, 22, 29, 33, 36, 57, 62, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 123],
11
+ "Array.prototype.map": [0, 11, 12, 13, 16, 17, 20, 21, 22, 29, 33, 36, 40, 46, 57, 62, 64, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 109, 124],
12
+ "Array.of": [0, 11, 20, 21, 22, 26, 29, 33, 36, 57, 64, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 109, 125],
13
+ "Array.prototype.some": [0, 11, 12, 14, 16, 17, 20, 21, 22, 29, 33, 36, 40, 46, 57, 62, 64, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 109, 126],
14
+ "Date.now": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 127],
15
+ "Date.prototype.toISOString": [0, 11, 20, 21, 22, 27, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 99, 100, 102, 103, 104, 105, 109, 110, 128],
16
+ "Date.prototype.toJSON": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 129],
17
+ "Date.prototype.toString": [0, 29, 130],
18
+ "Function.prototype.name": [0, 28, 131],
19
+ "Number.isInteger": [0, 11, 20, 22, 29, 33, 36, 57, 66, 67, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 132],
20
+ "Number.isSafeInteger": [0, 11, 20, 22, 29, 33, 36, 57, 66, 67, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 133],
21
+ "Object.defineProperties": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 78, 80, 82, 83, 87, 88, 89, 93, 102, 103, 104, 105, 134],
22
+ "Object.defineProperty": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 135],
23
+ "Object.freeze": [0, 7, 11, 15, 20, 22, 29, 33, 36, 38, 57, 59, 66, 74, 76, 80, 81, 82, 83, 85, 87, 89, 93, 102, 103, 104, 105, 137],
24
+ "Object.getPrototypeOf": [0, 11, 20, 22, 23, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 84, 87, 89, 93, 102, 103, 104, 105, 139],
25
+ "Object.isExtensible": [0, 7, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 85, 87, 89, 93, 102, 103, 104, 105, 140],
26
+ "Object.isFrozen": [0, 7, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 141],
27
+ "Object.isSealed": [0, 7, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 142],
28
+ "Object.keys": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 88, 89, 93, 102, 103, 104, 105, 143],
29
+ "Object.preventExtensions": [0, 7, 11, 15, 20, 22, 29, 33, 36, 38, 57, 59, 66, 74, 76, 80, 81, 82, 83, 85, 87, 89, 93, 102, 103, 104, 105, 144],
30
+ "Object.seal": [0, 7, 11, 15, 20, 22, 29, 33, 36, 38, 57, 59, 66, 74, 76, 80, 81, 82, 83, 85, 87, 89, 93, 102, 103, 104, 105, 145],
31
+ "Object.setPrototypeOf": [0, 4, 11, 20, 22, 29, 33, 36, 45, 57, 66, 70, 74, 76, 80, 82, 83, 87, 89, 90, 93, 102, 103, 104, 105, 146],
32
+ "Reflect.apply": [0, 11, 20, 22, 29, 33, 36, 39, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 148],
33
+ "Reflect.construct": [0, 3, 11, 15, 20, 21, 22, 29, 33, 36, 39, 42, 55, 57, 64, 66, 74, 76, 77, 78, 80, 82, 83, 87, 88, 89, 93, 102, 103, 104, 105, 109, 149],
34
+ "Reflect.defineProperty": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 150],
35
+ "Reflect.deleteProperty": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 151],
36
+ "Reflect.get": [0, 11, 20, 22, 23, 29, 33, 36, 57, 65, 66, 74, 76, 80, 82, 83, 84, 87, 89, 93, 102, 103, 104, 105, 154],
37
+ "Reflect.getOwnPropertyDescriptor": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 152],
38
+ "Reflect.getPrototypeOf": [0, 11, 20, 22, 23, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 84, 87, 89, 93, 102, 103, 104, 105, 153],
39
+ "Reflect.has": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 155],
40
+ "Reflect.isExtensible": [0, 7, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 85, 87, 89, 93, 102, 103, 104, 105, 156],
41
+ "Reflect.ownKeys": [0, 11, 20, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 157],
42
+ "Reflect.preventExtensions": [0, 11, 20, 22, 29, 33, 36, 38, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 158],
43
+ "Reflect.setPrototypeOf": [0, 4, 11, 20, 22, 29, 33, 36, 45, 57, 66, 70, 74, 76, 80, 82, 83, 87, 89, 90, 93, 102, 103, 104, 105, 159],
44
+ "String.prototype.codePointAt": [0, 11, 20, 21, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 98, 102, 103, 104, 105, 109, 110, 160],
45
+ "String.raw": [0, 11, 20, 21, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 109, 110, 161],
46
+ "String.prototype.repeat": [0, 11, 20, 21, 22, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 100, 102, 103, 104, 105, 109, 110, 162],
47
+ "Object.entries": [0, 11, 20, 22, 23, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 84, 87, 88, 89, 91, 93, 102, 103, 104, 105, 136],
48
+ "Object.getOwnPropertyDescriptors": [0, 11, 20, 22, 26, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 87, 89, 93, 102, 103, 104, 105, 138],
49
+ "Object.values": [0, 11, 20, 22, 23, 29, 33, 36, 57, 66, 74, 76, 80, 82, 83, 84, 87, 88, 89, 91, 93, 102, 103, 104, 105, 147],
51
50
  "focus-visible": [163]
52
51
  },
53
- "maxSize": 87683
52
+ "maxSize": 94935
54
53
  }
@@ -8,7 +8,6 @@ import {Audit} from '../audit.js';
8
8
  import * as i18n from '../../lib/i18n/i18n.js';
9
9
  import {NetworkRequest} from '../../lib/network-request.js';
10
10
  import {NetworkRecords} from '../../computed/network-records.js';
11
- import {Util} from '../../../shared/util.js';
12
11
 
13
12
  const UIStrings = {
14
13
  /** Title of a diagnostic audit that provides detail on large network resources required during page load. 'Payloads' is roughly equivalent to 'resources'. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
@@ -99,7 +98,6 @@ class TotalByteWeight extends Audit {
99
98
 
100
99
  return {
101
100
  score,
102
- scoreDisplayMode: score >= Util.PASS_THRESHOLD ? Audit.SCORING_MODES.INFORMATIVE : undefined,
103
101
  numericValue: totalBytes,
104
102
  numericUnit: 'byte',
105
103
  displayValue: str_(UIStrings.displayValue, {totalBytes}),
@@ -0,0 +1,42 @@
1
+ export default ClickjackingMitigation;
2
+ declare class ClickjackingMitigation extends Audit {
3
+ /**
4
+ * @param {LH.Artifacts} artifacts
5
+ * @param {LH.Audit.Context} context
6
+ * @return {Promise<{cspHeaders: string[], xfoHeaders: string[]}>}
7
+ */
8
+ static getRawCspsAndXfo(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<{
9
+ cspHeaders: string[];
10
+ xfoHeaders: string[];
11
+ }>;
12
+ /**
13
+ * @param {string | undefined} directive
14
+ * @param {LH.IcuMessage | string} findingDescription
15
+ * @param {LH.IcuMessage=} severity
16
+ * @return {LH.Audit.Details.TableItem}
17
+ */
18
+ static findingToTableItem(directive: string | undefined, findingDescription: LH.IcuMessage | string, severity?: LH.IcuMessage | undefined): LH.Audit.Details.TableItem;
19
+ /**
20
+ * @param {string[]} cspHeaders
21
+ * @param {string[]} xfoHeaders
22
+ * @return {{score: number, results: LH.Audit.Details.TableItem[]}}
23
+ */
24
+ static constructResults(cspHeaders: string[], xfoHeaders: string[]): {
25
+ score: number;
26
+ results: LH.Audit.Details.TableItem[];
27
+ };
28
+ /**
29
+ * @param {LH.Artifacts} artifacts
30
+ * @param {LH.Audit.Context} context
31
+ * @return {Promise<LH.Audit.Product>}
32
+ */
33
+ static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
34
+ }
35
+ export namespace UIStrings {
36
+ let title: string;
37
+ let description: string;
38
+ let noClickjackingMitigation: string;
39
+ let columnSeverity: string;
40
+ }
41
+ import { Audit } from './audit.js';
42
+ //# sourceMappingURL=clickjacking-mitigation.d.ts.map
@@ -0,0 +1,139 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import {Audit} from './audit.js';
8
+ import {MainResource} from '../computed/main-resource.js';
9
+ import * as i18n from '../lib/i18n/i18n.js';
10
+
11
+ const UIStrings = {
12
+ /** Title of a Lighthouse audit that evaluates whether the set CSP or XFO header is mitigating clickjacking attacks. "XFO" stands for "X-Frame-Options" and should not be translated. "CSP" stands for "Content-Security-Policy" and should not be translated. "clickjacking" should not be translated. */
13
+ title: 'Mitigate clickjacking with XFO or CSP',
14
+ /** Description of a Lighthouse audit that evaluates whether the set CSP or XFO header is mitigating clickjacking attacks. This is displayed after a user expands the section to see more. "clickjacking" should not be translated. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. "XFO" stands for "X-Frame-Options" and should not be translated. "CSP" stands for "Content-Security-Policy" and should not be translated. */
15
+ description: 'The `X-Frame-Options` (XFO) header or the `frame-ancestors` directive in the `Content-Security-Policy` (CSP) header control where a page can be embedded. These can mitigate clickjacking attacks by blocking some or all sites from embedding the page. [Learn more about mitigating clickjacking](https://developer.chrome.com/docs/lighthouse/best-practices/clickjacking-mitigation).',
16
+ /** Summary text for the results of a Lighthouse audit that evaluates whether the page is mitigating clickjacking attacks with a frame control policy. This text is displayed if the page does not control how it can be embedded on other pages. */
17
+ noClickjackingMitigation: 'No frame control policy found',
18
+ /** Label for a column in a data table; entries will be the severity of an issue with the page's frame control policy. */
19
+ columnSeverity: 'Severity',
20
+ };
21
+
22
+ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
23
+
24
+ class ClickjackingMitigation extends Audit {
25
+ /**
26
+ * @return {LH.Audit.Meta}
27
+ */
28
+ static get meta() {
29
+ return {
30
+ id: 'clickjacking-mitigation',
31
+ scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE,
32
+ title: str_(UIStrings.title),
33
+ description: str_(UIStrings.description),
34
+ requiredArtifacts: ['devtoolsLogs', 'URL'],
35
+ supportedModes: ['navigation'],
36
+ };
37
+ }
38
+
39
+ /**
40
+ * @param {LH.Artifacts} artifacts
41
+ * @param {LH.Audit.Context} context
42
+ * @return {Promise<{cspHeaders: string[], xfoHeaders: string[]}>}
43
+ */
44
+ static async getRawCspsAndXfo(artifacts, context) {
45
+ const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
46
+ const mainResource =
47
+ await MainResource.request({devtoolsLog, URL: artifacts.URL}, context);
48
+
49
+ const cspHeaders = mainResource.responseHeaders
50
+ .filter(h => {
51
+ return h.name.toLowerCase() === 'content-security-policy';
52
+ })
53
+ .flatMap(h => h.value.split(','))
54
+ .filter(rawCsp => rawCsp.replace(/\s/g, ''));
55
+ let xfoHeaders = mainResource.responseHeaders
56
+ .filter(h => {
57
+ return h.name.toLowerCase() === 'x-frame-options';
58
+ })
59
+ .flatMap(h => h.value);
60
+
61
+ // Sanitize the XFO header value.
62
+ xfoHeaders = xfoHeaders.map(v => v.toLowerCase().replace(/\s/g, ''));
63
+
64
+ return {cspHeaders, xfoHeaders};
65
+ }
66
+
67
+ /**
68
+ * @param {string | undefined} directive
69
+ * @param {LH.IcuMessage | string} findingDescription
70
+ * @param {LH.IcuMessage=} severity
71
+ * @return {LH.Audit.Details.TableItem}
72
+ */
73
+ static findingToTableItem(directive, findingDescription, severity) {
74
+ return {
75
+ description: findingDescription,
76
+ severity,
77
+ };
78
+ }
79
+
80
+ /**
81
+ * @param {string[]} cspHeaders
82
+ * @param {string[]} xfoHeaders
83
+ * @return {{score: number, results: LH.Audit.Details.TableItem[]}}
84
+ */
85
+ static constructResults(cspHeaders, xfoHeaders) {
86
+ const allowedDirectives = ['deny', 'sameorigin'];
87
+
88
+ // Check for frame-ancestors in CSP.
89
+ for (const cspHeader of cspHeaders) {
90
+ if (cspHeader.includes('frame-ancestors')) {
91
+ // Pass the audit if frame-ancestors is present.
92
+ return {score: 1, results: []};
93
+ }
94
+ }
95
+
96
+ for (const actualDirective of xfoHeaders) {
97
+ if (allowedDirectives.includes(actualDirective)) {
98
+ // DENY or SAMEORIGIN are present.
99
+ return {score: 1, results: []};
100
+ }
101
+ }
102
+
103
+ return {
104
+ score: 0,
105
+ results: [{
106
+ severity: str_(i18n.UIStrings.itemSeverityHigh),
107
+ description: str_(UIStrings.noClickjackingMitigation),
108
+ }],
109
+ };
110
+ }
111
+
112
+ /**
113
+ * @param {LH.Artifacts} artifacts
114
+ * @param {LH.Audit.Context} context
115
+ * @return {Promise<LH.Audit.Product>}
116
+ */
117
+ static async audit(artifacts, context) {
118
+ const {cspHeaders, xfoHeaders} = await this.getRawCspsAndXfo(artifacts, context);
119
+ const {score, results} = this.constructResults(cspHeaders, xfoHeaders);
120
+
121
+ /** @type {LH.Audit.Details.Table['headings']} */
122
+ const headings = [
123
+ /* eslint-disable max-len */
124
+ {key: 'description', valueType: 'text', subItemsHeading: {key: 'description'}, label: str_(i18n.UIStrings.columnDescription)},
125
+ {key: 'severity', valueType: 'text', subItemsHeading: {key: 'severity'}, label: str_(UIStrings.columnSeverity)},
126
+ /* eslint-enable max-len */
127
+ ];
128
+ const details = Audit.makeTableDetails(headings, results);
129
+
130
+ return {
131
+ score,
132
+ notApplicable: !results.length,
133
+ details,
134
+ };
135
+ }
136
+ }
137
+
138
+ export default ClickjackingMitigation;
139
+ export {UIStrings};
@@ -14,7 +14,6 @@
14
14
  import {Audit} from '../audit.js';
15
15
  import * as i18n from '../../lib/i18n/i18n.js';
16
16
  import {TBTImpactTasks} from '../../computed/tbt-impact-tasks.js';
17
- import {Util} from '../../../shared/util.js';
18
17
 
19
18
  const UIStrings = {
20
19
  /** Title of a diagnostic audit that provides detail on the size of the web page's DOM. The size of a DOM is characterized by the total number of DOM elements and greatest DOM depth. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
@@ -168,7 +167,6 @@ class DOMSize extends Audit {
168
167
 
169
168
  return {
170
169
  score,
171
- scoreDisplayMode: score >= Util.PASS_THRESHOLD ? Audit.SCORING_MODES.INFORMATIVE : undefined,
172
170
  numericValue: stats.totalBodyElements,
173
171
  numericUnit: 'element',
174
172
  displayValue: str_(UIStrings.displayValue, {itemCount: stats.totalBodyElements}),
@@ -0,0 +1,3 @@
1
+ # Insight audits
2
+
3
+ When adding new insight audits, you can start off by just running `yarn generate-insight-audits`
@@ -0,0 +1,25 @@
1
+ export default CLSCulpritsInsight;
2
+ export type SubItem = {
3
+ extra?: LH.Audit.Details.NodeValue | LH.Audit.Details.UrlValue;
4
+ cause: LH.IcuMessage;
5
+ };
6
+ declare class CLSCulpritsInsight extends Audit {
7
+ /**
8
+ * @param {import('@paulirish/trace_engine/models/trace/insights/CLSCulprits.js').CLSCulpritsInsightModel} insight
9
+ * @param {import('../../lib/trace-engine.js').SaneSyntheticLayoutShift} event
10
+ * @param {LH.Artifacts.TraceElement[]} TraceElements
11
+ * @return {LH.Audit.Details.TableSubItems|undefined}
12
+ */
13
+ static getCulpritSubItems(insight: import("@paulirish/trace_engine/models/trace/insights/CLSCulprits.js").CLSCulpritsInsightModel, event: import("../../lib/trace-engine.js").SaneSyntheticLayoutShift, TraceElements: LH.Artifacts.TraceElement[]): LH.Audit.Details.TableSubItems | undefined;
14
+ /**
15
+ * @param {LH.Artifacts} artifacts
16
+ * @param {LH.Audit.Context} context
17
+ * @return {Promise<LH.Audit.Product>}
18
+ */
19
+ static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
20
+ }
21
+ export namespace UIStrings {
22
+ let columnScore: string;
23
+ }
24
+ import { Audit } from '../audit.js';
25
+ //# sourceMappingURL=cls-culprits-insight.d.ts.map