lighthouse 8.0.0-dev.20210709 → 8.0.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 (299) hide show
  1. package/docs/architecture.md +101 -0
  2. package/docs/authenticated-pages.md +44 -0
  3. package/docs/bug-labels.md +35 -0
  4. package/docs/configuration.md +213 -0
  5. package/docs/emulation.md +32 -0
  6. package/docs/error-reporting.md +42 -0
  7. package/docs/hacking-tips.md +55 -0
  8. package/docs/headless-chrome.md +119 -0
  9. package/docs/lantern.md +55 -0
  10. package/docs/new-audits.md +99 -0
  11. package/docs/performance-budgets.md +187 -0
  12. package/docs/plugins.md +374 -0
  13. package/docs/puppeteer.md +95 -0
  14. package/docs/readme.md +164 -0
  15. package/docs/recipes/auth/README.md +129 -0
  16. package/docs/recipes/auth/example-lh-auth.js +81 -0
  17. package/docs/recipes/auth/package.json +11 -0
  18. package/docs/recipes/auth/server/public/dashboard-unauthenticated.html +21 -0
  19. package/docs/recipes/auth/server/public/dashboard.html +25 -0
  20. package/docs/recipes/auth/server/public/home-unauthenticated.html +27 -0
  21. package/docs/recipes/auth/server/public/home.html +17 -0
  22. package/docs/recipes/auth/server/public/unauthenticated.html +22 -0
  23. package/docs/recipes/auth/server/server.js +85 -0
  24. package/docs/recipes/custom-audit/custom-config.js +36 -0
  25. package/docs/recipes/custom-audit/package.json +8 -0
  26. package/docs/recipes/custom-audit/readme.md +32 -0
  27. package/docs/recipes/custom-audit/searchable-audit.js +46 -0
  28. package/docs/recipes/custom-audit/searchable-gatherer.js +32 -0
  29. package/docs/recipes/custom-gatherer-puppeteer/custom-audit.js +34 -0
  30. package/{root.js → docs/recipes/custom-gatherer-puppeteer/custom-config.js} +23 -2
  31. package/docs/recipes/custom-gatherer-puppeteer/custom-gatherer.js +51 -0
  32. package/docs/recipes/custom-gatherer-puppeteer/package.json +13 -0
  33. package/docs/recipes/custom-gatherer-puppeteer/readme.md +7 -0
  34. package/docs/recipes/custom-gatherer-puppeteer/test.sh +9 -0
  35. package/docs/recipes/gulp/gulpfile.js +79 -0
  36. package/docs/recipes/gulp/package.json +12 -0
  37. package/docs/recipes/gulp/public/index.html +22 -0
  38. package/docs/recipes/gulp/readme.md +6 -0
  39. package/docs/recipes/integration-test/README.md +14 -0
  40. package/docs/recipes/integration-test/example-lh-auth.test.js +160 -0
  41. package/docs/recipes/integration-test/package.json +9 -0
  42. package/docs/recipes/lighthouse-plugin-example/audits/preload-as.js +46 -0
  43. package/docs/recipes/lighthouse-plugin-example/package.json +11 -0
  44. package/docs/recipes/lighthouse-plugin-example/plugin-recipe-screenshot.png +0 -0
  45. package/docs/recipes/lighthouse-plugin-example/plugin.js +24 -0
  46. package/docs/recipes/lighthouse-plugin-example/readme.md +53 -0
  47. package/docs/releasing.md +164 -0
  48. package/docs/scoring.md +79 -0
  49. package/docs/throttling.md +150 -0
  50. package/docs/understanding-results.md +209 -0
  51. package/docs/v8-perf-faq.md +244 -0
  52. package/docs/variability.md +150 -0
  53. package/jest.config.js +0 -3
  54. package/lighthouse-cli/bin.js +8 -6
  55. package/lighthouse-core/audits/accessibility/aria-command-name.js +1 -1
  56. package/lighthouse-core/audits/accessibility/aria-meter-name.js +1 -1
  57. package/lighthouse-core/audits/accessibility/aria-progressbar-name.js +1 -1
  58. package/lighthouse-core/audits/accessibility/aria-tooltip-name.js +1 -1
  59. package/lighthouse-core/audits/accessibility/aria-treeitem-name.js +1 -1
  60. package/lighthouse-core/audits/apple-touch-icon.js +0 -1
  61. package/lighthouse-core/audits/audit.js +3 -3
  62. package/lighthouse-core/audits/autocomplete.js +2 -2
  63. package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +14 -29
  64. package/lighthouse-core/audits/byte-efficiency/duplicated-javascript.js +2 -3
  65. package/lighthouse-core/audits/byte-efficiency/efficient-animated-content.js +1 -1
  66. package/lighthouse-core/audits/byte-efficiency/legacy-javascript.js +2 -3
  67. package/lighthouse-core/audits/byte-efficiency/modern-image-formats.js +15 -55
  68. package/lighthouse-core/audits/byte-efficiency/offscreen-images.js +4 -8
  69. package/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js +8 -15
  70. package/lighthouse-core/audits/byte-efficiency/total-byte-weight.js +9 -10
  71. package/lighthouse-core/audits/byte-efficiency/unminified-css.js +1 -1
  72. package/lighthouse-core/audits/byte-efficiency/unminified-javascript.js +1 -1
  73. package/lighthouse-core/audits/byte-efficiency/unused-css-rules.js +1 -1
  74. package/lighthouse-core/audits/byte-efficiency/unused-javascript.js +1 -2
  75. package/lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js +2 -2
  76. package/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js +1 -2
  77. package/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +24 -46
  78. package/lighthouse-core/audits/byte-efficiency/uses-text-compression.js +1 -1
  79. package/lighthouse-core/audits/critical-request-chains.js +0 -1
  80. package/lighthouse-core/audits/csp-xss.js +1 -1
  81. package/lighthouse-core/audits/diagnostics.js +0 -1
  82. package/lighthouse-core/audits/dobetterweb/geolocation-on-start.js +0 -1
  83. package/lighthouse-core/audits/dobetterweb/inspector-issues.js +1 -1
  84. package/lighthouse-core/audits/dobetterweb/notification-on-start.js +0 -1
  85. package/lighthouse-core/audits/dobetterweb/uses-http2.js +0 -1
  86. package/lighthouse-core/audits/final-screenshot.js +4 -8
  87. package/lighthouse-core/audits/font-display.js +0 -1
  88. package/lighthouse-core/audits/installable-manifest.js +3 -4
  89. package/lighthouse-core/audits/largest-contentful-paint-element.js +0 -1
  90. package/lighthouse-core/audits/long-tasks.js +1 -1
  91. package/lighthouse-core/audits/maskable-icon.js +0 -1
  92. package/lighthouse-core/audits/metrics/first-contentful-paint-3g.js +2 -4
  93. package/lighthouse-core/audits/metrics/first-contentful-paint.js +2 -4
  94. package/lighthouse-core/audits/metrics/first-meaningful-paint.js +2 -4
  95. package/lighthouse-core/audits/metrics/interactive.js +2 -4
  96. package/lighthouse-core/audits/metrics/largest-contentful-paint.js +2 -4
  97. package/lighthouse-core/audits/metrics/max-potential-fid.js +2 -4
  98. package/lighthouse-core/audits/metrics/speed-index.js +2 -4
  99. package/lighthouse-core/audits/metrics/total-blocking-time.js +2 -10
  100. package/lighthouse-core/audits/metrics.js +2 -4
  101. package/lighthouse-core/audits/performance-budget.js +0 -1
  102. package/lighthouse-core/audits/predictive-perf.js +6 -9
  103. package/lighthouse-core/audits/preload-fonts.js +1 -11
  104. package/lighthouse-core/audits/preload-lcp-image.js +5 -18
  105. package/lighthouse-core/audits/redirects.js +8 -10
  106. package/lighthouse-core/audits/screenshot-thumbnails.js +13 -28
  107. package/lighthouse-core/audits/seo/canonical.js +1 -2
  108. package/lighthouse-core/audits/seo/font-size.js +4 -4
  109. package/lighthouse-core/audits/seo/hreflang.js +2 -3
  110. package/lighthouse-core/audits/seo/http-status-code.js +16 -21
  111. package/lighthouse-core/audits/seo/is-crawlable.js +3 -4
  112. package/lighthouse-core/audits/seo/robots-txt.js +2 -2
  113. package/lighthouse-core/audits/seo/tap-targets.js +5 -5
  114. package/lighthouse-core/audits/server-response-time.js +2 -20
  115. package/lighthouse-core/audits/splash-screen.js +0 -1
  116. package/lighthouse-core/audits/themed-omnibox.js +0 -1
  117. package/lighthouse-core/audits/third-party-facades.js +0 -1
  118. package/lighthouse-core/audits/third-party-summary.js +3 -1
  119. package/lighthouse-core/audits/timing-budget.js +2 -4
  120. package/lighthouse-core/audits/uses-rel-preconnect.js +9 -14
  121. package/lighthouse-core/audits/uses-rel-preload.js +2 -13
  122. package/lighthouse-core/computed/main-thread-tasks.js +2 -2
  123. package/lighthouse-core/computed/metrics/cumulative-layout-shift.js +3 -3
  124. package/lighthouse-core/computed/metrics/first-contentful-paint-all-frames.js +6 -6
  125. package/lighthouse-core/computed/metrics/first-contentful-paint.js +8 -9
  126. package/lighthouse-core/computed/metrics/first-meaningful-paint.js +9 -10
  127. package/lighthouse-core/computed/metrics/interactive.js +24 -25
  128. package/lighthouse-core/computed/metrics/lantern-first-contentful-paint.js +6 -6
  129. package/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js +6 -6
  130. package/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js +6 -6
  131. package/lighthouse-core/computed/metrics/lantern-metric.js +8 -16
  132. package/lighthouse-core/computed/metrics/largest-contentful-paint-all-frames.js +7 -7
  133. package/lighthouse-core/computed/metrics/largest-contentful-paint.js +9 -10
  134. package/lighthouse-core/computed/metrics/max-potential-fid.js +11 -8
  135. package/lighthouse-core/computed/metrics/metric.js +5 -32
  136. package/lighthouse-core/computed/metrics/speed-index.js +5 -6
  137. package/lighthouse-core/computed/metrics/timing-summary.js +45 -55
  138. package/lighthouse-core/computed/metrics/total-blocking-time.js +29 -36
  139. package/lighthouse-core/computed/page-dependency-graph.js +14 -14
  140. package/lighthouse-core/computed/resource-summary.js +7 -3
  141. package/lighthouse-core/computed/speedline.js +3 -3
  142. package/lighthouse-core/computed/trace-of-tab.js +86 -15
  143. package/lighthouse-core/computed/user-timings.js +5 -5
  144. package/lighthouse-core/config/default-config.js +0 -1
  145. package/lighthouse-core/fraggle-rock/config/config.js +7 -9
  146. package/lighthouse-core/fraggle-rock/config/default-config.js +2 -40
  147. package/lighthouse-core/fraggle-rock/config/filters.js +6 -39
  148. package/lighthouse-core/fraggle-rock/config/validation.js +4 -4
  149. package/lighthouse-core/fraggle-rock/gather/base-artifacts.js +19 -54
  150. package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +10 -21
  151. package/lighthouse-core/fraggle-rock/gather/runner-helpers.js +2 -2
  152. package/lighthouse-core/fraggle-rock/gather/snapshot-runner.js +2 -2
  153. package/lighthouse-core/fraggle-rock/gather/timespan-runner.js +2 -2
  154. package/lighthouse-core/gather/driver/prepare.js +0 -3
  155. package/lighthouse-core/gather/fetcher.js +2 -0
  156. package/lighthouse-core/gather/gather-runner.js +14 -2
  157. package/lighthouse-core/gather/gatherers/image-elements.js +61 -24
  158. package/lighthouse-core/gather/gatherers/inspector-issues.js +2 -2
  159. package/lighthouse-core/gather/gatherers/script-elements.js +12 -45
  160. package/lighthouse-core/gather/gatherers/seo/font-size.js +5 -5
  161. package/lighthouse-core/gather/gatherers/seo/tap-targets.js +12 -64
  162. package/lighthouse-core/gather/gatherers/service-worker.js +3 -20
  163. package/lighthouse-core/gather/gatherers/trace-compat.js +1 -1
  164. package/lighthouse-core/gather/gatherers/trace-elements.js +3 -15
  165. package/lighthouse-core/gather/gatherers/trace.js +4 -13
  166. package/lighthouse-core/gather/gatherers/viewport-dimensions.js +1 -1
  167. package/lighthouse-core/lib/dependency-graph/simulator/network-analyzer.js +2 -13
  168. package/lighthouse-core/lib/emulation.js +2 -0
  169. package/lighthouse-core/lib/i18n/i18n.js +2 -2
  170. package/lighthouse-core/lib/i18n/locales/ar-XB.json +141 -141
  171. package/lighthouse-core/lib/i18n/locales/ar.json +143 -143
  172. package/lighthouse-core/lib/i18n/locales/bg.json +143 -143
  173. package/lighthouse-core/lib/i18n/locales/ca.json +141 -141
  174. package/lighthouse-core/lib/i18n/locales/cs.json +141 -141
  175. package/lighthouse-core/lib/i18n/locales/da.json +141 -141
  176. package/lighthouse-core/lib/i18n/locales/de.json +142 -142
  177. package/lighthouse-core/lib/i18n/locales/el.json +141 -141
  178. package/lighthouse-core/lib/i18n/locales/en-GB.json +141 -141
  179. package/lighthouse-core/lib/i18n/locales/en-US.ctc.json +6659 -0
  180. package/lighthouse-core/lib/i18n/locales/en-US.json +144 -150
  181. package/lighthouse-core/lib/i18n/locales/en-XA.json +141 -141
  182. package/lighthouse-core/lib/i18n/locales/en-XL.ctc.json +6628 -0
  183. package/lighthouse-core/lib/i18n/locales/en-XL.json +144 -150
  184. package/lighthouse-core/lib/i18n/locales/es-419.json +141 -141
  185. package/lighthouse-core/lib/i18n/locales/es.json +141 -141
  186. package/lighthouse-core/lib/i18n/locales/fi.json +143 -143
  187. package/lighthouse-core/lib/i18n/locales/fil.json +142 -142
  188. package/lighthouse-core/lib/i18n/locales/fr.json +141 -141
  189. package/lighthouse-core/lib/i18n/locales/he.json +142 -142
  190. package/lighthouse-core/lib/i18n/locales/hi.json +143 -143
  191. package/lighthouse-core/lib/i18n/locales/hr.json +141 -141
  192. package/lighthouse-core/lib/i18n/locales/hu.json +143 -143
  193. package/lighthouse-core/lib/i18n/locales/id.json +143 -143
  194. package/lighthouse-core/lib/i18n/locales/it.json +143 -143
  195. package/lighthouse-core/lib/i18n/locales/ja.json +143 -143
  196. package/lighthouse-core/lib/i18n/locales/ko.json +143 -143
  197. package/lighthouse-core/lib/i18n/locales/lt.json +143 -143
  198. package/lighthouse-core/lib/i18n/locales/lv.json +143 -143
  199. package/lighthouse-core/lib/i18n/locales/nl.json +141 -141
  200. package/lighthouse-core/lib/i18n/locales/no.json +141 -141
  201. package/lighthouse-core/lib/i18n/locales/pl.json +141 -141
  202. package/lighthouse-core/lib/i18n/locales/pt-PT.json +141 -141
  203. package/lighthouse-core/lib/i18n/locales/pt.json +141 -141
  204. package/lighthouse-core/lib/i18n/locales/ro.json +144 -144
  205. package/lighthouse-core/lib/i18n/locales/ru.json +143 -143
  206. package/lighthouse-core/lib/i18n/locales/sk.json +142 -142
  207. package/lighthouse-core/lib/i18n/locales/sl.json +141 -141
  208. package/lighthouse-core/lib/i18n/locales/sr-Latn.json +143 -143
  209. package/lighthouse-core/lib/i18n/locales/sr.json +143 -143
  210. package/lighthouse-core/lib/i18n/locales/sv.json +142 -142
  211. package/lighthouse-core/lib/i18n/locales/ta.json +141 -141
  212. package/lighthouse-core/lib/i18n/locales/te.json +143 -143
  213. package/lighthouse-core/lib/i18n/locales/th.json +143 -143
  214. package/lighthouse-core/lib/i18n/locales/tr.json +143 -143
  215. package/lighthouse-core/lib/i18n/locales/uk.json +141 -141
  216. package/lighthouse-core/lib/i18n/locales/vi.json +143 -143
  217. package/lighthouse-core/lib/i18n/locales/zh-HK.json +141 -141
  218. package/lighthouse-core/lib/i18n/locales/zh-TW.json +143 -143
  219. package/lighthouse-core/lib/i18n/locales/zh.json +143 -143
  220. package/lighthouse-core/lib/lh-error.js +2 -2
  221. package/lighthouse-core/lib/minify-trace.js +1 -1
  222. package/lighthouse-core/lib/network-request.js +1 -17
  223. package/lighthouse-core/lib/page-functions.js +5 -6
  224. package/lighthouse-core/lib/rect-helpers.js +3 -3
  225. package/lighthouse-core/lib/sd-validation/assets/jsonldcontext.json +7137 -0
  226. package/lighthouse-core/lib/sd-validation/assets/schema-tree.json +9900 -0
  227. package/{report/report-assets.js → lighthouse-core/lib/sd-validation/helpers/walk-object.js} +20 -12
  228. package/lighthouse-core/lib/sd-validation/json-expander.js +56 -0
  229. package/lighthouse-core/lib/sd-validation/json-linter.js +49 -0
  230. package/lighthouse-core/lib/sd-validation/jsonld-keyword-validator.js +50 -0
  231. package/lighthouse-core/lib/sd-validation/line-number-from-jsonld-path.js +60 -0
  232. package/lighthouse-core/lib/sd-validation/schema-validator.js +146 -0
  233. package/lighthouse-core/lib/sd-validation/scripts/download-jsonldcontext.js +30 -0
  234. package/lighthouse-core/lib/sd-validation/scripts/generate-schema-tree.js +97 -0
  235. package/lighthouse-core/lib/sd-validation/sd-validation.js +77 -0
  236. package/lighthouse-core/lib/tappable-rects.js +1 -1
  237. package/lighthouse-core/lib/tracehouse/trace-processor.js +42 -116
  238. package/lighthouse-core/lib/url-shim.js +2 -29
  239. package/lighthouse-core/report/html/html-report-assets.js +38 -0
  240. package/{report/README.md → lighthouse-core/report/html/readme.md} +11 -7
  241. package/{report → lighthouse-core/report/html}/renderer/category-renderer.js +0 -0
  242. package/{report → lighthouse-core/report/html}/renderer/crc-details-renderer.js +0 -0
  243. package/{report → lighthouse-core/report/html}/renderer/details-renderer.js +1 -1
  244. package/{report → lighthouse-core/report/html}/renderer/dom.js +0 -0
  245. package/{report → lighthouse-core/report/html}/renderer/element-screenshot-renderer.js +0 -0
  246. package/{report → lighthouse-core/report/html}/renderer/i18n.js +1 -1
  247. package/{report → lighthouse-core/report/html}/renderer/logger.js +0 -0
  248. package/{report → lighthouse-core/report/html}/renderer/performance-category-renderer.js +0 -0
  249. package/{report → lighthouse-core/report/html}/renderer/psi.js +0 -0
  250. package/{report → lighthouse-core/report/html}/renderer/pwa-category-renderer.js +0 -0
  251. package/{report → lighthouse-core/report/html}/renderer/report-renderer.js +0 -0
  252. package/{report → lighthouse-core/report/html}/renderer/report-ui-features.js +3 -3
  253. package/{report → lighthouse-core/report/html}/renderer/snippet-renderer.js +0 -0
  254. package/{report → lighthouse-core/report/html}/renderer/text-encoding.js +0 -0
  255. package/{report → lighthouse-core/report/html}/renderer/util.js +4 -7
  256. package/{report/assets/styles.css → lighthouse-core/report/html/report-styles.css} +0 -0
  257. package/{report/assets/standalone-template.html → lighthouse-core/report/html/report-template.html} +41 -1
  258. package/{report/assets → lighthouse-core/report/html}/templates.html +0 -0
  259. package/{report → lighthouse-core/report}/report-generator.js +1 -1
  260. package/lighthouse-core/runner.js +1 -1
  261. package/package.json +12 -13
  262. package/readme.md +2 -2
  263. package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +2 -3
  264. package/third-party/chromium-synchronization/installability-errors-test.js +2 -2
  265. package/third-party/download-content-shell/download-content-shell.js +1 -2
  266. package/third-party/snyk/snapshot.json +1 -1
  267. package/tsconfig.json +1 -0
  268. package/types/artifacts.d.ts +21 -41
  269. package/types/audit.d.ts +0 -2
  270. package/types/config.d.ts +2 -16
  271. package/types/externs.d.ts +0 -1
  272. package/types/gatherer.d.ts +13 -13
  273. package/types/html-renderer.d.ts +14 -14
  274. package/types/i18n.d.ts +1 -1
  275. package/lighthouse-core/audits/byte-efficiency/uses-responsive-images-snapshot.js +0 -94
  276. package/lighthouse-core/computed/image-records.js +0 -62
  277. package/lighthouse-core/computed/metrics/navigation-metric.js +0 -46
  278. package/lighthouse-core/computed/processed-navigation.js +0 -21
  279. package/lighthouse-core/computed/processed-trace.js +0 -21
  280. package/lighthouse-core/gather/gatherers/gather-context.js +0 -25
  281. package/lighthouse-core/gather/gatherers/host-form-factor.js +0 -31
  282. package/lighthouse-core/gather/gatherers/host-user-agent.js +0 -29
  283. package/lighthouse-core/lib/lh-trace-processor.js +0 -46
  284. package/report/clients/standalone.js +0 -52
  285. package/report/test/renderer/category-renderer-test.js +0 -488
  286. package/report/test/renderer/crc-details-renderer-test.js +0 -115
  287. package/report/test/renderer/details-renderer-test.js +0 -843
  288. package/report/test/renderer/dom-test.js +0 -157
  289. package/report/test/renderer/element-screenshot-renderer-test.js +0 -189
  290. package/report/test/renderer/i18n-test.js +0 -146
  291. package/report/test/renderer/performance-category-renderer-test.js +0 -332
  292. package/report/test/renderer/psi-test.js +0 -152
  293. package/report/test/renderer/pwa-category-renderer-test.js +0 -303
  294. package/report/test/renderer/report-renderer-test.js +0 -325
  295. package/report/test/renderer/report-ui-features-test.js +0 -572
  296. package/report/test/renderer/snippet-renderer-test.js +0 -291
  297. package/report/test/renderer/text-encoding-test.js +0 -41
  298. package/report/test/renderer/util-test.js +0 -388
  299. package/report/test/report-generator-test.js +0 -145
