lighthouse 8.6.0-dev.20211102 → 8.6.0-dev.20211103

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/dist/report/flow.js +8 -8
  2. package/dist/report/standalone.js +40 -34
  3. package/flow-report/assets/standalone-flow-template.html +3 -2
  4. package/flow-report/src/icons.tsx +9 -0
  5. package/flow-report/src/sidebar/sidebar.tsx +18 -5
  6. package/flow-report/src/wrappers/report-renderer.tsx +1 -0
  7. package/flow-report/src/wrappers/report.tsx +2 -3
  8. package/flow-report/standalone-flow.tsx +4 -3
  9. package/flow-report/test/sidebar/sidebar-test.tsx +43 -1
  10. package/package.json +1 -1
  11. package/report/assets/standalone-template.html +2 -3
  12. package/report/assets/styles.css +1 -1
  13. package/report/clients/bundle.js +1 -0
  14. package/report/clients/standalone.js +6 -13
  15. package/report/renderer/api.js +32 -0
  16. package/report/renderer/category-renderer.js +1 -1
  17. package/report/renderer/components.js +26 -26
  18. package/report/renderer/dom.js +16 -1
  19. package/report/renderer/drop-down-menu.js +2 -2
  20. package/report/renderer/element-screenshot-renderer.js +6 -6
  21. package/report/renderer/features-util.js +1 -1
  22. package/report/renderer/report-renderer.js +32 -9
  23. package/report/renderer/report-ui-features.js +34 -30
  24. package/report/renderer/swap-locale-feature.js +3 -3
  25. package/report/renderer/topbar-features.js +19 -21
  26. package/report/test/clients/bundle-test.js +3 -0
  27. package/report/test/renderer/report-renderer-axe-test.js +5 -2
  28. package/report/test/renderer/report-renderer-test.js +13 -10
  29. package/report/test/renderer/report-ui-features-test.js +4 -1
  30. package/report/test-assets/faux-psi-template.html +2 -7
  31. package/report/test-assets/faux-psi.js +15 -34
  32. package/report/types/html-renderer.d.ts +2 -0
  33. package/report/types/report-renderer.d.ts +23 -0
@@ -23,11 +23,12 @@ limitations under the License.
23
23
  <title>Lighthouse Flow Report</title>
24
24
  <style>/*%%LIGHTHOUSE_CSS%%*/</style>
25
25
  <style>/*%%LIGHTHOUSE_FLOW_CSS%%*/</style>
26
+ <style>body {margin: 0}</style>
26
27
  </head>
27
- <body class="flow-vars lh-root lh-vars">
28
+ <body>
28
29
  <noscript>Lighthouse report requires JavaScript. Please enable.</noscript>
29
30
 
30
- <main><!-- report populated here --></main>
31
+ <main class="flow-vars lh-root lh-vars"><!-- report populated here --></main>
31
32
 
32
33
  <script>window.__LIGHTHOUSE_FLOW_JSON__ = %%LIGHTHOUSE_FLOW_JSON%%;</script>
33
34
  <script>%%LIGHTHOUSE_FLOW_JAVASCRIPT%%
@@ -104,6 +104,14 @@ const EnvIcon: FunctionComponent = () => {
104
104
  );
105
105
  };
106
106
 
