lighthouse 10.4.0 → 11.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 (288) hide show
  1. package/CONTRIBUTING.md +1 -1
  2. package/cli/cli-flags.d.ts +1 -6
  3. package/cli/cli-flags.js +0 -5
  4. package/cli/run.js +3 -10
  5. package/cli/sentry-prompt.js +4 -2
  6. package/cli/test/smokehouse/core-tests.js +0 -2
  7. package/cli/test/smokehouse/frontends/smokehouse-bin.js +24 -14
  8. package/cli/test/smokehouse/lighthouse-runners/bundle.d.ts +1 -2
  9. package/cli/test/smokehouse/lighthouse-runners/bundle.js +12 -21
  10. package/cli/test/smokehouse/lighthouse-runners/cli.d.ts +1 -3
  11. package/cli/test/smokehouse/lighthouse-runners/cli.js +3 -7
  12. package/cli/test/smokehouse/lighthouse-runners/devtools.d.ts +1 -5
  13. package/cli/test/smokehouse/lighthouse-runners/devtools.js +1 -12
  14. package/cli/test/smokehouse/readme.md +0 -2
  15. package/cli/test/smokehouse/report-assert.d.ts +1 -3
  16. package/cli/test/smokehouse/report-assert.js +2 -19
  17. package/cli/test/smokehouse/smokehouse.js +3 -32
  18. package/core/audits/accessibility/aria-allowed-role.d.ts +10 -0
  19. package/core/audits/accessibility/aria-allowed-role.js +46 -0
  20. package/core/audits/accessibility/image-redundant-alt.d.ts +10 -0
  21. package/core/audits/accessibility/image-redundant-alt.js +45 -0
  22. package/core/audits/accessibility/label-content-name-mismatch.d.ts +10 -0
  23. package/core/audits/accessibility/label-content-name-mismatch.js +44 -0
  24. package/core/audits/accessibility/skip-link.d.ts +10 -0
  25. package/core/audits/accessibility/skip-link.js +43 -0
  26. package/core/audits/accessibility/table-duplicate-name.d.ts +10 -0
  27. package/core/audits/accessibility/table-duplicate-name.js +44 -0
  28. package/core/audits/accessibility/target-size.js +1 -1
  29. package/core/audits/byte-efficiency/duplicated-javascript.js +2 -2
  30. package/core/audits/byte-efficiency/render-blocking-resources.js +1 -0
  31. package/core/audits/dobetterweb/uses-http2.d.ts +18 -1
  32. package/core/audits/dobetterweb/uses-http2.js +62 -16
  33. package/core/audits/installable-manifest.d.ts +1 -5
  34. package/core/audits/installable-manifest.js +2 -7
  35. package/core/audits/largest-contentful-paint-element.d.ts +0 -6
  36. package/core/audits/largest-contentful-paint-element.js +13 -15
  37. package/core/audits/metrics/{experimental-interaction-to-next-paint.d.ts → interaction-to-next-paint.d.ts} +3 -3
  38. package/core/audits/metrics/{experimental-interaction-to-next-paint.js → interaction-to-next-paint.js} +3 -3
  39. package/core/audits/uses-rel-preconnect.js +23 -8
  40. package/core/audits/work-during-interaction.js +2 -2
  41. package/core/computed/processed-navigation.d.ts +1 -1
  42. package/core/config/config-helpers.d.ts +3 -3
  43. package/core/config/config-helpers.js +5 -12
  44. package/core/config/config.js +1 -7
  45. package/core/config/constants.d.ts +0 -2
  46. package/core/config/constants.js +2 -18
  47. package/core/config/default-config.js +59 -53
  48. package/core/config/filters.js +1 -1
  49. package/core/config/validation.d.ts +7 -12
  50. package/core/config/validation.js +16 -26
  51. package/core/gather/base-artifacts.d.ts +4 -4
  52. package/core/gather/base-artifacts.js +2 -6
  53. package/core/gather/base-gatherer.d.ts +12 -37
  54. package/core/gather/base-gatherer.js +7 -54
  55. package/core/gather/driver/dom.d.ts +4 -4
  56. package/core/gather/driver/dom.js +2 -2
  57. package/core/gather/driver/environment.d.ts +4 -4
  58. package/core/gather/driver/environment.js +2 -2
  59. package/core/gather/driver/execution-context.d.ts +12 -3
  60. package/core/gather/driver/execution-context.js +34 -3
  61. package/core/gather/driver/navigation.d.ts +2 -2
  62. package/core/gather/driver/navigation.js +2 -5
  63. package/core/gather/driver/network-monitor.d.ts +7 -6
  64. package/core/gather/driver/network-monitor.js +4 -4
  65. package/core/gather/driver/network.d.ts +2 -2
  66. package/core/gather/driver/network.js +1 -1
  67. package/core/gather/driver/prepare.d.ts +10 -10
  68. package/core/gather/driver/prepare.js +10 -10
  69. package/core/gather/driver/service-workers.d.ts +4 -4
  70. package/core/gather/driver/service-workers.js +2 -2
  71. package/core/gather/driver/storage.d.ts +6 -6
  72. package/core/gather/driver/storage.js +3 -3
  73. package/core/gather/driver/target-manager.d.ts +6 -5
  74. package/core/gather/driver/target-manager.js +3 -3
  75. package/core/gather/driver/wait-for-condition.d.ts +14 -14
  76. package/core/gather/driver/wait-for-condition.js +8 -8
  77. package/core/gather/driver.d.ts +9 -6
  78. package/core/gather/driver.js +14 -4
  79. package/core/gather/fetcher.d.ts +3 -3
  80. package/core/gather/fetcher.js +1 -1
  81. package/core/gather/gatherers/accessibility.d.ts +4 -4
  82. package/core/gather/gatherers/accessibility.js +8 -3
  83. package/core/gather/gatherers/anchor-elements.d.ts +4 -4
  84. package/core/gather/gatherers/anchor-elements.js +4 -4
  85. package/core/gather/gatherers/bf-cache-failures.d.ts +8 -14
  86. package/core/gather/gatherers/bf-cache-failures.js +5 -14
  87. package/core/gather/gatherers/cache-contents.d.ts +4 -4
  88. package/core/gather/gatherers/cache-contents.js +3 -3
  89. package/core/gather/gatherers/console-messages.d.ts +6 -6
  90. package/core/gather/gatherers/console-messages.js +4 -4
  91. package/core/gather/gatherers/css-usage.d.ts +14 -14
  92. package/core/gather/gatherers/css-usage.js +9 -9
  93. package/core/gather/gatherers/devtools-log-compat.d.ts +5 -5
  94. package/core/gather/gatherers/devtools-log-compat.js +4 -4
  95. package/core/gather/gatherers/devtools-log.d.ts +6 -6
  96. package/core/gather/gatherers/devtools-log.js +4 -4
  97. package/core/gather/gatherers/dobetterweb/doctype.d.ts +4 -4
  98. package/core/gather/gatherers/dobetterweb/doctype.js +3 -3
  99. package/core/gather/gatherers/dobetterweb/domstats.d.ts +4 -4
  100. package/core/gather/gatherers/dobetterweb/domstats.js +3 -3
  101. package/core/gather/gatherers/dobetterweb/optimized-images.d.ts +10 -22
  102. package/core/gather/gatherers/dobetterweb/optimized-images.js +10 -27
  103. package/core/gather/gatherers/dobetterweb/response-compression.d.ts +6 -12
  104. package/core/gather/gatherers/dobetterweb/response-compression.js +14 -21
  105. package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.d.ts +8 -14
  106. package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.js +5 -14
  107. package/core/gather/gatherers/full-page-screenshot.d.ts +10 -10
  108. package/core/gather/gatherers/full-page-screenshot.js +7 -10
  109. package/core/gather/gatherers/global-listeners.d.ts +4 -4
  110. package/core/gather/gatherers/global-listeners.js +3 -3
  111. package/core/gather/gatherers/iframe-elements.d.ts +4 -4
  112. package/core/gather/gatherers/iframe-elements.js +3 -3
  113. package/core/gather/gatherers/image-elements.d.ts +10 -10
  114. package/core/gather/gatherers/image-elements.js +6 -6
  115. package/core/gather/gatherers/inputs.d.ts +4 -4
  116. package/core/gather/gatherers/inputs.js +3 -3
  117. package/core/gather/gatherers/inspector-issues.d.ts +8 -19
  118. package/core/gather/gatherers/inspector-issues.js +9 -26
  119. package/core/gather/gatherers/installability-errors.d.ts +6 -6
  120. package/core/gather/gatherers/installability-errors.js +4 -4
  121. package/core/gather/gatherers/js-usage.d.ts +6 -6
  122. package/core/gather/gatherers/js-usage.js +4 -4
  123. package/core/gather/gatherers/link-elements.d.ts +8 -20
  124. package/core/gather/gatherers/link-elements.js +7 -24
  125. package/core/gather/gatherers/main-document-content.d.ts +4 -16
  126. package/core/gather/gatherers/main-document-content.js +5 -23
  127. package/core/gather/gatherers/meta-elements.d.ts +4 -4
  128. package/core/gather/gatherers/meta-elements.js +3 -3
  129. package/core/gather/gatherers/network-user-agent.d.ts +5 -5
  130. package/core/gather/gatherers/network-user-agent.js +4 -4
  131. package/core/gather/gatherers/script-elements.d.ts +6 -11
  132. package/core/gather/gatherers/script-elements.js +4 -13
  133. package/core/gather/gatherers/scripts.d.ts +7 -6
  134. package/core/gather/gatherers/scripts.js +7 -9
  135. package/core/gather/gatherers/seo/embedded-content.d.ts +4 -4
  136. package/core/gather/gatherers/seo/embedded-content.js +3 -3
  137. package/core/gather/gatherers/seo/font-size.d.ts +6 -6
  138. package/core/gather/gatherers/seo/font-size.js +5 -5
  139. package/core/gather/gatherers/seo/robots-txt.d.ts +4 -4
  140. package/core/gather/gatherers/seo/robots-txt.js +3 -3
  141. package/core/gather/gatherers/seo/tap-targets.d.ts +8 -8
  142. package/core/gather/gatherers/seo/tap-targets.js +5 -5
  143. package/core/gather/gatherers/service-worker.d.ts +4 -10
  144. package/core/gather/gatherers/service-worker.js +3 -15
  145. package/core/gather/gatherers/source-maps.d.ts +11 -23
  146. package/core/gather/gatherers/source-maps.js +22 -53
  147. package/core/gather/gatherers/stacks.d.ts +7 -7
  148. package/core/gather/gatherers/stacks.js +6 -6
  149. package/core/gather/gatherers/trace-compat.d.ts +5 -5
  150. package/core/gather/gatherers/trace-compat.js +4 -4
  151. package/core/gather/gatherers/trace-elements.d.ts +13 -25
  152. package/core/gather/gatherers/trace-elements.js +19 -32
  153. package/core/gather/gatherers/trace.d.ts +8 -8
  154. package/core/gather/gatherers/trace.js +5 -5
  155. package/core/gather/gatherers/viewport-dimensions.d.ts +4 -4
  156. package/core/gather/gatherers/viewport-dimensions.js +3 -3
  157. package/core/gather/gatherers/web-app-manifest.d.ts +8 -8
  158. package/core/gather/gatherers/web-app-manifest.js +5 -5
  159. package/core/gather/navigation-runner.d.ts +9 -9
  160. package/core/gather/navigation-runner.js +14 -8
  161. package/core/gather/runner-helpers.d.ts +3 -3
  162. package/core/gather/runner-helpers.js +12 -4
  163. package/core/gather/session.d.ts +2 -2
  164. package/core/gather/session.js +1 -1
  165. package/core/gather/snapshot-runner.d.ts +2 -2
  166. package/core/gather/snapshot-runner.js +1 -1
  167. package/core/gather/timespan-runner.d.ts +2 -2
  168. package/core/gather/timespan-runner.js +1 -1
  169. package/core/index.cjs +0 -7
  170. package/core/index.d.ts +0 -15
  171. package/core/index.js +2 -40
  172. package/core/lib/asset-saver.js +14 -4
  173. package/core/lib/axe.js +1 -1
  174. package/core/lib/dependency-graph/simulator/network-analyzer.d.ts +28 -12
  175. package/core/lib/dependency-graph/simulator/network-analyzer.js +128 -100
  176. package/core/lib/emulation.d.ts +14 -14
  177. package/core/lib/emulation.js +7 -7
  178. package/core/lib/navigation-error.js +5 -0
  179. package/core/lib/network-recorder.d.ts +2 -1
  180. package/core/lib/network-recorder.js +1 -0
  181. package/core/lib/network-request.js +12 -3
  182. package/core/lib/page-functions.d.ts +10 -2
  183. package/core/lib/page-functions.js +85 -8
  184. package/core/lib/sentry.js +9 -2
  185. package/core/lib/stack-packs.js +4 -0
  186. package/core/runner.d.ts +8 -30
  187. package/core/runner.js +8 -39
  188. package/core/user-flow.d.ts +4 -4
  189. package/core/user-flow.js +2 -2
  190. package/dist/report/bundle.esm.js +2221 -5832
  191. package/dist/report/flow.js +2631 -235
  192. package/dist/report/standalone.js +2586 -234
  193. package/flow-report/src/i18n/i18n.d.ts +2 -2
  194. package/package.json +17 -24
  195. package/readme.md +3 -1
  196. package/report/assets/templates.html +3 -1
  197. package/report/renderer/category-renderer.d.ts +3 -2
  198. package/report/renderer/category-renderer.js +8 -4
  199. package/report/renderer/components.js +11 -5
  200. package/report/renderer/pwa-category-renderer.js +1 -1
  201. package/report/renderer/report-ui-features.js +9 -6
  202. package/report/renderer/report-utils.d.ts +1 -1
  203. package/report/renderer/report-utils.js +2 -2
  204. package/report/renderer/topbar-features.js +3 -0
  205. package/shared/localization/locales/ar-XB.json +185 -44
  206. package/shared/localization/locales/ar.json +185 -44
  207. package/shared/localization/locales/bg.json +185 -44
  208. package/shared/localization/locales/ca.json +190 -49
  209. package/shared/localization/locales/cs.json +185 -44
  210. package/shared/localization/locales/da.json +185 -44
  211. package/shared/localization/locales/de.json +185 -44
  212. package/shared/localization/locales/el.json +185 -44
  213. package/shared/localization/locales/en-GB.json +185 -44
  214. package/shared/localization/locales/en-US.json +99 -45
  215. package/shared/localization/locales/en-XA.json +185 -44
  216. package/shared/localization/locales/en-XL.json +99 -45
  217. package/shared/localization/locales/es-419.json +185 -44
  218. package/shared/localization/locales/es.json +185 -44
  219. package/shared/localization/locales/fi.json +185 -44
  220. package/shared/localization/locales/fil.json +185 -44
  221. package/shared/localization/locales/fr.json +185 -44
  222. package/shared/localization/locales/he.json +186 -45
  223. package/shared/localization/locales/hi.json +185 -44
  224. package/shared/localization/locales/hr.json +185 -44
  225. package/shared/localization/locales/hu.json +185 -44
  226. package/shared/localization/locales/id.json +185 -44
  227. package/shared/localization/locales/it.json +185 -44
  228. package/shared/localization/locales/ja.json +185 -44
  229. package/shared/localization/locales/ko.json +185 -44
  230. package/shared/localization/locales/lt.json +185 -44
  231. package/shared/localization/locales/lv.json +185 -44
  232. package/shared/localization/locales/nl.json +185 -44
  233. package/shared/localization/locales/no.json +185 -44
  234. package/shared/localization/locales/pl.json +185 -44
  235. package/shared/localization/locales/pt-PT.json +185 -44
  236. package/shared/localization/locales/pt.json +190 -49
  237. package/shared/localization/locales/ro.json +185 -44
  238. package/shared/localization/locales/ru.json +185 -44
  239. package/shared/localization/locales/sk.json +185 -44
  240. package/shared/localization/locales/sl.json +185 -44
  241. package/shared/localization/locales/sr-Latn.json +185 -44
  242. package/shared/localization/locales/sr.json +185 -44
  243. package/shared/localization/locales/sv.json +185 -44
  244. package/shared/localization/locales/ta.json +185 -44
  245. package/shared/localization/locales/te.json +185 -44
  246. package/shared/localization/locales/th.json +185 -44
  247. package/shared/localization/locales/tr.json +185 -44
  248. package/shared/localization/locales/uk.json +185 -44
  249. package/shared/localization/locales/vi.json +185 -44
  250. package/shared/localization/locales/zh-HK.json +185 -44
  251. package/shared/localization/locales/zh-TW.json +185 -44
  252. package/shared/localization/locales/zh.json +185 -44
  253. package/third-party/esbuild-plugins-polyfills/LICENSE +3 -0
  254. package/third-party/esbuild-plugins-polyfills/README.md +7 -0
  255. package/third-party/esbuild-plugins-polyfills/esbuild-polyfills.d.ts +9 -0
  256. package/third-party/esbuild-plugins-polyfills/esbuild-polyfills.js +129 -0
  257. package/tsconfig.json +2 -1
  258. package/types/artifacts.d.ts +16 -45
  259. package/types/config.d.ts +10 -52
  260. package/types/externs.d.ts +0 -2
  261. package/types/gatherer.d.ts +24 -47
  262. package/types/internal/rxjs.d.ts +26 -0
  263. package/types/internal/smokehouse.d.ts +1 -3
  264. package/types/lh.d.ts +0 -2
  265. package/types/lhr/settings.d.ts +1 -1
  266. package/core/audits/metrics/first-contentful-paint-3g.d.ts +0 -15
  267. package/core/audits/metrics/first-contentful-paint-3g.js +0 -69
  268. package/core/audits/resource-summary.d.ts +0 -16
  269. package/core/audits/resource-summary.js +0 -104
  270. package/core/audits/service-worker.d.ts +0 -46
  271. package/core/audits/service-worker.js +0 -182
  272. package/core/gather/gatherers/gatherer.d.ts +0 -46
  273. package/core/gather/gatherers/gatherer.js +0 -58
  274. package/core/legacy/config/config.d.ts +0 -107
  275. package/core/legacy/config/config.js +0 -566
  276. package/core/legacy/config/legacy-default-config.d.ts +0 -4
  277. package/core/legacy/config/legacy-default-config.js +0 -87
  278. package/core/legacy/gather/connections/connection.d.ts +0 -77
  279. package/core/legacy/gather/connections/connection.js +0 -196
  280. package/core/legacy/gather/connections/cri.d.ts +0 -27
  281. package/core/legacy/gather/connections/cri.js +0 -162
  282. package/core/legacy/gather/connections/raw.d.ts +0 -20
  283. package/core/legacy/gather/connections/raw.js +0 -57
  284. package/core/legacy/gather/driver.d.ts +0 -216
  285. package/core/legacy/gather/driver.js +0 -480
  286. package/core/legacy/gather/gather-runner.d.ts +0 -166
  287. package/core/legacy/gather/gather-runner.js +0 -590
  288. package/types/internal/lighthouse-logger.d.ts +0 -34