@@ -1,332 +0,0 @@
1
- /**
2
- * @license Copyright 2017 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
- /* eslint-env jest, browser */
9
-
10
- const assert = require('assert').strict;
11
- const jsdom = require('jsdom');
12
- const Util = require('../../renderer/util.js');
13
- const I18n = require('../../renderer/i18n.js');
14
- const URL = require('../../../lighthouse-core/lib/url-shim.js');
15
- const DOM = require('../../renderer/dom.js');
16
- const DetailsRenderer = require('../../renderer/details-renderer.js');
17
- const CriticalRequestChainRenderer = require('../../renderer/crc-details-renderer.js');
18
- const CategoryRenderer = require('../../renderer/category-renderer.js');
19
- const sampleResultsOrig = require('../../../lighthouse-core/test/results/sample_v2.json');
20
- const reportAssets = require('../../report-assets.js');
21
-
22
- describe('PerfCategoryRenderer', () => {
23
- let category;
24
- let renderer;
25
- let sampleResults;
26
-
27
- beforeAll(() => {
28
- global.Util = Util;
29
- global.Util.i18n = new I18n('en', {...Util.UIStrings});
30
- global.CriticalRequestChainRenderer = CriticalRequestChainRenderer;
31
- global.CategoryRenderer = CategoryRenderer;
32
-
33
- // Delayed so that CategoryRenderer is in global scope
34
- const PerformanceCategoryRenderer = require('../../renderer/performance-category-renderer.js');
35
-
36
- const {document} = new jsdom.JSDOM(reportAssets.REPORT_TEMPLATES).window;
37
- const dom = new DOM(document);
38
- const detailsRenderer = new DetailsRenderer(dom);
39
- renderer = new PerformanceCategoryRenderer(dom, detailsRenderer);
40
-
41
- // TODO: don't call a LH.ReportResult `sampleResults`, which is typically always LH.Result
42
- sampleResults = Util.prepareReportResult(sampleResultsOrig);
43
- category = sampleResults.categories.performance;
44
- });
45
-
46
- afterAll(() => {
47
- global.Util.i18n = undefined;
48
- global.Util = undefined;
49
- global.CriticalRequestChainRenderer = undefined;
50
- global.CategoryRenderer = undefined;
51
- });
52
-
53
- it('renders the category header', () => {
54
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
55
- const score = categoryDOM.querySelector('.lh-category-header');
56
- const value = categoryDOM.querySelector('.lh-category-header .lh-gauge__percentage');
57
- const title = score.querySelector('.lh-gauge__label');
58
-
59
- assert.deepEqual(score, score.firstElementChild, 'first child is a score');
60
- const scoreInDom = Number(value.textContent);
61
- assert.ok(Number.isInteger(scoreInDom) && scoreInDom > 10, 'category score is rounded');
62
- assert.equal(title.textContent, category.title, 'title is set');
63
- });
64
-
65
- it('renders the sections', () => {
66
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
67
- const sections = categoryDOM.querySelectorAll('.lh-category > .lh-audit-group');
68
- assert.equal(sections.length, 5);
69
- });
70
-
71
- it('renders the metrics', () => {
72
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
73
- const metricsSection = categoryDOM.querySelectorAll('.lh-category > .lh-audit-group')[0];
74
-
75
- const metricAudits = category.auditRefs.filter(audit => audit.group === 'metrics');
76
- const timelineElements = metricsSection.querySelectorAll('.lh-metric');
77
- const nontimelineElements = metricsSection.querySelectorAll('.lh-audit');
78
- assert.equal(timelineElements.length + nontimelineElements.length, metricAudits.length);
79
- });
80
-
81
- it('renders the metrics variance disclaimer as markdown', () => {
82
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
83
- const disclaimerEl =
84
- categoryDOM.querySelector('.lh-audit-group--metrics > .lh-metrics__disclaimer');
85
-
86
- assert.ok(disclaimerEl.textContent.includes('Values are estimated'));
87
- const disclamerLink = disclaimerEl.querySelector('a');
88
- assert.ok(disclamerLink, 'disclaimer contains coverted markdown link');
89
- const disclamerUrl = new URL(disclamerLink.href);
90
- assert.strictEqual(disclamerUrl.hostname, 'web.dev');
91
- const calcLink = disclaimerEl.querySelector('a.lh-calclink');
92
- assert.ok(calcLink, 'disclaimer contains scorecalc link');
93
- assert.strictEqual(new URL(calcLink.href).hostname, 'googlechrome.github.io');
94
- });
95
-
96
- it('renders the failing performance opportunities', () => {
97
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
98
-
99
- const oppAudits = category.auditRefs.filter(audit => audit.group === 'load-opportunities' &&
100
- audit.result.score !== 1 && audit.result.scoreDisplayMode !== 'notApplicable');
101
- const oppElements = categoryDOM.querySelectorAll('.lh-audit--load-opportunity');
102
- assert.equal(oppElements.length, oppAudits.length);
103
-
104
- const oppElement = oppElements[0];
105
- const oppSparklineBarElement = oppElement.querySelector('.lh-sparkline__bar');
106
- const oppSparklineElement = oppElement.querySelector('.lh-load-opportunity__sparkline');
107
- const oppTitleElement = oppElement.querySelector('.lh-audit__title');
108
- const oppWastedElement = oppElement.querySelector('.lh-audit__display-text');
109
- assert.ok(oppTitleElement.textContent, 'did not render title');
110
- assert.ok(oppSparklineBarElement.style.width, 'did not set sparkline width');
111
- assert.ok(oppWastedElement.textContent, 'did not render stats');
112
- assert.ok(oppSparklineElement.title, 'did not set tooltip on sparkline');
113
- });
114
-
115
- it('renders performance opportunities with an errorMessage', () => {
116
- const auditWithError = {
117
- score: 0,
118
- group: 'load-opportunities',
119
- result: {
120
- score: null, scoreDisplayMode: 'error', errorMessage: 'Yikes!!', title: 'Bug #2',
121
- description: '',
122
- },
123
- };
124
-
125
- const fakeCategory = Object.assign({}, category, {auditRefs: [auditWithError]});
126
- const categoryDOM = renderer.render(fakeCategory, sampleResults.categoryGroups);
127
- const tooltipEl = categoryDOM.querySelector('.lh-audit--load-opportunity .tooltip--error');
128
- assert.ok(tooltipEl, 'did not render error message');
129
- assert.ok(/Yikes!!/.test(tooltipEl.textContent));
130
- });
131
-
132
- it('renders performance opportunities\' explanation', () => {
133
- const auditWithExplanation = {
134
- score: 0,
135
- group: 'load-opportunities',
136
- result: {
137
- score: 0, scoreDisplayMode: 'numeric',
138
- numericValue: 100, explanation: 'Yikes!!', title: 'Bug #2', description: '',
139
- },
140
- };
141
-
142
- const fakeCategory = Object.assign({}, category, {auditRefs: [auditWithExplanation]});
143
- const categoryDOM = renderer.render(fakeCategory, sampleResults.categoryGroups);
144
-
145
- const selector = '.lh-audit--load-opportunity .lh-audit-explanation';
146
- const tooltipEl = categoryDOM.querySelector(selector);
147
- assert.ok(tooltipEl, 'did not render explanation text');
148
- assert.ok(/Yikes!!/.test(tooltipEl.textContent));
149
- });
150
-
151
- it('renders the failing diagnostics', () => {
152
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
153
- const diagnosticSection = categoryDOM.querySelector(
154
- '.lh-category > .lh-audit-group.lh-audit-group--diagnostics');
155
-
156
- const diagnosticAuditIds = category.auditRefs.filter(audit => {
157
- return audit.group === 'diagnostics' && !Util.showAsPassed(audit.result);
158
- }).map(audit => audit.id).sort();
159
- assert.ok(diagnosticAuditIds.length > 0);
160
-
161
- const diagnosticElementIds = [...diagnosticSection.querySelectorAll('.lh-audit')]
162
- .map(el => el.id).sort();
163
- assert.deepStrictEqual(diagnosticElementIds, diagnosticAuditIds);
164
- });
165
-
166
- it('renders the passed audits', () => {
167
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
168
- const passedSection = categoryDOM.querySelector('.lh-category > .lh-clump--passed');
169
-
170
- const passedAudits = category.auditRefs.filter(audit =>
171
- audit.group && audit.group !== 'metrics' && audit.id !== 'performance-budget'
172
- && Util.showAsPassed(audit.result));
173
- const passedElements = passedSection.querySelectorAll('.lh-audit');
174
- assert.equal(passedElements.length, passedAudits.length);
175
- });
176
-
177
- // Unsupported by perf cat renderer right now.
178
- it.skip('renders any manual audits', () => {
179
- });
180
-
181
- describe('getWastedMs', () => {
182
- it('handles erroring opportunities', () => {
183
- const auditWithDebug = {
184
- score: 0,
185
- group: 'load-opportunities',
186
- result: {
187
- error: true, score: 0,
188
- numericValue: 100, explanation: 'Yikes!!', title: 'Bug #2',
189
- },
190
- };
191
- const wastedMs = renderer._getWastedMs(auditWithDebug);
192
- assert.ok(Number.isFinite(wastedMs), 'Finite number not returned by wastedMs');
193
- });
194
- });
195
-
196
- describe('budgets', () => {
197
- it('renders the group and header', () => {
198
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
199
-
200
- const budgetsGroup = categoryDOM.querySelector('.lh-audit-group.lh-audit-group--budgets');
201
- assert.ok(budgetsGroup);
202
-
203
- const header = budgetsGroup.querySelector('.lh-audit-group__header');
204
- assert.ok(header);
205
- });
206
-
207
- it('renders the performance budget table', () => {
208
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
209
- const budgetTable = categoryDOM.querySelector('#performance-budget.lh-table');
210
- assert.ok(budgetTable);
211
-
212
- const lhrBudgetEntries = sampleResults.audits['performance-budget'].details.items;
213
- const tableRows = budgetTable.querySelectorAll('tbody > tr');
214
- assert.strictEqual(tableRows.length, lhrBudgetEntries.length);
215
- });
216
-
217
- it('renders the timing budget table', () => {
218
- const categoryDOM = renderer.render(category, sampleResults.categoryGroups);
219
- const budgetTable = categoryDOM.querySelector('#timing-budget.lh-table');
220
- assert.ok(budgetTable);
221
-
222
- const lhrBudgetEntries = sampleResults.audits['timing-budget'].details.items;
223
- const tableRows = budgetTable.querySelectorAll('tbody > tr');
224
- assert.strictEqual(tableRows.length, lhrBudgetEntries.length);
225
- });
226
-
227
- it('does not render the budgets section when all budget audits are notApplicable', () => {
228
- const budgetlessCategory = JSON.parse(JSON.stringify(category));
229
- ['performance-budget', 'timing-budget'].forEach((id) => {
230
- const budgetRef = budgetlessCategory.auditRefs.find(a => a.id === id);
231
- budgetRef.result.scoreDisplayMode = 'notApplicable';
232
- delete budgetRef.result.details;
233
- });
234
-
235
- const categoryDOM = renderer.render(budgetlessCategory, sampleResults.categoryGroups);
236
- const budgetsGroup = categoryDOM.querySelector('.lh-audit-group.lh-audit-group--budgets');
237
- assert.strictEqual(budgetsGroup, null);
238
- });
239
- });
240
-
241
- describe('_getScoringCalculatorHref', () => {
242
- it('creates a working link given some auditRefs', () => {
243
- const categoryClone = JSON.parse(JSON.stringify(category));
244
-
245
- // CLS of 0 is both valid and falsy. Make sure it doesn't become 'null'
246
- const cls = categoryClone.auditRefs.find(audit => audit.id === 'cumulative-layout-shift');
247
- cls.result.numericValue = 0;
248
-
249
- const href = renderer._getScoringCalculatorHref(categoryClone.auditRefs);
250
- const url = new URL(href);
251
- expect(url.hash.split('&')).toMatchInlineSnapshot(`
252
- Array [
253
- "#FCP=3969",
254
- "SI=4417",
255
- "LCP=4927",
256
- "TTI=4927",
257
- "TBT=117",
258
- "CLS=0",
259
- "FMP=3969",
260
- ]
261
- `);
262
- });
263
-
264
- it('also appends device and version number', () => {
265
- Util.reportJson = {
266
- configSettings: {formFactor: 'mobile'},
267
- lighthouseVersion: '6.0.0',
268
- };
269
- const href = renderer._getScoringCalculatorHref(category.auditRefs);
270
- const url = new URL(href);
271
- try {
272
- expect(url.hash.split('&')).toMatchInlineSnapshot(`
273
- Array [
274
- "#FCP=3969",
275
- "SI=4417",
276
- "LCP=4927",
277
- "TTI=4927",
278
- "TBT=117",
279
- "CLS=0.42",
280
- "FMP=3969",
281
- "device=mobile",
282
- "version=6.0.0",
283
- ]
284
- `);
285
- } finally {
286
- Util.reportJson = null;
287
- }
288
- });
289
-
290
- it('uses null if the metric is missing its value', () => {
291
- const categoryClone = JSON.parse(JSON.stringify(category));
292
- const lcp = categoryClone.auditRefs.find(audit => audit.id === 'largest-contentful-paint');
293
- lcp.result.numericValue = undefined;
294
- lcp.result.score = null;
295
- const href = renderer._getScoringCalculatorHref(categoryClone.auditRefs);
296
- expect(href).toContain('LCP=null');
297
- });
298
- });
299
-
300
- // This is done all in CSS, but tested here.
301
- describe('metric description toggles', () => {
302
- let container;
303
- let toggle;
304
- const metricsSelector = '.lh-audit-group--metrics';
305
- const toggleSelector = '.lh-metrics-toggle__input';
306
- const magicSelector =
307
- '.lh-metrics-toggle__input:checked ~ .lh-metrics-container .lh-metric__description';
308
- let getDescriptionsAfterCheckedToggle;
309
-
310
- describe('works if there is a performance category', () => {
311
- beforeAll(() => {
312
- container = renderer.render(category, sampleResults.categoryGroups);
313
- const metricsAuditGroup = container.querySelector(metricsSelector);
314
- toggle = metricsAuditGroup.querySelector(toggleSelector);
315
- // In the CSS, our magicSelector will flip display from `none` to `block`
316
- getDescriptionsAfterCheckedToggle = _ => metricsAuditGroup.querySelectorAll(magicSelector);
317
- });
318
-
319
- it('descriptions hidden by default', () => {
320
- assert.ok(getDescriptionsAfterCheckedToggle().length === 0);
321
- });
322
-
323
- it('can toggle description visibility', () => {
324
- assert.ok(getDescriptionsAfterCheckedToggle().length === 0);
325
- toggle.click();
326
- assert.ok(getDescriptionsAfterCheckedToggle().length > 2);
327
- toggle.click();
328
- assert.ok(getDescriptionsAfterCheckedToggle().length === 0);
329
- });
330
- });
331
- });
332
- });
@@ -1,152 +0,0 @@
1
- /**
2
- * @license Copyright 2017 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 assert = require('assert').strict;
9
- const fs = require('fs');
10
-
11
- const jsdom = require('jsdom');
12
-
13
- const testUtils = require('../../../lighthouse-core/test/test-utils.js');
14
- const reportAssets = require('../../report-assets.js');
15
- const prepareLabData = require('../../renderer/psi.js');
16
- const Util = require('../../renderer/util.js');
17
- const I18n = require('../../renderer/i18n.js');
18
- const DOM = require('../../renderer/dom.js');
19
- const CategoryRenderer = require('../../renderer/category-renderer.js');
20
- const DetailsRenderer = require('../../renderer/details-renderer.js');
21
- const CriticalRequestChainRenderer = require('../../renderer/crc-details-renderer.js');
22
- const ElementScreenshotRenderer = require('../../renderer/element-screenshot-renderer.js');
23
- const ReportUIFeatures = require('../../renderer/report-ui-features.js');
24
- const {LH_ROOT} = require('../../../root.js');
25
-
26
- const {itIfProtoExists, sampleResultsRoundtripStr} = testUtils.getProtoRoundTrip();
27
- const sampleResultsStr =
28
- fs.readFileSync(LH_ROOT + '/lighthouse-core/test/results/sample_v2.json', 'utf-8');
29
-
30
- /* eslint-env jest */
31
-
32
- describe('DOM', () => {
33
- let document;
34
- beforeAll(() => {
35
- global.Util = Util;
36
- global.I18n = I18n;
37
-
38
- global.DOM = DOM;
39
- global.CategoryRenderer = CategoryRenderer;
40
- global.DetailsRenderer = DetailsRenderer;
41
-
42
- // Delayed so that CategoryRenderer is in global scope
43
- const PerformanceCategoryRenderer =
44
- require('../../renderer/performance-category-renderer.js');
45
- global.PerformanceCategoryRenderer = PerformanceCategoryRenderer;
46
- global.CriticalRequestChainRenderer = CriticalRequestChainRenderer;
47
- global.ElementScreenshotRenderer = ElementScreenshotRenderer;
48
- global.ReportUIFeatures = ReportUIFeatures;
49
-
50
- const {window} = new jsdom.JSDOM(reportAssets.REPORT_TEMPLATES);
51
- document = window.document;
52
- });
53
-
54
- afterAll(() => {
55
- global.I18n = undefined;
56
- global.Util = undefined;
57
- global.DOM = undefined;
58
- global.CategoryRenderer = undefined;
59
- global.DetailsRenderer = undefined;
60
- global.PerformanceCategoryRenderer = undefined;
61
- global.CriticalRequestChainRenderer = undefined;
62
- global.ElementScreenshotRenderer = undefined;
63
- global.ReportUIFeatures = undefined;
64
- });
65
-
66
- describe('psi prepareLabData helpers', () => {
67
- describe('prepareLabData', () => {
68
- itIfProtoExists('succeeds with LHResult object (roundtrip) input', () => {
69
- const roundTripLHResult = /** @type {LH.Result} */ JSON.parse(sampleResultsRoundtripStr);
70
- const result = prepareLabData(roundTripLHResult, document);
71
-
72
- // Check that the report exists and has some content.
73
- assert.ok(result.perfCategoryEl instanceof document.defaultView.Element);
74
- assert.ok(result.perfCategoryEl.outerHTML.length > 50000, 'perfCategory HTML is populated');
75
- assert.ok(!result.perfCategoryEl.outerHTML.includes('lh-permalink'),
76
- 'PSI\'s perfCategory HTML doesn\'t include a lh-permalink element');
77
- // Assume using default locale.
78
- const title = result.perfCategoryEl.querySelector('.lh-audit-group--metrics')
79
- .querySelector('.lh-audit-group__title').textContent;
80
- assert.equal(title, Util.UIStrings.labDataTitle);
81
- });
82
-
83
- it('succeeds with stringified LHResult input', () => {
84
- const result = prepareLabData(sampleResultsStr, document);
85
- assert.ok(result.scoreGaugeEl instanceof document.defaultView.Element);
86
- assert.equal(result.scoreGaugeEl.querySelector('.lh-gauge__wrapper').href, '');
87
- assert.ok(result.scoreGaugeEl.outerHTML.includes('<svg'), 'score gauge comes with SVG');
88
-
89
- assert.ok(result.perfCategoryEl instanceof document.defaultView.Element);
90
- assert.ok(result.perfCategoryEl.outerHTML.length > 50000, 'perfCategory HTML is populated');
91
- assert.ok(!result.perfCategoryEl.outerHTML.includes('lh-permalink'),
92
- 'PSI\'s perfCategory HTML doesn\'t include a lh-permalink element');
93
-
94
- assert.equal(typeof result.finalScreenshotDataUri, 'string');
95
- assert.ok(result.finalScreenshotDataUri.startsWith('data:image/jpeg;base64,'));
96
- });
97
-
98
- it('throws if there is no perf category', () => {
99
- const lhrWithoutPerf = JSON.parse(sampleResultsStr);
100
- delete lhrWithoutPerf.categories.performance;
101
- const lhrWithoutPerfStr = JSON.stringify(lhrWithoutPerf);
102
-
103
- assert.throws(() => {
104
- prepareLabData(lhrWithoutPerfStr, document);
105
- }, /no performance category/i);
106
- });
107
-
108
- it('throws if there is no category groups', () => {
109
- const lhrWithoutGroups = JSON.parse(sampleResultsStr);
110
- delete lhrWithoutGroups.categoryGroups;
111
- const lhrWithoutGroupsStr = JSON.stringify(lhrWithoutGroups);
112
-
113
- assert.throws(() => {
114
- prepareLabData(lhrWithoutGroupsStr, document);
115
- }, /no category groups/i);
116
- });
117
-
118
- it('includes custom title and description', () => {
119
- const {perfCategoryEl} = prepareLabData(sampleResultsStr, document);
120
- const metricsGroupEl = perfCategoryEl.querySelector('.lh-audit-group--metrics');
121
-
122
- // Assume using default locale.
123
- // Replacing markdown because ".textContent" will be post-markdown.
124
- const expectedDescription = Util.UIStrings.lsPerformanceCategoryDescription
125
- .replace('[Lighthouse](https://developers.google.com/web/tools/lighthouse/)', 'Lighthouse');
126
-
127
- // Assume using default locale.
128
- const title = metricsGroupEl.querySelector('.lh-audit-group__title').textContent;
129
- const description =
130
- metricsGroupEl.querySelector('.lh-audit-group__description').textContent;
131
- assert.equal(title, Util.UIStrings.labDataTitle);
132
- assert.equal(description, expectedDescription);
133
- });
134
- });
135
- });
136
-
137
- describe('_getFinalScreenshot', () => {
138
- it('gets a datauri as a string', () => {
139
- const datauri = prepareLabData(sampleResultsStr, document).finalScreenshotDataUri;
140
- assert.equal(typeof datauri, 'string');
141
- assert.ok(datauri.startsWith('data:image/jpeg;base64,'));
142
- });
143
-
144
- it('returns null if there is no final-screenshot audit', () => {
145
- const clonedResults = JSON.parse(sampleResultsStr);
146
- delete clonedResults.audits['final-screenshot'];
147
- const LHResultJsonString = JSON.stringify(clonedResults);
148
- const datauri = prepareLabData(LHResultJsonString, document).finalScreenshotDataUri;
149
- assert.equal(datauri, null);
150
- });
151
- });
152
- });