lighthouse 9.1.0 → 9.2.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 (104) hide show
  1. package/changelog.md +51 -4
  2. package/dist/report/bundle.esm.js +3 -3
  3. package/dist/report/flow.js +1 -1
  4. package/dist/report/standalone.js +1 -1
  5. package/flow-report/assets/styles.css +1 -1
  6. package/lighthouse-cli/test/smokehouse/core-tests.js +124 -0
  7. package/lighthouse-cli/test/smokehouse/frontends/lib.js +6 -4
  8. package/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +2 -49
  9. package/lighthouse-cli/test/smokehouse/readme.md +1 -1
  10. package/lighthouse-cli/test/smokehouse/smokehouse.js +50 -0
  11. package/lighthouse-core/audits/apple-touch-icon.js +2 -2
  12. package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +1 -14
  13. package/lighthouse-core/audits/byte-efficiency/legacy-javascript.js +0 -4
  14. package/lighthouse-core/audits/no-unload-listeners.js +1 -1
  15. package/lighthouse-core/computed/computed-artifact.js +14 -7
  16. package/lighthouse-core/computed/critical-request-chains.js +3 -3
  17. package/lighthouse-core/computed/image-records.js +1 -1
  18. package/lighthouse-core/computed/js-bundles.js +1 -1
  19. package/lighthouse-core/computed/load-simulator.js +2 -1
  20. package/lighthouse-core/computed/main-resource.js +1 -1
  21. package/lighthouse-core/computed/main-thread-tasks.js +1 -1
  22. package/lighthouse-core/computed/manifest-values.js +1 -1
  23. package/lighthouse-core/computed/metrics/cumulative-layout-shift.js +1 -1
  24. package/lighthouse-core/computed/metrics/first-contentful-paint-all-frames.js +4 -1
  25. package/lighthouse-core/computed/metrics/first-contentful-paint.js +4 -1
  26. package/lighthouse-core/computed/metrics/first-meaningful-paint.js +4 -1
  27. package/lighthouse-core/computed/metrics/interactive.js +4 -1
  28. package/lighthouse-core/computed/metrics/lantern-first-contentful-paint.js +7 -2
  29. package/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js +4 -1
  30. package/lighthouse-core/computed/metrics/lantern-interactive.js +4 -1
  31. package/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js +4 -1
  32. package/lighthouse-core/computed/metrics/lantern-max-potential-fid.js +4 -1
  33. package/lighthouse-core/computed/metrics/lantern-speed-index.js +4 -1
  34. package/lighthouse-core/computed/metrics/lantern-total-blocking-time.js +4 -1
  35. package/lighthouse-core/computed/metrics/largest-contentful-paint-all-frames.js +4 -1
  36. package/lighthouse-core/computed/metrics/largest-contentful-paint.js +4 -1
  37. package/lighthouse-core/computed/metrics/max-potential-fid.js +4 -1
  38. package/lighthouse-core/computed/metrics/speed-index.js +4 -1
  39. package/lighthouse-core/computed/metrics/timing-summary.js +4 -1
  40. package/lighthouse-core/computed/metrics/total-blocking-time.js +4 -1
  41. package/lighthouse-core/computed/module-duplication.js +2 -2
  42. package/lighthouse-core/computed/network-analysis.js +1 -1
  43. package/lighthouse-core/computed/network-records.js +1 -1
  44. package/lighthouse-core/computed/page-dependency-graph.js +26 -16
  45. package/lighthouse-core/computed/processed-navigation.js +1 -1
  46. package/lighthouse-core/computed/processed-trace.js +1 -1
  47. package/lighthouse-core/computed/resource-summary.js +1 -1
  48. package/lighthouse-core/computed/screenshots.js +1 -1
  49. package/lighthouse-core/computed/speedline.js +1 -1
  50. package/lighthouse-core/computed/trace-of-tab.js +1 -1
  51. package/lighthouse-core/computed/unused-css.js +4 -4
  52. package/lighthouse-core/computed/unused-javascript-summary.js +4 -1
  53. package/lighthouse-core/computed/user-timings.js +1 -1
  54. package/lighthouse-core/computed/viewport-meta.js +1 -1
  55. package/lighthouse-core/config/default-config.js +1 -1
  56. package/lighthouse-core/fraggle-rock/gather/base-gatherer.js +1 -1
  57. package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +19 -8
  58. package/lighthouse-core/fraggle-rock/user-flow.js +9 -5
  59. package/lighthouse-core/gather/driver/execution-context.js +2 -0
  60. package/lighthouse-core/gather/driver/wait-for-condition.js +1 -1
  61. package/lighthouse-core/gather/gatherers/accessibility.js +1 -1
  62. package/lighthouse-core/gather/gatherers/anchor-elements.js +1 -1
  63. package/lighthouse-core/gather/gatherers/cache-contents.js +1 -1
  64. package/lighthouse-core/gather/gatherers/console-messages.js +1 -1
  65. package/lighthouse-core/gather/gatherers/dobetterweb/doctype.js +1 -1
  66. package/lighthouse-core/gather/gatherers/dobetterweb/domstats.js +1 -1
  67. package/lighthouse-core/gather/gatherers/dobetterweb/optimized-images.js +1 -1
  68. package/lighthouse-core/gather/gatherers/dobetterweb/password-inputs-with-prevented-paste.js +1 -1
  69. package/lighthouse-core/gather/gatherers/dobetterweb/response-compression.js +1 -1
  70. package/lighthouse-core/gather/gatherers/dobetterweb/tags-blocking-first-paint.js +2 -2
  71. package/lighthouse-core/gather/gatherers/form-elements.js +3 -3
  72. package/lighthouse-core/gather/gatherers/full-page-screenshot.js +1 -1
  73. package/lighthouse-core/gather/gatherers/global-listeners.js +1 -1
  74. package/lighthouse-core/gather/gatherers/iframe-elements.js +1 -1
  75. package/lighthouse-core/gather/gatherers/inspector-issues.js +1 -1
  76. package/lighthouse-core/gather/gatherers/js-usage.js +1 -1
  77. package/lighthouse-core/gather/gatherers/main-document-content.js +1 -1
  78. package/lighthouse-core/gather/gatherers/meta-elements.js +1 -1
  79. package/lighthouse-core/gather/gatherers/script-elements.js +1 -1
  80. package/lighthouse-core/gather/gatherers/seo/embedded-content.js +1 -1
  81. package/lighthouse-core/gather/gatherers/seo/font-size.js +8 -5
  82. package/lighthouse-core/gather/gatherers/seo/robots-txt.js +1 -1
  83. package/lighthouse-core/gather/gatherers/service-worker.js +1 -1
  84. package/lighthouse-core/gather/gatherers/source-maps.js +1 -1
  85. package/lighthouse-core/gather/gatherers/trace-elements.js +1 -1
  86. package/lighthouse-core/gather/gatherers/viewport-dimensions.js +1 -1
  87. package/lighthouse-core/lib/dependency-graph/base-node.js +8 -0
  88. package/lighthouse-core/lib/dependency-graph/simulator/network-analyzer.js +3 -2
  89. package/lighthouse-core/lib/dependency-graph/simulator/simulator.js +17 -0
  90. package/package.json +10 -9
  91. package/report/assets/styles.css +15 -12
  92. package/report/assets/templates.html +1 -1
  93. package/report/renderer/components.js +2 -2
  94. package/report/renderer/report-renderer.js +1 -1
  95. package/report/test/renderer/report-renderer-axe-test.js +48 -53
  96. package/report/test-assets/faux-psi-template.html +85 -26
  97. package/report/test-assets/faux-psi.js +44 -8
  98. package/shared/localization/locales/en-US.json +1 -1
  99. package/shared/localization/locales/en-XL.json +1 -1
  100. package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +1 -0
  101. package/types/config.d.ts +1 -0
  102. package/types/externs.d.ts +1 -0
  103. package/types/gatherer.d.ts +1 -0
  104. package/types/smokehouse.d.ts +2 -0
