lighthouse 11.1.0-dev.20231001 → 11.1.0-dev.20231003

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 (33) hide show
  1. package/cli/test/smokehouse/__snapshots__/report-assert-test.js.snap +8 -0
  2. package/core/audits/audit.js +4 -9
  3. package/core/audits/byte-efficiency/uses-long-cache-ttl.js +1 -1
  4. package/core/audits/csp-xss.js +1 -1
  5. package/core/audits/installable-manifest.js +2 -2
  6. package/core/audits/metrics/cumulative-layout-shift.js +4 -1
  7. package/core/audits/metrics/first-contentful-paint.js +1 -0
  8. package/core/audits/metrics/largest-contentful-paint.js +1 -0
  9. package/core/audits/metrics/speed-index.js +1 -0
  10. package/core/audits/metrics/total-blocking-time.js +1 -0
  11. package/core/lib/csp-evaluator.js +13 -13
  12. package/dist/report/bundle.esm.js +243 -89
  13. package/dist/report/flow.js +248 -94
  14. package/dist/report/standalone.js +244 -90
  15. package/package.json +1 -1
  16. package/report/assets/styles.css +227 -78
  17. package/report/assets/templates.html +22 -35
  18. package/report/renderer/components.d.ts +2 -2
  19. package/report/renderer/components.js +34 -51
  20. package/report/renderer/dom.d.ts +24 -4
  21. package/report/renderer/dom.js +30 -3
  22. package/report/renderer/explodey-gauge.d.ts +11 -0
  23. package/report/renderer/explodey-gauge.js +357 -0
  24. package/report/renderer/performance-category-renderer.d.ts +16 -18
  25. package/report/renderer/performance-category-renderer.js +93 -102
  26. package/shared/localization/locales/en-US.json +14 -14
  27. package/shared/localization/locales/en-XL.json +14 -14
  28. package/shared/util.d.ts +22 -0
  29. package/shared/util.js +31 -0
  30. package/types/audit.d.ts +3 -1
  31. package/types/lhr/audit-result.d.ts +9 -0
  32. /package/{core/lib → shared}/statistics.d.ts +0 -0
  33. /package/{core/lib → shared}/statistics.js +0 -0
@@ -20,6 +20,10 @@ exports[`getAssertionReport works (multiple failing) 1`] = `
20
20
  \\"numericValue\\": 0.13570762803819444,
21
21
  \\"numericUnit\\": \\"unitless\\",
22
22
  \\"displayValue\\": \\"0.136\\",
23
+ \\"scoringOptions\\": {
24
+ \\"p10\\": 0.1,
25
+ \\"median\\": 0.25
26
+ },
23
27
  \\"details\\": {
24
28
  \\"type\\": \\"debugdata\\",
25
29
  \\"items\\": [
@@ -46,6 +50,10 @@ exports[`getAssertionReport works (trivial failing) 1`] = `
46
50
  \\"numericValue\\": 0.13570762803819444,
47
51
  \\"numericUnit\\": \\"unitless\\",
48
52
  \\"displayValue\\": \\"0.136\\",