@@ -1,216 +0,0 @@
1
- export type CrdpEventEmitter = LH.Protocol.StrictEventEmitter<LH.CrdpEvents>;
2
- /**
3
- * @typedef {LH.Protocol.StrictEventEmitter<LH.CrdpEvents>} CrdpEventEmitter
4
- */
5
- /**
6
- * @implements {LH.Gatherer.FRTransitionalDriver}
7
- */
8
- export class Driver implements LH.Gatherer.FRTransitionalDriver {
9
- /** @deprecated - Not available on Fraggle Rock driver. */
10
- static get traceCategories(): string[];
11
- /**
12
- * @param {import('./connections/connection.js').Connection} connection
13
- */
14
- constructor(connection: import('./connections/connection.js').Connection);
15
- /**
16
- * @pri_vate (This should be private, but that makes our tests harder).
17
- * An event emitter that enforces mapping between Crdp event names and payload types.
18
- */
19
- _eventEmitter: CrdpEventEmitter;
20
- /**
21
- * @private
22
- * Used to save network and lifecycle protocol traffic. Just Page and Network are needed.
23
- */
24
- private _devtoolsLog;
25
- /**
26
- * @private
27
- * @type {Map<string, number>}
28
- */
29
- private _domainEnabledCounts;
30
- /**
31
- * @type {number}
32
- * @private
33
- */
34
- private _nextProtocolTimeout;
35
- online: boolean;
36
- executionContext: ExecutionContext;
37
- defaultSession: Driver;
38
- fetcher: Fetcher;
39
- _connection: import("./connections/connection.js").Connection;
40
- /** @private @deprecated Only available for plugin backcompat. */
41
- private evaluate;
42
- /** @private @deprecated Only available for plugin backcompat. */
43
- private evaluateAsync;
44
- targetManager: {
45
- rootSession: () => Driver;
46
- mainFrameExecutionContexts: () => LH.Crdp.Runtime.ExecutionContextDescription[];
47
- /**
48
- * Bind to *any* protocol event.
49
- * @param {'protocolevent'} event
50
- * @param {(payload: LH.Protocol.RawEventMessage) => void} callback
51
- */
52
- on: (event: 'protocolevent', callback: (payload: LH.Protocol.RawEventMessage) => void) => void;
53
- /**
54
- * Unbind to *any* protocol event.
55
- * @param {'protocolevent'} event
56
- * @param {(payload: LH.Protocol.RawEventMessage) => void} callback
57
- */
58
- off: (event: 'protocolevent', callback: (payload: LH.Protocol.RawEventMessage) => void) => void;
59
- };
60
- /**
61
- * @return {Promise<LH.Crdp.Browser.GetVersionResponse & {milestone: number}>}
62
- */
63
- getBrowserVersion(): Promise<LH.Crdp.Browser.GetVersionResponse & {
64
- milestone: number;
65
- }>;
66
- /**
67
- * @return {Promise<void>}
68
- */
69
- connect(): Promise<void>;
70
- /**
71
- * @return {Promise<void>}
72
- */
73
- disconnect(): Promise<void>;
74
- /** @return {Promise<void>} */
75
- dispose(): Promise<void>;
76
- /**
77
- * Get the browser WebSocket endpoint for devtools protocol clients like Puppeteer.
78
- * Only works with WebSocket connection, not extension or devtools.
79
- * @return {Promise<string>}
80
- */
81
- wsEndpoint(): Promise<string>;
82
- /**
83
- * Bind listeners for protocol events.
84
- * @template {keyof LH.CrdpEvents} E
85
- * @param {E} eventName
86
- * @param {(...args: LH.CrdpEvents[E]) => void} cb
87
- */
88
- on<E extends keyof LH.CrdpEvents>(eventName: E, cb: (...args: LH.CrdpEvents[E]) => void): void;
89
- /**
90
- * Bind a one-time listener for protocol events. Listener is removed once it
91
- * has been called.
92
- * @template {keyof LH.CrdpEvents} E
93
- * @param {E} eventName
94
- * @param {(...args: LH.CrdpEvents[E]) => void} cb
95
- */
96
- once<E_1 extends keyof LH.CrdpEvents>(eventName: E_1, cb: (...args: LH.CrdpEvents[E_1]) => void): void;
97
- /**
98
- * Unbind event listener.
99
- * @template {keyof LH.CrdpEvents} E
100
- * @param {E} eventName
101
- * @param {Function} cb
102
- */
103
- off<E_2 extends keyof LH.CrdpEvents>(eventName: E_2, cb: Function): void;
104
- /** @param {LH.Crdp.Target.TargetInfo} targetInfo */
105
- setTargetInfo(targetInfo: LH.Crdp.Target.TargetInfo): void;
106
- /**
107
- * Debounce enabling or disabling domains to prevent driver users from
108
- * stomping on each other. Maintains an internal count of the times a domain
109
- * has been enabled. Returns false if the command would have no effect (domain
110
- * is already enabled or disabled), or if command would interfere with another
111
- * user of that domain (e.g. two gatherers have enabled a domain, both need to
112
- * disable it for it to be disabled). Returns true otherwise.
113
- * @param {string} domain
114
- * @param {string|undefined} sessionId
115
- * @param {boolean} enable
116
- * @return {boolean}
117
- * @private
118
- */
119
- private _shouldToggleDomain;
120
- /**
121
- * @return {boolean}
122
- */
123
- hasNextProtocolTimeout(): boolean;
124
- /**
125
- * @return {number}
126
- */
127
- getNextProtocolTimeout(): number;
128
- /**
129
- * timeout is used for the next call to 'sendCommand'.
130
- * NOTE: This can eventually be replaced when TypeScript
131
- * resolves https://github.com/Microsoft/TypeScript/issues/5453.
132
- * @param {number} timeout
133
- */
134
- setNextProtocolTimeout(timeout: number): void;
135
- /**
136
- * @param {LH.Protocol.RawEventMessage} event
137
- */
138
- _handleProtocolEvent(event: LH.Protocol.RawEventMessage): void;
139
- /**
140
- * @param {Error} error
141
- */
142
- _handleEventError(error: Error): void;
143
- /**
144
- * @param {LH.Crdp.Target.AttachedToTargetEvent} event
145
- */
146
- _handleTargetAttached(event: LH.Crdp.Target.AttachedToTargetEvent): Promise<void>;
147
- /**
148
- * Call protocol methods, with a timeout.
149
- * To configure the timeout for the next call, use 'setNextProtocolTimeout'.
150
- * If 'sessionId' is undefined, the message is sent to the main session.
151
- * @template {keyof LH.CrdpCommands} C
152
- * @param {C} method
153
- * @param {string|undefined} sessionId
154
- * @param {LH.CrdpCommands[C]['paramsType']} params
155
- * @return {Promise<LH.CrdpCommands[C]['returnType']>}
156
- */
157
- sendCommandToSession<C extends keyof LH.CrdpCommands>(method: C, sessionId: string | undefined, ...params: LH.CrdpCommands[C]["paramsType"]): Promise<LH.CrdpCommands[C]["returnType"]>;
158
- /**
159
- * Alias for 'sendCommandToSession(method, undefined, ...params)'
160
- * @template {keyof LH.CrdpCommands} C
161
- * @param {C} method
162
- * @param {LH.CrdpCommands[C]['paramsType']} params
163
- * @return {Promise<LH.CrdpCommands[C]['returnType']>}
164
- */
165
- sendCommand<C_1 extends keyof LH.CrdpCommands>(method: C_1, ...params: LH.CrdpCommands[C_1]["paramsType"]): Promise<LH.CrdpCommands[C_1]["returnType"]>;
166
- /**
167
- * Call protocol methods.
168
- * @private
169
- * @template {keyof LH.CrdpCommands} C
170
- * @param {C} method
171
- * @param {string|undefined} sessionId
172
- * @param {LH.CrdpCommands[C]['paramsType']} params
173
- * @return {Promise<LH.CrdpCommands[C]['returnType']>}
174
- */
175
- private _innerSendCommand;
176
- /**
177
- * Returns whether a domain is currently enabled.
178
- * @param {string} domain
179
- * @return {boolean}
180
- */
181
- isDomainEnabled(domain: string): boolean;
182
- /**
183
- * Return the body of the response with the given ID. Rejects if getting the
184
- * body times out.
185
- * @param {string} requestId
186
- * @param {number} [timeout]
187
- * @return {Promise<string>}
188
- */
189
- getRequestContent(requestId: string, timeout?: number | undefined): Promise<string>;
190
- /**
191
- * @param {{additionalTraceCategories?: string|null}=} settings
192
- * @return {Promise<void>}
193
- */
194
- beginTrace(settings?: {
195
- additionalTraceCategories?: string | null;
196
- } | undefined): Promise<void>;
197
- /**
198
- * @return {Promise<LH.Trace>}
199
- */
200
- endTrace(): Promise<LH.Trace>;
201
- /**
202
- * Begin recording devtools protocol messages.
203
- */
204
- beginDevtoolsLog(): Promise<void>;
205
- _disableAsyncStacks: (() => Promise<void>) | undefined;
206
- /**
207
- * Stop recording to devtoolsLog and return log contents.
208
- * @return {Promise<LH.DevtoolsLog>}
209
- */
210
- endDevtoolsLog(): Promise<LH.DevtoolsLog>;
211
- url(): Promise<string>;
212
- }
213
- import * as LH from '../../../types/lh.js';
214
- import { ExecutionContext } from '../../gather/driver/execution-context.js';
215
- import { Fetcher } from '../../gather/fetcher.js';
216
- //# sourceMappingURL=driver.d.ts.map
@@ -1,480 +0,0 @@
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
-
7
- import {EventEmitter} from 'events';
8
-
9
- import log from 'lighthouse-logger';
10
-
11
- import * as LH from '../../../types/lh.js';
12
- import {Fetcher} from '../../gather/fetcher.js';
13
- import {ExecutionContext} from '../../gather/driver/execution-context.js';
14
- import {LighthouseError} from '../../lib/lh-error.js';
15
- import {fetchResponseBodyFromCache} from '../../gather/driver/network.js';
16
- import {DevtoolsMessageLog} from '../../gather/gatherers/devtools-log.js';
17
- import TraceGatherer from '../../gather/gatherers/trace.js';
18
- import {getBrowserVersion} from '../../gather/driver/environment.js';
19
- import {enableAsyncStacks} from '../../gather/driver/prepare.js';
20
-
21
- // Controls how long to wait for a response after sending a DevTools protocol command.
22
- const DEFAULT_PROTOCOL_TIMEOUT = 30000;
23
-
24
- /**
25
- * @typedef {LH.Protocol.StrictEventEmitter<LH.CrdpEvents>} CrdpEventEmitter
26
- */
27
-
28
- /**
29
- * @implements {LH.Gatherer.FRTransitionalDriver}
30
- */
31
- class Driver {
32
- /**
33
- * @pri_vate (This should be private, but that makes our tests harder).
34
- * An event emitter that enforces mapping between Crdp event names and payload types.
35
- */
36
- _eventEmitter = /** @type {CrdpEventEmitter} */ (new EventEmitter());
37
-
38
- /**
39
- * @private
40
- * Used to save network and lifecycle protocol traffic. Just Page and Network are needed.
41
- */
42
- _devtoolsLog = new DevtoolsMessageLog(/^(Page|Network|Target|Runtime)\./);
43
-
44
- /**
45
- * @private
46
- * @type {Map<string, number>}
47
- */
48
- _domainEnabledCounts = new Map();
49
-
50
- /**
51
- * @type {number}
52
- * @private
53
- */
54
- _nextProtocolTimeout = DEFAULT_PROTOCOL_TIMEOUT;
55
-
56
- online = true;
57
-
58
- // eslint-disable-next-line no-invalid-this
59
- executionContext = new ExecutionContext(this);
60
-
61
- // eslint-disable-next-line no-invalid-this
62
- defaultSession = this;
63
-
64
- // eslint-disable-next-line no-invalid-this
65
- fetcher = new Fetcher(this.defaultSession);
66
-
67
- /**
68
- * @param {import('./connections/connection.js').Connection} connection
69
- */
70
- constructor(connection) {
71
- this._connection = connection;
72
-
73
- this.on('Target.attachedToTarget', event => {
74
- this._handleTargetAttached(event).catch(this._handleEventError);
75
- });
76
-
77
- this.on('Page.frameNavigated', event => {
78
- // We're only interested in setting autoattach on the root via this method.
79
- // `_handleTargetAttached` takes care of the recursive piece.
80
- if (event.frame.parentId) return;
81
-
82
- // Enable auto-attaching to subtargets so we receive iframe information.
83
- this.sendCommand('Target.setAutoAttach', {
84
- flatten: true,
85
- autoAttach: true,
86
- // Pause targets on startup so we don't miss anything
87
- waitForDebuggerOnStart: true,
88
- }).catch(this._handleEventError);
89
- });
90
-
91
- connection.on('protocolevent', this._handleProtocolEvent.bind(this));
92
-
93
- /** @private @deprecated Only available for plugin backcompat. */
94
- this.evaluate = this.executionContext.evaluate.bind(this.executionContext);
95
- /** @private @deprecated Only available for plugin backcompat. */
96
- this.evaluateAsync = this.executionContext.evaluateAsync.bind(this.executionContext);
97
-
98
- // A shim for sufficient coverage of targetManager functionality. Exposes the target
99
- // management that legacy driver already handles (see this._handleTargetAttached).
100
- this.targetManager = {
101
- rootSession: () => {
102
- return this.defaultSession;
103
- },
104
- // For legacy driver, only bother supporting access to the default execution context.
105
- mainFrameExecutionContexts: () => {
106
- // @ts-expect-error - undefined ids are OK for purposes of calling protocol commands like Runtime.evaluate.
107
- return [/** @type {LH.Crdp.Runtime.ExecutionContextDescription} */({
108
- id: undefined,
109
- uniqueId: undefined,
110
- origin: '',
111
- name: '',
112
- auxData: {isDefault: true, type: 'default', frameId: ''},
113
- })];
114
- },
115
- /**
116
- * Bind to *any* protocol event.
117
- * @param {'protocolevent'} event
118
- * @param {(payload: LH.Protocol.RawEventMessage) => void} callback
119
- */
120
- on: (event, callback) => {
121
- this._connection.on('protocolevent', callback);
122
- },
123
- /**
124
- * Unbind to *any* protocol event.
125
- * @param {'protocolevent'} event
126
- * @param {(payload: LH.Protocol.RawEventMessage) => void} callback
127
- */
128
- off: (event, callback) => {
129
- this._connection.off('protocolevent', callback);
130
- },
131
- };
132
- }
133
-
134
- /** @deprecated - Not available on Fraggle Rock driver. */
135
- static get traceCategories() {
136
- return TraceGatherer.getDefaultTraceCategories();
137
- }
138
-
139
- /**
140
- * @return {Promise<LH.Crdp.Browser.GetVersionResponse & {milestone: number}>}
141
- */
142
- async getBrowserVersion() {
143
- return getBrowserVersion(this);
144
- }
145
-
146
- /**
147
- * @return {Promise<void>}
148
- */
149
- async connect() {
150
- const status = {msg: 'Connecting to browser', id: 'lh:init:connect'};
151
- log.time(status);
152
- await this._connection.connect();
153
- log.timeEnd(status);
154
- }
155
-
156
- /**
157
- * @return {Promise<void>}
158
- */
159
- disconnect() {
160
- return this._connection.disconnect();
161
- }
162
-
163
- /** @return {Promise<void>} */
164
- dispose() {
165
- return this.disconnect();
166
- }
167
-
168
- /**
169
- * Get the browser WebSocket endpoint for devtools protocol clients like Puppeteer.
170
- * Only works with WebSocket connection, not extension or devtools.
171
- * @return {Promise<string>}
172
- */
173
- wsEndpoint() {
174
- return this._connection.wsEndpoint();
175
- }
176
-
177
- /**
178
- * Bind listeners for protocol events.
179
- * @template {keyof LH.CrdpEvents} E
180
- * @param {E} eventName
181
- * @param {(...args: LH.CrdpEvents[E]) => void} cb
182
- */
183
- on(eventName, cb) {
184
- if (this._eventEmitter === null) {
185
- throw new Error('connect() must be called before attempting to listen to events.');
186
- }
187
-
188
- // log event listeners being bound
189
- log.formatProtocol('listen for event =>', {method: eventName}, 'verbose');
190
- this._eventEmitter.on(eventName, cb);
191
- }
192
-
193
- /**
194
- * Bind a one-time listener for protocol events. Listener is removed once it
195
- * has been called.
196
- * @template {keyof LH.CrdpEvents} E
197
- * @param {E} eventName
198
- * @param {(...args: LH.CrdpEvents[E]) => void} cb
199
- */
200
- once(eventName, cb) {
201
- if (this._eventEmitter === null) {
202
- throw new Error('connect() must be called before attempting to listen to events.');
203
- }
204
- // log event listeners being bound
205
- log.formatProtocol('listen once for event =>', {method: eventName}, 'verbose');
206
- this._eventEmitter.once(eventName, cb);
207
- }
208
-
209
- /**
210
- * Unbind event listener.
211
- * @template {keyof LH.CrdpEvents} E
212
- * @param {E} eventName
213
- * @param {Function} cb
214
- */
215
- off(eventName, cb) {
216
- if (this._eventEmitter === null) {
217
- throw new Error('connect() must be called before attempting to remove an event listener.');
218
- }
219
-
220
- this._eventEmitter.removeListener(eventName, cb);
221
- }
222
-
223
- /** @param {LH.Crdp.Target.TargetInfo} targetInfo */
224
- setTargetInfo(targetInfo) { // eslint-disable-line no-unused-vars
225
- // OOPIF handling in legacy driver is implicit.
226
- }
227
-
228
- /**
229
- * Debounce enabling or disabling domains to prevent driver users from
230
- * stomping on each other. Maintains an internal count of the times a domain
231
- * has been enabled. Returns false if the command would have no effect (domain
232
- * is already enabled or disabled), or if command would interfere with another
233
- * user of that domain (e.g. two gatherers have enabled a domain, both need to
234
- * disable it for it to be disabled). Returns true otherwise.
235
- * @param {string} domain
236
- * @param {string|undefined} sessionId
237
- * @param {boolean} enable
238
- * @return {boolean}
239
- * @private
240
- */
241
- _shouldToggleDomain(domain, sessionId, enable) {
242
- const key = domain + (sessionId || '');
243
- const enabledCount = this._domainEnabledCounts.get(key) || 0;
244
- const newCount = enabledCount + (enable ? 1 : -1);
245
- this._domainEnabledCounts.set(key, Math.max(0, newCount));
246
-
247
- // Switching to enabled or disabled, respectively.
248
- if ((enable && newCount === 1) || (!enable && newCount === 0)) {
249
- log.verbose('Driver', `${domain}.${enable ? 'enable' : 'disable'}`);
250
- return true;
251
- } else {
252
- if (newCount < 0) {
253
- log.error('Driver', `Attempted to disable domain '${domain}' when already disabled.`);
254
- }
255
- return false;
256
- }
257
- }
258
-
259
- /**
260
- * @return {boolean}
261
- */
262
- hasNextProtocolTimeout() {
263
- return this._nextProtocolTimeout !== DEFAULT_PROTOCOL_TIMEOUT;
264
- }
265
-
266
- /**
267
- * @return {number}
268
- */
269
- getNextProtocolTimeout() {
270
- return this._nextProtocolTimeout;
271
- }
272
-
273
- /**
274
- * timeout is used for the next call to 'sendCommand'.
275
- * NOTE: This can eventually be replaced when TypeScript
276
- * resolves https://github.com/Microsoft/TypeScript/issues/5453.
277
- * @param {number} timeout
278
- */
279
- setNextProtocolTimeout(timeout) {
280
- this._nextProtocolTimeout = timeout;
281
- }
282
-
283
- /**
284
- * @param {LH.Protocol.RawEventMessage} event
285
- */
286
- _handleProtocolEvent(event) {
287
- this._devtoolsLog.record(event);
288
-
289
- // @ts-expect-error TODO(bckenny): tsc can't type event.params correctly yet,
290
- // typing as property of union instead of narrowing from union of
291
- // properties. See https://github.com/Microsoft/TypeScript/pull/22348.
292
- this._eventEmitter.emit(event.method, event.params);
293
- }
294
-
295
- /**
296
- * @param {Error} error
297
- */
298
- _handleEventError(error) {
299
- log.error('Driver', 'Unhandled event error', error.message);
300
- }
301
-
302
- /**
303
- * @param {LH.Crdp.Target.AttachedToTargetEvent} event
304
- */
305
- async _handleTargetAttached(event) {
306
- // We're only interested in network requests from iframes for now as those are "part of the page".
307
- // If it's not an iframe, just resume it and move on.
308
- if (event.targetInfo.type !== 'iframe') {
309
- // We suspended the target when we auto-attached, so make sure it goes back to being normal.
310
- await this.sendCommandToSession('Runtime.runIfWaitingForDebugger', event.sessionId);
311
- return;
312
- }
313
-
314
- // Note: This is only reached for _out of process_ iframes (OOPIFs).
315
- // If the iframe is in the same process as its embedding document, that means they
316
- // share the same target.
317
-
318
- // A target won't acknowledge/respond to protocol methods (or, at least for Network.enable)
319
- // until it is resumed. But also we're paranoid about sending Network.enable _slightly_ too late,
320
- // so we issue that method first. Therefore, we don't await on this serially, but await all at once.
321
- await Promise.all([
322
- // Events from subtargets will be stringified and sent back on `Target.receivedMessageFromTarget`.
323
- // We want to receive information about network requests from iframes, so enable the Network domain.
324
- this.sendCommandToSession('Network.enable', event.sessionId),
325
- // We also want to receive information about subtargets of subtargets, so make sure we autoattach recursively.
326
- this.sendCommandToSession('Target.setAutoAttach', event.sessionId, {
327
- autoAttach: true,
328
- flatten: true,
329
- // Pause targets on startup so we don't miss anything
330
- waitForDebuggerOnStart: true,
331
- }),
332
- // We suspended the target when we auto-attached, so make sure it goes back to being normal.
333
- this.sendCommandToSession('Runtime.runIfWaitingForDebugger', event.sessionId),
334
- ]);
335
- }
336
-
337
- /**
338
- * Call protocol methods, with a timeout.
339
- * To configure the timeout for the next call, use 'setNextProtocolTimeout'.
340
- * If 'sessionId' is undefined, the message is sent to the main session.
341
- * @template {keyof LH.CrdpCommands} C
342
- * @param {C} method
343
- * @param {string|undefined} sessionId
344
- * @param {LH.CrdpCommands[C]['paramsType']} params
345
- * @return {Promise<LH.CrdpCommands[C]['returnType']>}
346
- */
347
- sendCommandToSession(method, sessionId, ...params) {
348
- const timeout = this._nextProtocolTimeout;
349
- this._nextProtocolTimeout = DEFAULT_PROTOCOL_TIMEOUT;
350
-
351
- /** @type {NodeJS.Timer|undefined} */
352
- let asyncTimeout;
353
- const timeoutPromise = new Promise((resolve, reject) => {
354
- if (timeout === Infinity) return;
355
- // eslint-disable-next-line max-len
356
- asyncTimeout = setTimeout(reject, timeout, new LighthouseError(LighthouseError.errors.PROTOCOL_TIMEOUT, {
357
- protocolMethod: method,
358
- }));
359
- });
360
-
361
- return Promise.race([
362
- this._innerSendCommand(method, sessionId, ...params),
363
- timeoutPromise,
364
- ]).finally(() => {
365
- asyncTimeout && clearTimeout(asyncTimeout);
366
- });
367
- }
368
-
369
- /**
370
- * Alias for 'sendCommandToSession(method, undefined, ...params)'
371
- * @template {keyof LH.CrdpCommands} C
372
- * @param {C} method
373
- * @param {LH.CrdpCommands[C]['paramsType']} params
374
- * @return {Promise<LH.CrdpCommands[C]['returnType']>}
375
- */
376
- sendCommand(method, ...params) {
377
- return this.sendCommandToSession(method, undefined, ...params);
378
- }
379
-
380
- /**
381
- * Call protocol methods.
382
- * @private
383
- * @template {keyof LH.CrdpCommands} C
384
- * @param {C} method
385
- * @param {string|undefined} sessionId
386
- * @param {LH.CrdpCommands[C]['paramsType']} params
387
- * @return {Promise<LH.CrdpCommands[C]['returnType']>}
388
- */
389
- _innerSendCommand(method, sessionId, ...params) {
390
- const domainCommand = /^(\w+)\.(enable|disable)$/.exec(method);
391
- if (domainCommand) {
392
- const enable = domainCommand[2] === 'enable';
393
- if (!this._shouldToggleDomain(domainCommand[1], sessionId, enable)) {
394
- return Promise.resolve();
395
- }
396
- }
397
- return this._connection.sendCommand(method, sessionId, ...params);
398
- }
399
-
400
- /**
401
- * Returns whether a domain is currently enabled.
402
- * @param {string} domain
403
- * @return {boolean}
404
- */
405
- isDomainEnabled(domain) {
406
- // Defined, non-zero elements of the domains map are enabled.
407
- return !!this._domainEnabledCounts.get(domain);
408
- }
409
-
410
- /**
411
- * Return the body of the response with the given ID. Rejects if getting the
412
- * body times out.
413
- * @param {string} requestId
414
- * @param {number} [timeout]
415
- * @return {Promise<string>}
416
- */
417
- async getRequestContent(requestId, timeout = 1000) {
418
- return fetchResponseBodyFromCache(this.defaultSession, requestId, timeout);
419
- }
420
-
421
- /**
422
- * @param {{additionalTraceCategories?: string|null}=} settings
423
- * @return {Promise<void>}
424
- */
425
- async beginTrace(settings) {
426
- const additionalCategories = (settings?.additionalTraceCategories &&
427
- settings.additionalTraceCategories.split(',')) || [];
428
- const traceCategories = TraceGatherer.getDefaultTraceCategories().concat(additionalCategories);
429
-
430
- const uniqueCategories = Array.from(new Set(traceCategories));
431
-
432
- // Check any domains that could interfere with or add overhead to the trace.
433
- if (this.isDomainEnabled('CSS')) {
434
- throw new Error('CSS domain enabled when starting trace');
435
- }
436
- if (this.isDomainEnabled('DOM')) {
437
- throw new Error('DOM domain enabled when starting trace');
438
- }
439
-
440
- // Enable Page domain to wait for Page.loadEventFired
441
- return this.sendCommand('Page.enable')
442
- .then(_ => this.sendCommand('Tracing.start', {
443
- categories: uniqueCategories.join(','),
444
- options: 'sampling-frequency=10000', // 1000 is default and too slow.
445
- }));
446
- }
447
-
448
- /**
449
- * @return {Promise<LH.Trace>}
450
- */
451
- endTrace() {
452
- return TraceGatherer.endTraceAndCollectEvents(this.defaultSession);
453
- }
454
-
455
- /**
456
- * Begin recording devtools protocol messages.
457
- */
458
- async beginDevtoolsLog() {
459
- this._disableAsyncStacks = await enableAsyncStacks(this);
460
- this._devtoolsLog.reset();
461
- this._devtoolsLog.beginRecording();
462
- }
463
-
464
- /**
465
- * Stop recording to devtoolsLog and return log contents.
466
- * @return {Promise<LH.DevtoolsLog>}
467
- */
468
- async endDevtoolsLog() {
469
- this._devtoolsLog.endRecording();
470
- await this._disableAsyncStacks?.();
471
- return this._devtoolsLog.messages;
472
- }
473
-
474
- async url() {
475
- const {frameTree} = await this.sendCommand('Page.getFrameTree');
476
- return `${frameTree.frame.url}${frameTree.frame.urlFragment || ''}`;
477
- }
478
- }
479
-
480
- export {Driver};