@@ -311,7 +311,7 @@ export class ReportRenderer {
311
311
  for (const category of Object.values(report.categories)) {
312
312
  const renderer = specificCategoryRenderers[category.id] || categoryRenderer;
313
313
  // .lh-category-wrapper is full-width and provides horizontal rules between categories.
314
- // .lh-category within has the max-width: var(--report-content-width);
314
+ // .lh-category within has the max-width: var(--report-content-max-width);
315
315
  const wrapper = renderer.dom.createChildOf(categories, 'div', 'lh-category-wrapper');
316
316
  wrapper.appendChild(renderer.render(
317
317
  category,
@@ -7,78 +7,73 @@
7
7
 
8
8
  /* eslint-env jest */
9
9
 
10
- import jsdom from 'jsdom';
11
- import {jest} from '@jest/globals';
10
+ import puppeteer from 'puppeteer';
12
11
 
13
- import {Util} from '../../renderer/util.js';
14
- import {DOM} from '../../renderer/dom.js';
15
- import {DetailsRenderer} from '../../renderer/details-renderer.js';
16
- import {CategoryRenderer} from '../../renderer/category-renderer.js';
17
- import {ReportRenderer} from '../../renderer/report-renderer.js';
18
- import sampleResultsOrig from '../../../lighthouse-core/test/results/sample_v2.json';
12
+ import sampleResults from '../../../lighthouse-core/test/results/sample_v2.json';
13
+ import reportGenerator from '../../generator/report-generator.js';
14
+ import axeLib from '../../../lighthouse-core/lib/axe.js';
19
15
 
20
16
  describe('ReportRendererAxe', () => {
21
17
  describe('with aXe', () => {
22
- let axe;
23
- let renderer;
24
- let sampleResults;
18
+ let browser;
25
19
 
26
20
  beforeAll(async () => {
27
- global.console.warn = jest.fn();
28
-
29
- const {window} = new jsdom.JSDOM();
30
- const dom = new DOM(window.document);
31
- const detailsRenderer = new DetailsRenderer(dom);
32
- const categoryRenderer = new CategoryRenderer(dom, detailsRenderer);
33
- renderer = new ReportRenderer(dom, categoryRenderer);
34
- sampleResults = Util.prepareReportResult(sampleResultsOrig);
35
-
36
- // Needed by axe-core
37
- // https://github.com/dequelabs/axe-core/blob/581c441c/doc/examples/jsdom/test/a11y.js#L24
38
- global.window = global.self = window;
39
- global.Node = global.self.Node;
40
- global.Element = global.self.Element;
41
-
42
- // axe-core must be imported after the global polyfills
43
- axe = (await import('axe-core')).default;
21
+ browser = await puppeteer.launch();
44
22
  });
45
23
 
46
- afterAll(() => {
47
- global.window = undefined;
48
- global.Node = undefined;
49
- global.Element = undefined;
24
+ afterAll(async () => {
25
+ await browser.close();
50
26
  });
51
27
 
52
28
  it('renders without axe violations', async () => {
53
- const container = renderer._dom.document().createElement('main');
54
- const output = renderer.renderReport(sampleResults, container);
55
-
56
- renderer._dom.document().body.appendChild(container);
29
+ const page = await browser.newPage();
30
+ const htmlReport = reportGenerator.generateReportHtml(sampleResults);
31
+ await page.setContent(htmlReport);
57
32
 
33
+ // Superset of Lighthouse's aXe config
58
34
  const config = {
35
+ runOnly: {
36
+ type: 'tag',
37
+ values: [
38
+ 'wcag2a',
39
+ 'wcag2aa',
40
+ ],
41
+ },
42
+ resultTypes: ['violations', 'inapplicable'],
59
43
  rules: {
60
- // Reports may have duplicate ids
61
- // https://github.com/GoogleChrome/lighthouse/issues/9432
62
- 'duplicate-id': {enabled: false},
63
- 'duplicate-id-aria': {enabled: false},
64
- 'landmark-no-duplicate-contentinfo': {enabled: false},
65
- // The following rules are disable for axe-core + jsdom compatibility
66
- // https://github.com/dequelabs/axe-core/tree/b573b1c1/doc/examples/jest_react#to-run-the-example
67
- 'color-contrast': {enabled: false},
68
- 'link-in-text-block': {enabled: false},
69
- // Report has empty links prior to i18n-ing.
70
- 'link-name': {enabled: false},
71
- // May not be a real issue. https://github.com/dequelabs/axe-core/issues/2958
72
- 'nested-interactive': {enabled: false},
44
+ 'tabindex': {enabled: true},
45
+ 'accesskeys': {enabled: true},
46
+ 'heading-order': {enabled: true},
47
+ 'meta-viewport': {enabled: true},
48
+ 'aria-treeitem-name': {enabled: true},
73
49
  },
74
50
  };
75
51
 
76
- const axeResults = await axe.run(output, config);
77
- expect(axeResults.violations).toEqual([]);
52
+ await page.evaluate(axeLib.source);
53
+ // eslint-disable-next-line no-undef
54
+ const axeResults = await page.evaluate(config => axe.run(config), config);
55
+
56
+ expect(axeResults.violations).toMatchObject([
57
+ // Color contrast failure only pops up if this pptr is run headfully.
58
+ // There are currently 27 problematic nodes, primarily audit display text and explanations.
59
+ // TODO: fix these failures, regardless.
60
+ // {
61
+ // id: 'color-contrast',
62
+ // },
63
+ {
64
+ id: 'duplicate-id',
65
+ nodes: [
66
+ // We use these audits in multiple categories. Makes sense.
67
+ {html: '<div class="lh-audit lh-audit--binary lh-audit--pass" id="viewport">'},
68
+ {html: '<div class="lh-audit lh-audit--binary lh-audit--fail" id="image-alt">'},
69
+ {html: '<div class="lh-audit lh-audit--binary lh-audit--pass" id="document-title">'},
70
+ ],
71
+ },
72
+ ]);
78
73
  },
79
- // This test takes 40s on fast hardware, and 50-60s on GHA (but can take longer).
74
+ // This test takes 10s on fast hardware, but can take longer in CI.
80
75
  // https://github.com/dequelabs/axe-core/tree/b573b1c1/doc/examples/jest_react#timeout-issues
81
- /* timeout= */ process.env.CI ? 200_000 : 60_000
76
+ /* timeout= */ 20_000
82
77
  );
83
78
  });
84
79
  });
@@ -43,10 +43,9 @@
43
43
  position: relative;
44
44
  display: inline-block;
45
45
  padding: 15px 55px 15px;
46
- border: 1px solid transparent;
47
- border-bottom: 0;
48
46
  cursor: pointer;
49
47
  font-weight: 600;
48
+ border-bottom: 3px solid transparent;
50
49
  }
51
50
 
52
51
  .tabset > label:hover {
@@ -59,51 +58,111 @@
59
58
  }
60
59
 
61
60
  .tabset > input:checked + label {
62
- border-color: #ccc;
63
- border-bottom: 1px solid #fff;
64
61
  margin-bottom: -1px;
65
62
  background: white;
63
+ border-bottom: 3px solid blue;
66
64
  }
67
65
 
68
66
  .tab-panel {
69
- border-top: 1px solid #ccc;
67
+ border: 1px solid #ccc;
68
+ padding: 24px;
69
+ row-gap: calc(8px*2);
70
+ border-radius: calc(8px/2);
70
71
  }
71
72
 
72
- body {
73
- padding: 30px;
74
- }
75
73
 
76
74
  .tabset {
77
- max-width: 65em;
78
- background: #eee;
75
+
79
76
  }
80
77
 
81
78
  .tab-panels {
82
79
  background: white;
83
80
  }
84
81
 
85
- /* extra styles */
86
82
  body {
87
- background: hsl(217deg 89% 61%);
83
+ height: 100%;
84
+ overflow: hidden;
85
+ -webkit-font-smoothing: antialiased;
86
+ color: rgba(0,0,0,0.87);
87
+ font-family: Roboto,RobotoDraft,Helvetica,Arial,sans-serif;
88
+ margin: 0;
89
+ text-size-adjust: 100%;
90
+ bottom: auto;
91
+ right: auto;
92
+ width: auto;
93
+ overflow: visible;
94
+ overflow-y: scroll;
95
+ overscroll-behavior: contain;
96
+ }
97
+ .page {
98
+ max-width: 960px;
99
+ width: calc(100% - 24px*2);
100
+ margin: auto;
101
+ padding: 24px;
102
+ padding-top: calc(24px*2);
103
+ min-width: calc(360px - 8px *2);
104
+ }
105
+ @media screen and (max-width: 768px) {
106
+ .page {
107
+ padding:8px;
108
+ width: calc(100% - 8px*2);
109
+ padding-top: calc(24px/2)
110
+ }
111
+ .tab-panel {
112
+ padding:unset;
113
+ border-width: 0;
114
+ }
115
+ }
116
+ .hrefbar {
117
+ background: hsl(210deg 17% 98%);
118
+ border: 1px solid hsl(0deg 0% 85%);
119
+ border-width: 1px 0;
120
+ padding: 4px;
121
+ }
122
+ button {
123
+ background-color: hsl(216deg 100% 50%);
124
+ border-radius: 4px;
125
+ color: white;
126
+ padding: 13px;
127
+ border: 0;
128
+ cursor: pointer;
129
+ float: right;
88
130
  }
131
+
89
132
  </style>
90
133
  </head>
91
134
  <body >
92
135
  <noscript>PSI requires JavaScript. Please enable.</noscript>
93
-
94
- <div class="tabset">
95
-
96
- <input type="radio" name="tabset" id="tab1" aria-controls="mobile" checked>
97
- <label for="tab1">Mobile</label>
98
-
99
- <input type="radio" name="tabset" id="tab2" aria-controls="desktop">
100
- <label for="tab2">Desktop</label>
101
-
102
- <div class="tab-panels">
103
- <section id="mobile" class="tab-panel"></section>
104
-
105
- <section id="desktop" class="tab-panel"></section>
106
-
136
+ <div class="page">
137
+ <button type=button>Reanalyze</button>
138
+ <div class="tabset">
139
+ <input type="radio" name="tabset" id="tab1" aria-controls="mobile" checked />
140
+ <label for="tab1">Mobile</label>
141
+
142
+ <input type="radio" name="tabset" id="tab2" aria-controls="desktop" />
143
+ <label for="tab2">Desktop</label>
144
+
145
+ <div class="tab-panels">
146
+ <section id="mobile" class="tab-panel">
147
+ <h2>Diagnose performance issues</h2>
148
+ <h4>
149
+ See detailed analysis and recommendations from loading your site in a simulated
150
+ environment.
151
+ </h4>
152
+ <div class="hrefbar">🔗 http://thisurl.com</div>
153
+ <div class="reportContainer"></div>
154
+ </section>
155
+
156
+ <section id="desktop" class="tab-panel">
157
+ <h2>Diagnose performance issues</h2>
158
+ <h4>
159
+ See detailed analysis and recommendations from loading your site in a simulated
160
+ environment.
161
+ </h4>
162
+ <div class="hrefbar">🔗 http://thisurl.com</div>
163
+ <div class="reportContainer"></div>
164
+ </section>
165
+ </div>
107
166
  </div>
108
167
  </div>
109
168
 
@@ -8,12 +8,22 @@
8
8
  /** @fileoverview This file exercises two LH reports within the same DOM. */
9
9
 
10
10
  /** @typedef {import('../clients/bundle.js')} lighthouseRenderer */
11
-
12
11
  /** @type {lighthouseRenderer} */
13
12
  // @ts-expect-error
14
13
  const lighthouseRenderer = window['report'];
15
14
 
15
+ const wait = (ms = 100) => new Promise(resolve => setTimeout(resolve, ms));
16
+
17
+
16
18
  (async function __initPsiReports__() {
19
+ renderLHReport();
20
+
21
+ document.querySelector('button')?.addEventListener('click', () => {
22
+ renderLHReport();
23
+ });
24
+ })();
25
+
26
+ async function renderLHReport() {
17
27
  // @ts-expect-error
18
28
  const mobileLHR = window.__LIGHTHOUSE_JSON__;
19
29
  const desktopLHR = JSON.parse(JSON.stringify(mobileLHR));
@@ -26,25 +36,49 @@ const lighthouseRenderer = window['report'];
26
36
  for (const [tabId, lhr] of Object.entries(lhrs)) {
27
37
  await distinguishLHR(lhr, tabId);
28
38
 
29
- const container = document.querySelector(`section#${tabId}`);
39
+ const container = document.querySelector(`section#${tabId} .reportContainer`);
30
40
  if (!container) throw new Error('Unexpected DOM. Bailing.');
31
41
 
32
42
  try {
43
+ container.textContent = 'Analyzing…';
44
+ await wait(500);
45
+ for (const el of container.childNodes) el.remove();
46
+
33
47
  const reportRootEl = lighthouseRenderer.renderReport(lhr, {
34
48
  omitTopbar: true,
35
49
  disableAutoDarkModeAndFireworks: true,
36
50
  });
37
51
  // TODO: display warnings if appropriate.
38
- for (const el of reportRootEl.querySelectorAll('.lh-warnings')) {
52
+ for (const el of reportRootEl.querySelectorAll('.lh-warnings--toplevel')) {
39
53
  el.setAttribute('hidden', 'true');
40
54
  }
55
+
56
+ // Move env block
57
+ const metaItemsEl = reportRootEl.querySelector('.lh-meta__items');
58
+ if (metaItemsEl) {
59
+ reportRootEl.querySelector('.lh-metrics-container')?.parentNode?.insertBefore(
60
+ metaItemsEl,
61
+ reportRootEl.querySelector('.lh-buttons')
62
+ );
63
+ }
64
+
41
65
  container.append(reportRootEl);
66
+
67
+ // Override some LH styles. (To find .lh-vars we must descend from reportRootEl's parent)
68
+ for (const el of container.querySelectorAll('article.lh-vars')) {
69
+ // Ensure these css var names are not stale.
70
+ el.style.setProperty('--report-content-max-width', '100%');
71
+ el.style.setProperty('--edge-gap-padding', '0');
72
+ }
73
+ for (const el of reportRootEl.querySelectorAll('footer.lh-footer')) {
74
+ el.style.display = 'none';
75
+ }
42
76
  } catch (e) {
43
77
  console.error(e);
44
78
  container.textContent = 'Error: LHR failed to render.';
45
79
  }
46
80
  }
47
- })();
81
+ }
48
82
 
49
83
 
50
84
  /**
@@ -59,13 +93,15 @@ async function distinguishLHR(lhr, tabId) {
59
93
  }
60
94
 
61
95
  const finalSSDetails = lhr.audits['final-screenshot'] && lhr.audits['final-screenshot'].details;
62
- if (!finalSSDetails || finalSSDetails.type !== 'screenshot') throw new Error();
63
- finalSSDetails.data = await decorateScreenshot(finalSSDetails.data, tabId);
96
+ if (finalSSDetails && finalSSDetails.type === 'screenshot') {
97
+ finalSSDetails.data = await decorateScreenshot(finalSSDetails.data, tabId);
98
+ }
64
99
 
65
100
  const fpSSDetails = lhr.audits['full-page-screenshot'] &&
66
101
  lhr.audits['full-page-screenshot'].details;
67
- if (!fpSSDetails || fpSSDetails.type !== 'full-page-screenshot') throw new Error();
68
- fpSSDetails.screenshot.data = await decorateScreenshot(fpSSDetails.screenshot.data, tabId);
102
+ if (fpSSDetails && fpSSDetails.type === 'full-page-screenshot') {
103
+ fpSSDetails.screenshot.data = await decorateScreenshot(fpSSDetails.screenshot.data, tabId);
104
+ }
69
105
  }
70
106
 
71
107
  /**
@@ -1218,7 +1218,7 @@
1218
1218
  "message": "Server Backend Latencies"
1219
1219
  },
1220
1220
  "lighthouse-core/audits/no-unload-listeners.js | description": {
1221
- "message": "The `unload` event does not fire reliably and listening for it can prevent browser optimizations like the Back-Forward Cache. Consider using the `pagehide` or `visibilitychange` events instead. [Learn more](https://developers.google.com/web/updates/2018/07/page-lifecycle-api#the-unload-event)"
1221
+ "message": "The `unload` event does not fire reliably and listening for it can prevent browser optimizations like the Back-Forward Cache. Use `pagehide` or `visibilitychange` events instead. [Learn more](https://web.dev/bfcache/#never-use-the-unload-event)"
1222
1222
  },
1223
1223
  "lighthouse-core/audits/no-unload-listeners.js | failureTitle": {
1224
1224
  "message": "Registers an `unload` listener"
@@ -1218,7 +1218,7 @@
1218
1218
  "message": "Ŝér̂v́êŕ B̂áĉḱêńd̂ Ĺât́êńĉíêś"
1219
1219
  },
1220
1220
  "lighthouse-core/audits/no-unload-listeners.js | description": {
1221
- "message": "T̂h́ê `unload` év̂én̂t́ d̂óêś n̂ót̂ f́îŕê ŕêĺîáb̂ĺŷ án̂d́ l̂íŝt́êńîńĝ f́ôŕ ît́ ĉán̂ ṕr̂év̂én̂t́ b̂ŕôẃŝér̂ óp̂t́îḿîźât́îón̂ś l̂ík̂é t̂h́ê B́âćk̂-F́ôŕŵár̂d́ Ĉáĉh́ê. Ćôńíd̂ úŝín̂ǵ t̂h́ê `pagehide` ó `visibilitychange` év̂én̂t́n̂śt̂éd́. [L̂éâŕôŕ](https://developers.google.com/web/updates/2018/07/page-lifecycle-api#the-unload-event)"
1221
+ "message": "T̂h́ê `unload` év̂én̂t́ d̂óêś n̂ót̂ f́îŕê ŕêĺîáb̂ĺŷ án̂d́ l̂íŝt́êńîńĝ f́ôŕ ît́ ĉán̂ ṕr̂év̂én̂t́ b̂ŕôẃŝér̂ óp̂t́îḿîźât́îón̂ś l̂ík̂é t̂h́ê B́âćk̂-F́ôŕŵár̂d́ Ĉáĉh́ê. Úŝé `pagehide` ôŕ `visibilitychange` êv́êńt̂ś îńŝt́êád̂. [Ĺêár̂ń m̂ór̂é](https://web.dev/bfcache/#never-use-the-unload-event)"
1222
1222
  },
1223
1223
  "lighthouse-core/audits/no-unload-listeners.js | failureTitle": {
1224
1224
  "message": "R̂éĝíŝt́êŕŝ án̂ `unload` ĺîśt̂én̂ér̂"
@@ -36,6 +36,7 @@ describe('issueAdded types', () => {
36
36
  Array [
37
37
  "attributionReportingIssueDetails",
38
38
  "blockedByResponseIssueDetails",
39
+ "clientHintIssueDetails",
39
40
  "contentSecurityPolicyIssueDetails",
40
41
  "corsIssueDetails",
41
42
  "deprecationIssueDetails",
package/types/config.d.ts CHANGED
@@ -65,6 +65,7 @@ declare module Config {
65
65
  gatherMode?: Gatherer.GatherMode;
66
66
  configPath?: string;
67
67
  settingsOverrides?: SharedFlagsSettings & Pick<LH.Flags, 'plugins'>;
68
+ skipAboutBlank?: boolean;
68
69
  }
69
70
 
70
71
  interface SharedPassNavigationJson {
@@ -20,6 +20,7 @@ declare global {
20
20
  // See: `executionContext.cacheNativesOnNewDocument`.
21
21
  __nativePromise: PromiseConstructor;
22
22
  __nativePerformance: Performance;
23
+ __nativeFetch: typeof fetch,
23
24
  __nativeURL: typeof URL;
24
25
  __ElementMatches: Element['matches'];
25
26
 
@@ -153,6 +153,7 @@ declare module Gatherer {
153
153
  interface Options {
154
154
  rtt?: number;
155
155
  throughput?: number;
156
+ observedThroughput: number;
156
157
  maximumConcurrentRequests?: number;
157
158
  cpuSlowdownMultiplier?: number;
158
159
  layoutTaskMultiplier?: number;
@@ -70,6 +70,8 @@ declare global {
70
70
  urlFilterRegex?: RegExp;
71
71
  skip?: (test: TestDfn, expectation: ExpectedRunnerResult) => string | false;
72
72
  modify?: (test: TestDfn, expectation: ExpectedRunnerResult) => void;
73
+ /** String of form `shardNumber/shardTotal`, e.g. `'1/4'`. */
74
+ shardArg: string | undefined;
73
75
  }
74
76
  }
75
77
  }