lighthouse 8.6.0-dev.20211021 → 8.6.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 (115) hide show
  1. package/dist/report/flow.js +13 -30
  2. package/dist/report/standalone.js +17 -17
  3. package/flow-report/assets/styles.css +30 -51
  4. package/flow-report/src/common.tsx +1 -1
  5. package/flow-report/src/header.tsx +2 -2
  6. package/flow-report/src/help-dialog.tsx +3 -3
  7. package/flow-report/src/i18n/i18n.tsx +13 -50
  8. package/flow-report/src/i18n/ui-strings.js +0 -48
  9. package/flow-report/src/icons.tsx +0 -7
  10. package/flow-report/src/sidebar/sidebar.tsx +6 -8
  11. package/flow-report/src/summary/category.tsx +18 -17
  12. package/flow-report/src/summary/summary.tsx +10 -10
  13. package/flow-report/src/topbar.tsx +5 -9
  14. package/flow-report/src/util.ts +5 -0
  15. package/flow-report/src/wrappers/category-score.tsx +3 -0
  16. package/flow-report/test/common-test.tsx +1 -1
  17. package/flow-report/test/summary/category-test.tsx +5 -9
  18. package/flow-report/test/summary/summary-test.tsx +1 -1
  19. package/flow-report/test/topbar-test.tsx +0 -1
  20. package/flow-report/tsconfig.json +0 -1
  21. package/jest.config.js +0 -1
  22. package/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js +1 -1
  23. package/lighthouse-core/audits/accessibility/axe-audit.js +1 -7
  24. package/lighthouse-core/audits/redirects-http.js +59 -0
  25. package/lighthouse-core/config/config-helpers.js +0 -1
  26. package/lighthouse-core/config/default-config.js +11 -0
  27. package/lighthouse-core/fraggle-rock/config/config.js +1 -1
  28. package/lighthouse-core/gather/gatherers/accessibility.js +0 -27
  29. package/lighthouse-core/gather/gatherers/http-redirect.js +46 -0
  30. package/lighthouse-core/lib/asset-saver.js +3 -3
  31. package/lighthouse-core/lib/i18n/i18n.js +8 -19
  32. package/lighthouse-core/lib/i18n/locales/en-US.ctc.json +6699 -0
  33. package/lighthouse-core/lib/i18n/locales/en-XL.ctc.json +6672 -0
  34. package/lighthouse-core/util-commonjs.js +37 -25
  35. package/package.json +4 -8
  36. package/readme.md +3 -3
  37. package/report/assets/styles.css +28 -157
  38. package/report/assets/templates.html +47 -2
  39. package/report/clients/psi.js +158 -0
  40. package/report/renderer/category-renderer.js +1 -30
  41. package/report/renderer/components.js +34 -16
  42. package/report/renderer/performance-category-renderer.js +10 -5
  43. package/report/renderer/report-renderer.js +33 -56
  44. package/report/renderer/util.js +37 -25
  45. package/report/test/clients/psi-test.js +143 -0
  46. package/report/test/renderer/category-renderer-test.js +1 -5
  47. package/report/test/renderer/i18n-test.js +7 -0
  48. package/report/test/renderer/performance-category-renderer-test.js +1 -1
  49. package/report/test/renderer/pwa-category-renderer-test.js +2 -2
  50. package/report/test/renderer/report-renderer-axe-test.js +10 -5
  51. package/report/test/renderer/report-renderer-test.js +11 -9
  52. package/report/test-assets/faux-psi-template.html +4 -1
  53. package/report/test-assets/faux-psi.js +16 -39
  54. package/shared/localization/format.js +17 -50
  55. package/shared/localization/locales/ar-XB.json +24 -0
  56. package/shared/localization/locales/ar.json +24 -0
  57. package/shared/localization/locales/bg.json +24 -0
  58. package/shared/localization/locales/ca.json +24 -0
  59. package/shared/localization/locales/cs.json +24 -0
  60. package/shared/localization/locales/da.json +24 -0
  61. package/shared/localization/locales/de.json +24 -0
  62. package/shared/localization/locales/el.json +24 -0
  63. package/shared/localization/locales/en-GB.json +24 -0
  64. package/shared/localization/locales/en-US.ctc.json +6877 -0
  65. package/shared/localization/locales/en-US.json +23 -26
  66. package/shared/localization/locales/en-XA.json +24 -0
  67. package/shared/localization/locales/en-XL.ctc.json +6852 -0
  68. package/shared/localization/locales/en-XL.json +23 -26
  69. package/shared/localization/locales/es-419.json +24 -0
  70. package/shared/localization/locales/es.json +24 -0
  71. package/shared/localization/locales/fi.json +24 -0
  72. package/shared/localization/locales/fil.json +24 -0
  73. package/shared/localization/locales/fr.json +24 -0
  74. package/shared/localization/locales/he.json +24 -0
  75. package/shared/localization/locales/hi.json +24 -0
  76. package/shared/localization/locales/hr.json +24 -0
  77. package/shared/localization/locales/hu.json +24 -0
  78. package/shared/localization/locales/id.json +24 -0
  79. package/shared/localization/locales/it.json +24 -0
  80. package/shared/localization/locales/ja.json +24 -0
  81. package/shared/localization/locales/ko.json +24 -0
  82. package/shared/localization/locales/lt.json +24 -0
  83. package/shared/localization/locales/lv.json +24 -0
  84. package/shared/localization/locales/nl.json +24 -0
  85. package/shared/localization/locales/no.json +24 -0
  86. package/shared/localization/locales/pl.json +24 -0
  87. package/shared/localization/locales/pt-PT.json +24 -0
  88. package/shared/localization/locales/pt.json +24 -0
  89. package/shared/localization/locales/ro.json +24 -0
  90. package/shared/localization/locales/ru.json +24 -0
  91. package/shared/localization/locales/sk.json +24 -0
  92. package/shared/localization/locales/sl.json +24 -0
  93. package/shared/localization/locales/sr-Latn.json +24 -0
  94. package/shared/localization/locales/sr.json +24 -0
  95. package/shared/localization/locales/sv.json +24 -0
  96. package/shared/localization/locales/ta.json +24 -0
  97. package/shared/localization/locales/te.json +24 -0
  98. package/shared/localization/locales/th.json +24 -0
  99. package/shared/localization/locales/tr.json +24 -0
  100. package/shared/localization/locales/uk.json +24 -0
  101. package/shared/localization/locales/vi.json +24 -0
  102. package/shared/localization/locales/zh-HK.json +24 -0
  103. package/shared/localization/locales/zh-TW.json +24 -0
  104. package/shared/localization/locales/zh.json +24 -0
  105. package/shared/localization/locales.js +0 -6
  106. package/shared/test/localization/format-test.js +9 -45
  107. package/shared/test/localization/swap-locale-test.js +12 -0
  108. package/third-party/download-content-shell/download-content-shell.js +2 -2
  109. package/third-party/download-content-shell/utils.js +24 -0
  110. package/tsconfig.json +1 -0
  111. package/types/artifacts.d.ts +3 -1
  112. package/types/enquirer.d.ts +1 -3
  113. package/types/node.d.ts +5 -5
  114. package/flow-report/test/wrappers/category-score-test.tsx +0 -87
  115. package/report/test/clients/bundle-test.js +0 -62
@@ -79,6 +79,11 @@ export function useFlowResult(): LH.FlowResult {
79
79
  return flowResult;
80
80
  }
81
81
 
82
+ export function useLocale(): LH.Locale {
83
+ const flowResult = useFlowResult();
84
+ return flowResult.steps[0].lhr.configSettings.locale;
85
+ }
86
+
82
87
  export function useHashParam(param: string) {
83
88
  const [paramValue, setParamValue] = useState(getHashParam(param));
84
89
 
@@ -23,6 +23,9 @@ export const CategoryScore: FunctionComponent<{
23
23
  // Category label is displayed in the navigation header.
24
24
  const label = el.querySelector('.lh-gauge__label,.lh-fraction__label');
25
25
  if (label) label.remove();
26
+ // Background is displayed in individual reports, but not on the summary page.
27
+ const bg = el.querySelector('.lh-fraction__background');
28
+ if (bg) bg.remove();
26
29
 
27
30
  if (ref.current) ref.current.append(el);
28
31
  return () => {
@@ -82,7 +82,7 @@ describe('FlowStepThumbnail', () => {
82
82
 
83
83
  expect(thumbnail.src).toContain('frame1');
84
84
  await act(() => {
85
- jest.advanceTimersByTime(501);
85
+ jest.advanceTimersByTime(251);
86
86
  });
87
87
  expect(thumbnail.src).toContain('frame2');
88
88
  });
@@ -44,8 +44,7 @@ describe('SummaryTooltip', () => {
44
44
 
45
45
  expect(root.getByText('Average')).toBeTruthy();
46
46
  expect(() => root.getByText(/^[0-9]+$/)).toThrow();
47
- expect(root.getByText('2 audits passed')).toBeTruthy();
48
- expect(root.getByText('3 passable audits')).toBeTruthy();
47
+ expect(root.getByText('2 audits passed / 3 passable audits')).toBeTruthy();
49
48
  });
50
49
 
51
50
  it('renders tooltip without rating', async () => {
@@ -66,8 +65,7 @@ describe('SummaryTooltip', () => {
66
65
 
67
66
  expect(() => root.getByText(/^(Average|Good|Poor)$/)).toThrow();
68
67
  expect(() => root.getByText(/^[0-9]+$/)).toThrow();
69
- expect(root.getByText('2 audits passed')).toBeTruthy();
70
- expect(root.getByText('3 passable audits')).toBeTruthy();
68
+ expect(root.getByText('2 audits passed / 3 passable audits')).toBeTruthy();
71
69
  });
72
70
 
73
71
  it('renders scored category tooltip with score', async () => {
@@ -88,8 +86,7 @@ describe('SummaryTooltip', () => {
88
86
 
89
87
  expect(root.getByText('Good')).toBeTruthy();
90
88
  expect(root.getByText('100')).toBeTruthy();
91
- expect(root.getByText('2 audits passed')).toBeTruthy();
92
- expect(root.getByText('3 passable audits')).toBeTruthy();
89
+ expect(root.getByText('2 audits passed / 3 passable audits')).toBeTruthy();
93
90
  });
94
91
 
95
92
  it('renders informative audit count if any', async () => {
@@ -110,8 +107,7 @@ describe('SummaryTooltip', () => {
110
107
 
111
108
  expect(root.getByText('Good')).toBeTruthy();
112
109
  expect(root.getByText('100')).toBeTruthy();
113
- expect(root.getByText('2 audits passed')).toBeTruthy();
114
- expect(root.getByText('2 passable audits')).toBeTruthy();
115
- expect(root.getByText('1 informative audit')).toBeTruthy();
110
+ expect(root.getByText('2 audits passed / 2 passable audits')).toBeTruthy();
111
+ expect(root.getByText('1 informative audits')).toBeTruthy();
116
112
  });
117
113
  });
@@ -34,7 +34,7 @@ describe('SummaryHeader', () => {
34
34
  const lhrCounts = root.getByText(/·/);
35
35
  expect(root.getByText('Summary')).toBeTruthy();
36
36
  expect(lhrCounts.textContent).toEqual(
37
- '2 navigation reports · 1 timespan report · 1 snapshot report'
37
+ '2 navigation reports · 1 timespan reports · 1 snapshot reports'
38
38
  );
39
39
  });
40
40
  });
@@ -18,7 +18,6 @@ const flowResult = {
18
18
  steps: [{lhr: {
19
19
  fetchTime: '2021-09-14T22:24:22.462Z',
20
20
  configSettings: {locale: 'en-US'},
21
- i18n: {rendererFormattedStrings: {}},
22
21
  }}],
23
22
  } as any;
24
23
 
@@ -14,7 +14,6 @@
14
14
  "references": [
15
15
  {"path": "../types/lhr/"},
16
16
  {"path": "../report"},
17
- {"path": "../shared"},
18
17
  ],
19
18
  "include": [
20
19
  "**/*.js",
package/jest.config.js CHANGED
@@ -18,7 +18,6 @@ module.exports = {
18
18
  '**/third-party/**/*-test.js',
19
19
  '**/clients/test/**/*-test.js',
20
20
  '**/shared/**/*-test.js',
21
- '**/build/**/*-test.js',
22
21
  ],
23
22
  transform: {},
24
23
  prettierPath: null,
@@ -39,7 +39,7 @@ async function runLighthouse(url, configJson, testRunnerOptions = {}) {
39
39
  const tmpPath = await fs.mkdtemp(`${tmpDir}/smokehouse-`);
40
40
  return internalRun(url, tmpPath, configJson, testRunnerOptions)
41
41
  // Wait for internalRun() before removing scratch directory.
42
- .finally(() => !isDebug && fs.rm(tmpPath, {recursive: true, force: true}));
42
+ .finally(() => !isDebug && fs.rmdir(tmpPath, {recursive: true}));
43
43
  }
44
44
 
45
45
  /**
@@ -79,18 +79,12 @@ class AxeAudit extends Audit {
79
79
  ...Audit.makeNodeItem(axeNode.node),
80
80
  explanation: axeNode.failureSummary,
81
81
  },
82
- subItems: axeNode.relatedNodes.length ? {
83
- type: 'subitems',
84
- items: axeNode.relatedNodes.map(node => ({relatedNode: Audit.makeNodeItem(node)})),
85
- } : undefined,
86
82
  }));
87
83
  }
88
84
 
89
85
  /** @type {LH.Audit.Details.Table['headings']} */
90
86
  const headings = [
91
- /* eslint-disable max-len */
92
- {key: 'node', itemType: 'node', subItemsHeading: {key: 'relatedNode', itemType: 'node'}, text: str_(UIStrings.failingElementsHeader)},
93
- /* eslint-enable max-len */
87
+ {key: 'node', itemType: 'node', text: str_(UIStrings.failingElementsHeader)},
94
88
  ];
95
89
 
96
90
  /** @type {LH.Audit.Details.DebugData|undefined} */
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @license Copyright 2016 The Lighthouse Authors. All Rights Reserved.
3
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
5
+ */
6
+ 'use strict';
7
+
8
+ const Audit = require('./audit.js');
9
+ const i18n = require('../lib/i18n/i18n.js');
10
+ const URL = require('../lib/url-shim.js');
11
+
12
+ const UIStrings = {
13
+ /** Title of a Lighthouse audit that provides detail on HTTP to HTTPS redirects. This descriptive title is shown to users when HTTP traffic is redirected to HTTPS. */
14
+ title: 'Redirects HTTP traffic to HTTPS',
15
+ /** Title of a Lighthouse audit that provides detail on HTTP to HTTPS redirects. This descriptive title is shown to users when HTTP traffic is not redirected to HTTPS. */
16
+ failureTitle: 'Does not redirect HTTP traffic to HTTPS',
17
+ /** Description of a Lighthouse audit that tells the user why they should direct HTTP traffic to HTTPS. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
18
+ description: 'If you\'ve already set up HTTPS, make sure that you redirect all HTTP ' +
19
+ 'traffic to HTTPS in order to enable secure web features for all your users. [Learn more](https://web.dev/redirects-http/).',
20
+ };
21
+
22
+ const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
23
+
24
+ class RedirectsHTTP extends Audit {
25
+ /**
26
+ * @return {LH.Audit.Meta}
27
+ */
28
+ static get meta() {
29
+ return {
30
+ id: 'redirects-http',
31
+ title: str_(UIStrings.title),
32
+ failureTitle: str_(UIStrings.failureTitle),
33
+ description: str_(UIStrings.description),
34
+ requiredArtifacts: ['HTTPRedirect', 'URL'],
35
+ };
36
+ }
37
+
38
+ /**
39
+ * @param {LH.Artifacts} artifacts
40
+ * @return {LH.Audit.Product}
41
+ */
42
+ static audit(artifacts) {
43
+ // Redirecting HTTP to HTTPS makes no sense on localhost
44
+ const url = new URL(artifacts.URL.finalUrl);
45
+ if (URL.isLikeLocalhost(url.hostname)) {
46
+ return {
47
+ score: 1,
48
+ notApplicable: true,
49
+ };
50
+ }
51
+
52
+ return {
53
+ score: Number(artifacts.HTTPRedirect.value),
54
+ };
55
+ }
56
+ }
57
+
58
+ module.exports = RedirectsHTTP;
59
+ module.exports.UIStrings = UIStrings;
@@ -283,7 +283,6 @@ function resolveSettings(settingsJson = {}, overrides = undefined) {
283
283
  // If a locale is requested in flags or settings, use it. A typical CLI run will not have one,
284
284
  // however `lookupLocale` will always determine which of our supported locales to use (falling
285
285
  // back if necessary).
286
- // TODO: could do more work to sniff out the user's locale
287
286
  const locale = i18n.lookupLocale((overrides && overrides.locale) || settingsJson.locale);
288
287
 
289
288
  // Fill in missing settings with defaults
@@ -171,9 +171,19 @@ const defaultConfig = {
171
171
  gatherers: [
172
172
  'service-worker',
173
173
  ],
174
+ },
175
+ {
176
+ passName: 'redirectPass',
177
+ loadFailureMode: 'warn',
178
+ // Speed up the redirect pass by blocking stylesheets, fonts, and images
179
+ blockedUrlPatterns: ['*.css', '*.jpg', '*.jpeg', '*.png', '*.gif', '*.svg', '*.ttf', '*.woff', '*.woff2'],
180
+ gatherers: [
181
+ 'http-redirect',
182
+ ],
174
183
  }],
175
184
  audits: [
176
185
  'is-on-https',
186
+ 'redirects-http',
177
187
  'service-worker',
178
188
  'viewport',
179
189
  'metrics/first-contentful-paint',
@@ -607,6 +617,7 @@ const defaultConfig = {
607
617
  {id: 'installable-manifest', weight: 2, group: 'pwa-installable'},
608
618
  // PWA Optimized
609
619
  {id: 'service-worker', weight: 1, group: 'pwa-optimized'},
620
+ {id: 'redirects-http', weight: 2, group: 'pwa-optimized'},
610
621
  {id: 'splash-screen', weight: 1, group: 'pwa-optimized'},
611
622
  {id: 'themed-omnibox', weight: 1, group: 'pwa-optimized'},
612
623
  {id: 'content-width', weight: 1, group: 'pwa-optimized'},
@@ -140,7 +140,7 @@ function resolveArtifactsToDefns(artifacts, configDir) {
140
140
 
141
141
  const gatherer = resolveGathererToDefn(gathererJson, coreGathererList, configDir);
142
142
  if (!isFRGathererDefn(gatherer)) {
143
- throw new Error(`${gatherer.instance.name} gatherer does not have a Fraggle Rock meta obj`);
143
+ throw new Error(`${gatherer.instance.name} gatherer does not support Fraggle Rock`);
144
144
  }
145
145
 
146
146
  /** @type {LH.Config.AnyArtifactDefn} */
@@ -87,37 +87,10 @@ function createAxeRuleResultArtifact(result) {
87
87
  // @ts-expect-error - getNodeDetails put into scope via stringification
88
88
  const nodeDetails = getNodeDetails(/** @type {HTMLElement} */ (element));
89
89
 
90
- /** @type {Set<HTMLElement>} */
91
- const relatedNodeElements = new Set();
92
- /** @param {import('axe-core/axe').ImpactValue} impact */
93
- const impactToNumber =
94
- (impact) => [null, 'minor', 'moderate', 'serious', 'critical'].indexOf(impact);
95
- const checkResults = [...node.any, ...node.all, ...node.none]
96
- // @ts-expect-error CheckResult.impact is a string, even though ImpactValue is a thing.
97
- .sort((a, b) => impactToNumber(b.impact) - impactToNumber(a.impact));
98
- for (const checkResult of checkResults) {
99
- for (const relatedNode of checkResult.relatedNodes || []) {
100
- /** @type {HTMLElement} */
101
- // @ts-expect-error - should always exist, just being cautious.
102
- const relatedElement = relatedNode.element;
103
-
104
- // Prevent overloading the report with way too many nodes.
105
- if (relatedNodeElements.size >= 3) break;
106
- // Should always exist, just being cautious.
107
- if (!relatedElement) continue;
108
- if (element === relatedElement) continue;
109
-
110
- relatedNodeElements.add(relatedElement);
111
- }
112
- }
113
- // @ts-expect-error - getNodeDetails put into scope via stringification
114
- const relatedNodeDetails = [...relatedNodeElements].map(getNodeDetails);
115
-
116
90
  return {
117
91
  target,
118
92
  failureSummary,
119
93
  node: nodeDetails,
120
- relatedNodes: relatedNodeDetails,
121
94
  };
122
95
  });
123
96
 
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @license Copyright 2016 The Lighthouse Authors. All Rights Reserved.
3
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
5
+ */
6
+ 'use strict';
7
+
8
+ const Gatherer = require('./gatherer.js');
9
+
10
+ /**
11
+ * This gatherer changes the options.url so that its pass loads the http page.
12
+ * After load it detects if its on a crypographic scheme.
13
+ * TODO: Instead of abusing a loadPage pass for this test, it could likely just do an XHR instead
14
+ */
15
+ class HTTPRedirect extends Gatherer {
16
+ constructor() {
17
+ super();
18
+ this._preRedirectURL = '';
19
+ }
20
+
21
+ /**
22
+ * @param {LH.Gatherer.PassContext} passContext
23
+ */
24
+ beforePass(passContext) {
25
+ this._preRedirectURL = passContext.url;
26
+ passContext.url = this._preRedirectURL.replace(/^https/, 'http');
27
+ }
28
+
29
+ /**
30
+ * @param {LH.Gatherer.PassContext} passContext
31
+ * @return {Promise<LH.Artifacts['HTTPRedirect']>}
32
+ */
33
+ async afterPass(passContext) {
34
+ // Reset the options.
35
+ passContext.url = this._preRedirectURL;
36
+
37
+ const executionContext = passContext.driver.executionContext;
38
+ const expression = `new URL(window.location).protocol === 'https:'`;
39
+ const isHttps = await executionContext.evaluateAsync(expression, {useIsolation: true});
40
+ return {
41
+ value: isHttps,
42
+ };
43
+ }
44
+ }
45
+
46
+ module.exports = HTTPRedirect;
@@ -235,9 +235,9 @@ async function saveTrace(traceData, traceFilename) {
235
235
  const traceIter = traceJsonGenerator(traceData);
236
236
  const writeStream = fs.createWriteStream(traceFilename);
237
237
 
238
- // TODO: Can remove promisify(pipeline) in Node 15.
238
+ // TODO: Can remove Readable.from() in Node 13, promisify(pipeline) in Node 15.
239
239
  // https://nodejs.org/api/stream.html#stream_stream_pipeline_streams_callback
240
- return pipeline(traceIter, writeStream);
240
+ return pipeline(stream.Readable.from(traceIter), writeStream);
241
241
  }
242
242
 
243
243
  /**
@@ -250,7 +250,7 @@ function saveDevtoolsLog(devtoolsLog, devtoolLogFilename) {
250
250
  const logIter = arrayOfObjectsJsonGenerator(devtoolsLog);
251
251
  const writeStream = fs.createWriteStream(devtoolLogFilename);
252
252
 
253
- return pipeline(logIter, writeStream);
253
+ return pipeline(stream.Readable.from(logIter), writeStream);
254
254
  }
255
255
 
256
256
  /**
@@ -12,11 +12,9 @@ const lookupClosestLocale = require('lookup-closest-locale');
12
12
  const {getAvailableLocales} = require('../../../shared/localization/format.js');
13
13
  const log = require('lighthouse-logger');
14
14
  const {LH_ROOT} = require('../../../root.js');
15
- const {
16
- isIcuMessage,
17
- formatMessage,
18
- DEFAULT_LOCALE,
19
- } = require('../../../shared/localization/format.js');
15
+ const {isIcuMessage, _formatMessage} = require('../../../shared/localization/format.js');
16
+
17
+ const DEFAULT_LOCALE = 'en';
20
18
 
21
19
  const UIStrings = {
22
20
  /** Used to show the duration in milliseconds that something lasted. The `{timeInMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 63 ms) */
@@ -120,32 +118,23 @@ const UIStrings = {
120
118
  * - supported locales in Intl formatters
121
119
  *
122
120
  * If `locale` isn't provided or one could not be found, DEFAULT_LOCALE is returned.
123
- *
124
- * By default any of the locales Lighthouse has strings for can be returned, but this
125
- * can be overriden with `possibleLocales`, useful e.g. when Lighthouse is bundled and
126
- * only DEFAULT_LOCALE is available, but `possibleLocales` can be used to select a
127
- * locale available to be downloaded on demand.
128
121
  * @param {string|string[]=} locales
129
- * @param {Array<string>=} possibleLocales
130
122
  * @return {LH.Locale}
131
123
  */
132
- function lookupLocale(locales, possibleLocales) {
133
- // TODO: lookupLocale may need to be split into two functions, one that canonicalizes
134
- // locales and one that looks up the best locale filename for a given locale.
135
- // e.g. `en-IE` is canonical, but uses `en-GB.json`. See TODO in locales.js
136
-
124
+ function lookupLocale(locales) {
125
+ // If Node was built with `--with-intl=none`, `Intl` won't exist.
137
126
  if (typeof Intl !== 'object') {
138
- // If Node was built with `--with-intl=none`, `Intl` won't exist.
139
127
  throw new Error('Lighthouse must be run in Node with `Intl` support. See https://nodejs.org/api/intl.html for help');
140
128
  }
141
129
 
130
+ // TODO: could do more work to sniff out the user's locale
142
131
  const canonicalLocales = Intl.getCanonicalLocales(locales);
143
132
 
144
133
  // Filter by what's available in this runtime.
145
134
  const availableLocales = Intl.NumberFormat.supportedLocalesOf(canonicalLocales);
146
135
 
147
136
  // Get available locales and transform into object to match `lookupClosestLocale`'s API.
148
- const localesWithMessages = possibleLocales || getAvailableLocales();
137
+ const localesWithMessages = getAvailableLocales();
149
138
  const localesWithmessagesObj = /** @type {Record<LH.Locale, LhlMessages>} */ (
150
139
  Object.fromEntries(localesWithMessages.map(l => [l, {}])));
151
140
 
@@ -193,7 +182,7 @@ function createIcuMessageFn(filename, fileStrings) {
193
182
  return {
194
183
  i18nId,
195
184
  values,
196
- formattedDefault: formatMessage(message, values, DEFAULT_LOCALE),
185
+ formattedDefault: _formatMessage(message, values, DEFAULT_LOCALE),
197
186
  };
198
187
  };
199
188