107
+ const NetworkIcon: FunctionComponent = () => {
108
+ return (
109
+ <svg width="16" height="11" viewBox="0 0 16 11" fill="none" role="img">
110
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M0.666687 3.26663L2.00002 4.59997C3.92002 2.67997 6.52669 1.87997 9.02002 2.18663L9.81335 0.399966C6.59335 -0.173367 3.16002 0.779966 0.666687 3.26663ZM10.6 0.599966C10.4867 0.599966 10.3867 0.659966 10.3267 0.753299L10.28 0.853299L6.82669 8.61996C6.72002 8.8133 6.65335 9.02663 6.65335 9.25996C6.65335 9.99996 7.25335 10.6 7.99335 10.6C8.63335 10.6 9.17335 10.1466 9.30002 9.53996L9.30669 9.51997L10.9334 0.933299C10.9334 0.746633 10.7867 0.599966 10.6 0.599966ZM15.3334 3.26663L14 4.59997C13.1867 3.78663 12.2534 3.17997 11.2534 2.76663L11.6067 0.886633C12.9667 1.38663 14.24 2.1733 15.3334 3.26663ZM11.3334 7.26663L12.6667 5.9333C12.1334 5.39997 11.5334 4.98663 10.8934 4.6733L10.5267 6.61997C10.8067 6.79997 11.08 7.0133 11.3334 7.26663ZM4.66669 7.26663L3.33335 5.9333C4.67335 4.5933 6.45335 3.95997 8.20669 4.0133L7.35335 5.9333C6.37335 6.0733 5.42002 6.5133 4.66669 7.26663Z" fill="currentColor"/>
111
+ </svg>
112
+ );
113
+ };
114
+
107
115
  const CpuIcon: FunctionComponent = () => {
108
116
  return (
109
117
  <svg width="16" height="16" viewBox="0 0 16 16" fill="none" role="img">
@@ -137,6 +145,7 @@ export {
137
145
  SnapshotIcon,
138
146
  CloseIcon,
139
147
  EnvIcon,
148
+ NetworkIcon,
140
149
  CpuIcon,
141
150
  HamburgerIcon,
142
151
  InfoIcon,
@@ -6,9 +6,10 @@
6
6
 
7
7
  import {FunctionComponent} from 'preact';
8
8
 
9
+ import {Util} from '../../../report/renderer/util';
9
10
  import {Separator} from '../common';
10
11
  import {useI18n, useLocalizedStrings} from '../i18n/i18n';
11
- import {CpuIcon, EnvIcon, SummaryIcon} from '../icons';
12
+ import {CpuIcon, EnvIcon, NetworkIcon, SummaryIcon} from '../icons';
12
13
  import {classNames, useHashState, useFlowResult} from '../util';
13
14
  import {SidebarFlow} from './flow';
14
15
 
@@ -32,8 +33,10 @@ const SidebarSummary: FunctionComponent = () => {
32
33
  );
33
34
  };
34
35
 
35
- const SidebarRuntimeSettings: FunctionComponent<{settings: LH.ConfigSettings}> = ({settings}) => {
36
+ const SidebarRuntimeSettings: FunctionComponent<{settings: LH.ConfigSettings}> =
37
+ ({settings}) => {
36
38
  const strings = useLocalizedStrings();
39
+ const env = Util.getEmulationDescriptions(settings);
37
40
 
38
41
  return (
39
42
  <div className="SidebarRuntimeSettings">
@@ -42,9 +45,18 @@ const SidebarRuntimeSettings: FunctionComponent<{settings: LH.ConfigSettings}> =
42
45
  <EnvIcon/>
43
46
  </div>
44
47
  {
45
- settings.formFactor === 'desktop' ?
46
- strings.runtimeDesktopEmulation :
47
- strings.runtimeMobileEmulation
48
+ env.deviceEmulation
49
+ }
50
+ </div>
51
+ <div
52
+ className="SidebarRuntimeSettings__item"
53
+ title={strings.runtimeSettingsNetworkThrottling}
54
+ >
55
+ <div className="SidebarRuntimeSettings__item--icon">
56
+ <NetworkIcon/>
57
+ </div>
58
+ {
59
+ env.summary
48
60
  }
49
61
  </div>
50
62
  <div className="SidebarRuntimeSettings__item" title={strings.runtimeSettingsCPUThrottling}>
@@ -87,6 +99,7 @@ const Sidebar: FunctionComponent = () => {
87
99
 
88
100
  export {
89
101
  SidebarSummary,
102
+ SidebarRuntimeSettings,
90
103
  SidebarHeader,
91
104
  Sidebar,
92
105
  };
@@ -29,6 +29,7 @@ function useReportRenderer() {
29
29
 
30
30
  const ReportRendererProvider: FunctionComponent = ({children}) => {
31
31
  const globals = useMemo(() => {
32
+ // @ts-expect-error Still using legacy
32
33
  const dom = new DOM(document);
33
34
  const detailsRenderer = new DetailsRenderer(dom);
34
35
  const categoryRenderer = new CategoryRenderer(dom, detailsRenderer);
@@ -50,11 +50,10 @@ const Report: FunctionComponent<{hashState: LH.FlowResult.HashState}> =
50
50
  convertChildAnchors(ref.current, hashState.index);
51
51
  const fullPageScreenshot = getFullPageScreenshot(hashState.currentLhr);
52
52
  if (fullPageScreenshot) {
53
- const container = dom.find('.lh-container', ref.current);
54
53
  ElementScreenshotRenderer.installOverlayFeature({
55
54
  dom,
56
- reportEl: container,
57
- overlayContainerEl: container,
55
+ rootEl: ref.current,
56
+ overlayContainerEl: ref.current,
58
57
  fullPageScreenshot,
59
58
  });
60
59
  }
@@ -15,9 +15,10 @@ import {App} from './src/app';
15
15
 
16
16
  // Used by standalone-flow.html
17
17
  function __initLighthouseFlowReport__() {
18
- const root = document.body.querySelector('main');
19
- if (!root) throw Error('Root element not found');
20
- render(<App flowResult={window.__LIGHTHOUSE_FLOW_JSON__} />, root);
18
+ // TODO(adamraine): add lh-vars, etc classes programmatically instead of in the HTML template
19
+ const container = document.body.querySelector('main');
20
+ if (!container) throw Error('Container element not found');
21
+ render(<App flowResult={window.__LIGHTHOUSE_FLOW_JSON__} />, container);
21
22
  }
22
23
 
23
24
  window.__initLighthouseFlowReport__ = __initLighthouseFlowReport__;
@@ -8,7 +8,7 @@ import {render} from '@testing-library/preact';
8
8
  import {FunctionComponent} from 'preact';
9
9
 
10
10
  import {I18nProvider} from '../../src/i18n/i18n';
11
- import {SidebarHeader, SidebarSummary} from '../../src/sidebar/sidebar';
11
+ import {SidebarHeader, SidebarRuntimeSettings, SidebarSummary} from '../../src/sidebar/sidebar';
12
12
  import {FlowResultContext} from '../../src/util';
13
13
  import {flowResult} from '../sample-flow';
14
14
 
@@ -45,3 +45,45 @@ describe('SidebarSummary', () => {
45
45
  expect(link.classList).toContain('Sidebar--current');
46
46
  });
47
47
  });
48
+
49
+ describe('SidebarRuntimeSettings', () => {
50
+ it('displays default runtime settings', async () => {
51
+ const settings = {
52
+ formFactor: 'mobile',
53
+ throttlingMethod: 'simulate',
54
+ throttling: {
55
+ cpuSlowdownMultiplier: 4,
56
+ requestLatencyMs: 150 * 3.75,
57
+ downloadThroughputKbps: 1.6 * 1024 * 0.9,
58
+ uploadThroughputKbps: 750 * 0.9,
59
+ throughputKbps: 1.6 * 1024,
60
+ rttMs: 150,
61
+ },
62
+ } as any;
63
+ const root = render(<SidebarRuntimeSettings settings={settings}/>, {wrapper});
64
+
65
+ expect(root.getByText('Emulated Moto G4')).toBeTruthy();
66
+ expect(root.getByText('Slow 4G throttling')).toBeTruthy();
67
+ expect(root.getByText('4x slowdown'));
68
+ });
69
+
70
+ it('displays custom runtime settings', async () => {
71
+ const settings = {
72
+ formFactor: 'desktop',
73
+ throttlingMethod: 'devtools',
74
+ throttling: {
75
+ cpuSlowdownMultiplier: 1,
76
+ requestLatencyMs: 1,
77
+ downloadThroughputKbps: 1,
78
+ uploadThroughputKbps: 1,
79
+ throughputKbps: 1,
80
+ rttMs: 1,
81
+ },
82
+ } as any;
83
+ const root = render(<SidebarRuntimeSettings settings={settings}/>, {wrapper});
84
+
85
+ expect(root.getByText('Emulated Desktop')).toBeTruthy();
86
+ expect(root.getByText('Custom throttling')).toBeTruthy();
87
+ expect(root.getByText('1x slowdown'));
88
+ });
89
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lighthouse",
3
- "version": "8.6.0-dev.20211102",
3
+ "version": "8.6.0-dev.20211103",
4
4
  "description": "Automated auditing, performance metrics, and best practices for the web.",
5
5
  "main": "./lighthouse-core/index.js",
6
6
  "bin": {
@@ -21,12 +21,11 @@ limitations under the License.
21
21
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
22
22
  <link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEhklEQVR4AWJxL/BhIAesev1U5tcflpncgNrKIsqNIwzC9feMpDUzs70kOczMzMzJJcxwCTMzncPMnOwtzBwzMzPb0vRfeZPp0VhPS5I39V5fdiXV1/VD+9QC7OVn9BsyH1XIoEI1PfmJvLFowVV564+34DFUHudbmfDh4kVXh//7XwE+WjS/YfXZe3yr4j2rqj1AIhSB7hZ8ZtPZu/zw8cK523U4wE1/rvPfWrz4zs0m9ZdC9yUJAlASdBAgocRegfF/f3/h/PuaFsxMdwjAR0vm1+06eMMfIrhLqTWqdH4EumU2SPfMhigJAlRQbZrgrRsl9U+Y2DYDFCz3ILC9kiAiqSrMwbWT0nceEnR+9Kggc2zjOJCASDENkg0a5HfZZgDP81CM3CrQs2Z1+o7DJ6ePr8sK0AOCHv5Jjdt3evyYSaZ351VIStIxPRAUtrBYbxC6w+BZ0ivVSBKkIhJhemSyZpfB00EiPO2VjzYkxhcqXQqCWCShGplvi3y0QxqbuBurMjyJeWnkHZuAEgIQGsUBqwrfjZ+IlBgKyRJzVVYF8O6qFWdh86YzQzMrZigYmxAyfvHgLZQ/LC1CbeniW2Hkqr/PH16SgvGuf2/uzNMBwJA/njxizGPtSyAf7EziJCMGRDRdhoAC4PL1A/SrKQMAAQkEfpJAcRQdrBJ7gNwjSpJsdwK+CANBkqa1LgQB4IicV9nYUct7gaxuDJUErQIiEAiMxLVOFlKzIktPpT0ggpdpC/8YAHnxbgkUY4tAAFSR7AAXNyAAWHJrA/kHGjzg5nleuwFO7Nd/IoDw4Pm58+4jNLmYG0wRA5bErc2Mr3Y+dXTDW1VvwqbJkzMCHQ4S1GTCBOIgUHJrGdEwqzR+jAp/o2qAZelUDoQnruEEdDclJI6576AlNVfc+22XN/+Y1vnJD0Yind6UpEEvn/Hqq15EYjCW7jZCJEpnNvDgkyelDjs106kuux2AAXCSobULOWP8mLhYlpoDMK4qAFXJGk+grtH8YXVz5KJblqaG1+VUdTc0I290bmUQAriGITRbdQnom0aoFj8kx1+wMD2ifncAXUQE4SkDqN1hE0jEophs1SUwZAOhUAiMCLwRtamtTZtbbmZErSAUHbSysaoEmnrsakiMiUAURi283gN6wans9oX8rOCrj7/JP35DFD+iQ7Au/K2KE1jzx6ujjUnXFH9KjEq6ZlhsTBICrNLJf47Pv/pkHzvup1w4dmUbEei0+bcXRqJuh5kVARQ8byyYxOwNGr7A87xh1tp8sGT+uMInrwi++Xj7TQz2d27NvwEkrOflAFQGIDA5khASBCGdO2/Z/MnLPwYfv5TFhjW7QhVKAB6afwe2LpFlFsCnlQEosgQgDsdOG1/LKeNqJS4JCSPJ/i+TakwEARor7gER1Iva5JmPOJK0RUqmoPnnlzFCtmIAhAAQEIQRgDaiYPIauNXcnDlRIrWNFY3hm7PG9YRqr7IV7HrCgAC17befjEvRq2nGhAHtBqDpOuI/I1diUUAMYIxEdyejBJqLnNoszGZtfiX/CztGv2mq+sdaAAAAAElFTkSuQmCC">
23
23
  <title>Lighthouse Report</title>
24
+ <style>body {margin: 0}</style>
24
25
  </head>
25
- <body class="lh-root lh-vars">
26
+ <body>
26
27
  <noscript>Lighthouse report requires JavaScript. Please enable.</noscript>
27
28
 
28
- <main><!-- report populated here --></main>
29
-
30
29
  <div id="lh-log"></div>
31
30
 
32
31
  <script>window.__LIGHTHOUSE_JSON__ = %%LIGHTHOUSE_JSON%%;</script>
@@ -175,7 +175,7 @@
175
175
  }
176
176
 
177
177
  @media not print {
178
- .lh-vars.lh-dark {
178
+ .lh-dark {
179
179
  /* Pallete */
180
180
  --color-gray-200: var(--color-gray-800);
181
181
  --color-gray-300: #616161;
@@ -15,3 +15,4 @@
15
15
  export {DOM} from '../renderer/dom.js';
16
16
  export {ReportRenderer} from '../renderer/report-renderer.js';
17
17
  export {ReportUIFeatures} from '../renderer/report-ui-features.js';
18
+ export {renderReport} from '../renderer/api.js';
@@ -13,24 +13,16 @@
13
13
 
14
14
  /* global ga */
15
15
 
16
- import {DOM} from '../renderer/dom.js';
16
+ import {renderReport} from '../renderer/api.js';
17
17
  import {Logger} from '../renderer/logger.js';
18
- import {ReportRenderer} from '../renderer/report-renderer.js';
19
- import {ReportUIFeatures} from '../renderer/report-ui-features.js';
20
18
 
21
19
  function __initLighthouseReport__() {
22
- const dom = new DOM(document);
23
- const renderer = new ReportRenderer(dom);
24
- const container = dom.find('main', document);
25
- /** @type {LH.ReportResult} */
20
+ /** @type {LH.Result} */
26
21
  // @ts-expect-error
27
22
  const lhr = window.__LIGHTHOUSE_JSON__;
28
- renderer.renderReport(lhr, container);
29
23
 
30
- // Hook in JS features and page-level event listeners after the report
31
- // is in the document.
32
- const features = new ReportUIFeatures(dom);
33
- features.initFeatures(lhr);
24
+ const reportRootEl = renderReport(lhr);
25
+ document.body.append(reportRootEl);
34
26
 
35
27
  document.addEventListener('lh-analytics', /** @param {Event} e */ e => {
36
28
  // @ts-expect-error
@@ -38,7 +30,8 @@ function __initLighthouseReport__() {
38
30
  });
39
31
 
40
32
  document.addEventListener('lh-log', /** @param {Event} e */ e => {
41
- const el = dom.find('div#lh-log', document);
33
+ const el = document.querySelector('div#lh-log');
34
+ if (!el) return;
42
35
 
43
36
  const logger = new Logger(el);
44
37
  // @ts-expect-error
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @license Copyright 2021 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
+
9
+ import {DOM} from '../renderer/dom.js';
10
+ import {ReportRenderer} from '../renderer/report-renderer.js';
11
+ import {ReportUIFeatures} from '../renderer/report-ui-features.js';
12
+
13
+ /**
14
+ * @param {LH.Result} lhr
15
+ * @param {LH.Renderer.Options} opts
16
+ * @return {HTMLElement}
17
+ */
18
+ export function renderReport(lhr, opts = {}) {
19
+ const rootEl = document.createElement('article');
20
+ rootEl.classList.add('lh-root', 'lh-vars');
21
+
22
+ const dom = new DOM(rootEl.ownerDocument, rootEl);
23
+ const renderer = new ReportRenderer(dom);
24
+
25
+ renderer.renderReport(lhr, rootEl, opts);
26
+
27
+ // Hook in JS features and page-level event listeners after the report
28
+ // is in the document.
29
+ const features = new ReportUIFeatures(dom, opts);
30
+ features.initFeatures(lhr);
31
+ return rootEl;
32
+ }
@@ -133,7 +133,7 @@ export class CategoryRenderer {
133
133
  const warningsEl = this.dom.createChildOf(summaryEl, 'div', 'lh-warnings');
134
134
  this.dom.createChildOf(warningsEl, 'span').textContent = strings.warningHeader;
135
135
  if (warnings.length === 1) {
136
- warningsEl.appendChild(this.dom.document().createTextNode(warnings.join('')));
136
+ warningsEl.appendChild(this.dom.createTextNode(warnings.join('')));
137
137
  } else {
138
138
  const warningsUl = this.dom.createChildOf(warningsEl, 'ul');
139
139
  for (const warning of warnings) {