53
+ \\"scoringOptions\\": {
54
+ \\"p10\\": 0.1,
55
+ \\"median\\": 0.25
56
+ },
49
57
  \\"details\\": {
50
58
  \\"type\\": \\"debugdata\\",
51
59
  \\"items\\": [
@@ -6,7 +6,6 @@
6
6
 
7
7
  import * as LH from '../../types/lh.js';
8
8
  import {isUnderTest} from '../lib/lh-env.js';
9
- import * as statistics from '../lib/statistics.js';
10
9
  import {Util} from '../../shared/util.js';
11
10
 
12
11
  const DEFAULT_PASS = 'defaultPass';
@@ -105,14 +104,7 @@ class Audit {
105
104
  * @return {number}
106
105
  */
107
106
  static computeLogNormalScore(controlPoints, value) {
108
- let percentile = statistics.getLogNormalScore(controlPoints, value);
109
- // Add a boost to scores of 90+, linearly ramping from 0 at 0.9 to half a
110
- // point (0.005) at 1. Expands scores in (0.9, 1] to (0.9, 1.005], so more top
111
- // scores will be a perfect 1 after the two-digit `Math.floor()` rounding below.
112
- if (percentile > 0.9) { // getLogNormalScore ensures `percentile` can't exceed 1.
113
- percentile += 0.05 * (percentile - 0.9);
114
- }
115
- return Math.floor(percentile * 100) / 100;
107
+ return Util.computeLogNormalScore(controlPoints, value);
116
108
  }
117
109
 
118
110
  /**
@@ -411,8 +403,11 @@ class Audit {
411
403
  errorMessage: product.errorMessage,
412
404
  errorStack: product.errorStack,
413
405
  warnings: product.warnings,
406
+ scoringOptions: product.scoringOptions,
407
+ metricSavings: product.metricSavings,
414
408
 
415
409
  details: product.details,
410
+ guidanceLevel: audit.meta.guidanceLevel,
416
411
  };
417
412
  }
418
413
 
@@ -9,7 +9,7 @@ import parseCacheControl from 'parse-cache-control';
9
9
  import {Audit} from '../audit.js';
10
10
  import {NetworkRequest} from '../../lib/network-request.js';
11
11
  import UrlUtils from '../../lib/url-utils.js';
12
- import {linearInterpolation} from '../../lib/statistics.js';
12
+ import {linearInterpolation} from '../../../shared/statistics.js';
13
13
  import * as i18n from '../../lib/i18n/i18n.js';
14
14
  import {NetworkRecords} from '../../computed/network-records.js';
15
15
 
@@ -21,7 +21,7 @@ const UIStrings = {
21
21
  /** Summary text for the results of a Lighthouse audit that evaluates the security of a page's CSP. This is displayed if no CSP is being enforced. "CSP" stands for "Content Security Policy". "CSP" does not need to be translated. */
22
22
  noCsp: 'No CSP found in enforcement mode',
23
23
  /** Message shown when one or more CSPs are defined in a <meta> tag. Shown in a table with a list of other CSP bypasses and warnings. "CSP" stands for "Content Security Policy". "CSP" and "HTTP" do not need to be translated. */
24
- metaTagMessage: 'The page contains a CSP defined in a <meta> tag. ' +
24
+ metaTagMessage: 'The page contains a CSP defined in a `<meta>` tag. ' +
25
25
  'Consider moving the CSP to an HTTP header or ' +
26
26
  'defining another strict CSP in an HTTP header.',
27
27
  /** Label for a column in a data table; entries will be a directive of a CSP. "CSP" stands for "Content Security Policy". */
@@ -39,9 +39,9 @@ const UIStrings = {
39
39
  /** Error message explaining that the provided manifest URL is invalid. */
40
40
  'start-url-not-valid': `Manifest start URL is not valid`,
41
41
  /** Error message explaining that the provided manifest does not contain a name or short_name field. */
42
- 'manifest-missing-name-or-short-name': `Manifest does not contain a 'name' or 'short_name' field`,
42
+ 'manifest-missing-name-or-short-name': 'Manifest does not contain a `name` or `short_name` field',
43
43
  /** Error message explaining that the manifest display property must be one of 'standalone', 'fullscreen', or 'minimal-ui'. */
44
- 'manifest-display-not-supported': `Manifest 'display' property must be one of 'standalone', 'fullscreen', or 'minimal-ui'`,
44
+ 'manifest-display-not-supported': 'Manifest `display` property must be one of `standalone`, `fullscreen`, or `minimal-ui`',
45
45
  /** Error message explaining that the manifest could not be fetched, might be empty, or could not be parsed. */
46
46
  'manifest-empty': `Manifest could not be fetched, is empty, or could not be parsed`,
47
47
  /**
@@ -62,11 +62,14 @@ class CumulativeLayoutShift extends Audit {
62
62
  items: [rest],
63
63
  };
64
64
 
65
+ const scoringOptions = {p10: context.options.p10, median: context.options.median};
66
+
65
67
  return {
66
68
  score: Audit.computeLogNormalScore(
67
- {p10: context.options.p10, median: context.options.median},
69
+ scoringOptions,
68
70
  cumulativeLayoutShift
69
71
  ),
72
+ scoringOptions,
70
73
  numericValue: cumulativeLayoutShift,
71
74
  numericUnit: 'unitless',
72
75
  displayValue: cumulativeLayoutShift.toLocaleString(context.settings.locale),
@@ -74,6 +74,7 @@ class FirstContentfulPaint extends Audit {
74
74
  options.scoring,
75
75
  metricResult.timing
76
76
  ),
77
+ scoringOptions: options.scoring,
77
78
  numericValue: metricResult.timing,
78
79
  numericUnit: 'millisecond',
79
80
  displayValue: str_(i18n.UIStrings.seconds, {timeInMs: metricResult.timing}),
@@ -83,6 +83,7 @@ class LargestContentfulPaint extends Audit {
83
83
  options.scoring,
84
84
  metricResult.timing
85
85
  ),
86
+ scoringOptions: options.scoring,
86
87
  numericValue: metricResult.timing,
87
88
  numericUnit: 'millisecond',
88
89
  displayValue: str_(i18n.UIStrings.seconds, {timeInMs: metricResult.timing}),
@@ -77,6 +77,7 @@ class SpeedIndex extends Audit {
77
77
  options.scoring,
78
78
  metricResult.timing
79
79
  ),
80
+ scoringOptions: options.scoring,
80
81
  numericValue: metricResult.timing,
81
82
  numericUnit: 'millisecond',
82
83
  displayValue: str_(i18n.UIStrings.seconds, {timeInMs: metricResult.timing}),
@@ -107,6 +107,7 @@ class TotalBlockingTime extends Audit {
107
107
  options.scoring,
108
108
  metricResult.timing
109
109
  ),
110
+ scoringOptions: options.scoring,
110
111
  numericValue: metricResult.timing,
111
112
  numericUnit: 'millisecond',
112
113
  displayValue: str_(i18n.UIStrings.ms, {timeInMs: metricResult.timing}),
@@ -19,31 +19,31 @@ import {isIcuMessage} from '../../shared/localization/format.js';
19
19
 
20
20
  const UIStrings = {
21
21
  /** Message shown when a CSP does not have a base-uri directive. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "base-uri", "'none'", and "'self'" do not need to be translated. */
22
- missingBaseUri: 'Missing base-uri allows injected <base> tags to set the base URL for all ' +
22
+ missingBaseUri: 'Missing `base-uri` allows injected `<base>` tags to set the base URL for all ' +
23
23
  'relative URLs (e.g. scripts) to an attacker controlled domain. ' +
24
- 'Consider setting base-uri to \'none\' or \'self\'.',
24
+ 'Consider setting `base-uri` to `\'none\'` or `\'self\'`.',
25
25
  /** Message shown when a CSP does not have a script-src directive. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "script-src" does not need to be translated. */
26
- missingScriptSrc: 'script-src directive is missing. ' +
26
+ missingScriptSrc: '`script-src` directive is missing. ' +
27
27
  'This can allow the execution of unsafe scripts.',
28
28
  /** Message shown when a CSP does not have a script-src directive. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "object-src" and "'none'" do not need to be translated. */
29
- missingObjectSrc: 'Missing object-src allows the injection of plugins ' +
30
- 'that execute unsafe scripts. Consider setting object-src to \'none\' if you can.',
29
+ missingObjectSrc: 'Missing `object-src` allows the injection of plugins ' +
30
+ 'that execute unsafe scripts. Consider setting `object-src` to `\'none\'` if you can.',
31
31
  /** Message shown when a CSP uses a domain allowlist to filter out malicious scripts. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "CSP", "'strict-dynamic'", "nonces", and "hashes" do not need to be translated. "allowlists" can be interpreted as "whitelist". */
32
32
  strictDynamic: 'Host allowlists can frequently be bypassed. Consider using ' +
33
- 'CSP nonces or hashes instead, along with \'strict-dynamic\' if necessary.',
33
+ 'CSP nonces or hashes instead, along with `\'strict-dynamic\'` if necessary.',
34
34
  /** Message shown when a CSP allows inline scripts to be run in the page. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "CSP", "'unsafe-inline'", "nonces", and "hashes" do not need to be translated. */
35
- unsafeInline: '\'unsafe-inline\' allows the execution of unsafe in-page scripts ' +
35
+ unsafeInline: '`\'unsafe-inline\'` allows the execution of unsafe in-page scripts ' +
36
36
  'and event handlers. Consider using CSP nonces or hashes to allow scripts individually.',
37
37
  /** Message shown when a CSP is not backwards compatible with browsers that do not support CSP nonces/hashes. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "'unsafe-inline'", "nonces", and "hashes" do not need to be translated. */
38
- unsafeInlineFallback: 'Consider adding \'unsafe-inline\' (ignored by browsers supporting ' +
38
+ unsafeInlineFallback: 'Consider adding `\'unsafe-inline\'` (ignored by browsers supporting ' +
39
39
  'nonces/hashes) to be backward compatible with older browsers.',
40
40
  /** Message shown when a CSP is not backwards compatible with browsers that do not support the 'strict-dynamic' keyword. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "http:", "https:", and "'strict-dynamic'" do not need to be translated. */
41
41
  allowlistFallback: 'Consider adding https: and http: URL schemes (ignored by browsers ' +
42
- 'supporting \'strict-dynamic\') to be backward compatible with older browsers.',
42
+ 'supporting `\'strict-dynamic\'`) to be backward compatible with older browsers.',
43
43
  /** Message shown when a CSP only provides a reporting destination through the report-to directive. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "report-to", "report-uri", and "Chromium" do not need to be translated. */
44
44
  reportToOnly: 'The reporting destination is only configured via the report-to directive. ' +
45
45
  'This directive is only supported in Chromium-based browsers so it is ' +
46
- 'recommended to also use a report-uri directive.',
46
+ 'recommended to also use a `report-uri` directive.',
47
47
  /** Message shown when a CSP does not provide a reporting destination. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "CSP" does not need to be translated. */
48
48
  reportingDestinationMissing: 'No CSP configures a reporting destination. ' +
49
49
  'This makes it difficult to maintain the CSP over time and monitor for any breakages.',
@@ -65,13 +65,13 @@ const UIStrings = {
65
65
  */
66
66
  unknownKeyword: '{keyword} seems to be an invalid keyword.',
67
67
  /** Message shown when a CSP uses the deprecated reflected-xss directive. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "reflected-xss", "CSP2" and "X-XSS-Protection" do not need to be translated. */
68
- deprecatedReflectedXSS: 'reflected-xss is deprecated since CSP2. ' +
68
+ deprecatedReflectedXSS: '`reflected-xss` is deprecated since CSP2. ' +
69
69
  'Please, use the X-XSS-Protection header instead.',
70
70
  /** Message shown when a CSP uses the deprecated referrer directive. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "referrer", "CSP2" and "Referrer-Policy" do not need to be translated. */
71
- deprecatedReferrer: 'referrer is deprecated since CSP2. ' +
71
+ deprecatedReferrer: '`referrer` is deprecated since CSP2. ' +
72
72
  'Please, use the Referrer-Policy header instead.',
73
73
  /** Message shown when a CSP uses the deprecated disown-opener directive. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "disown-opener", "CSP3" and "Cross-Origin-Opener-Policy" do not need to be translated. */
74
- deprecatedDisownOpener: 'disown-opener is deprecated since CSP3. ' +
74
+ deprecatedDisownOpener: '`disown-opener` is deprecated since CSP3. ' +
75
75
  'Please, use the Cross-Origin-Opener-Policy header instead.',
76
76
  /**
77
77
  * @description Message shown when a CSP wildcard allows unsafe scripts to be run in the page. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy".