browser-debugger-cli 0.8.0 → 0.9.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 (251) hide show
  1. package/README.md +4 -1
  2. package/dist/cdp/schema.d.ts +4 -1
  3. package/dist/cdp/schema.js +48 -7
  4. package/dist/commands/cdp.js +3 -2
  5. package/dist/commands/cleanup.d.ts +11 -0
  6. package/dist/commands/cleanup.js +161 -57
  7. package/dist/commands/console.d.ts +20 -1
  8. package/dist/commands/console.js +57 -17
  9. package/dist/commands/details.js +3 -2
  10. package/dist/commands/dom/DomElementResolver.d.ts +10 -3
  11. package/dist/commands/dom/DomElementResolver.js +35 -17
  12. package/dist/commands/dom/a11y.d.ts +10 -0
  13. package/dist/commands/dom/a11y.js +27 -5
  14. package/dist/commands/dom/eval.d.ts +3 -1
  15. package/dist/commands/dom/eval.js +29 -4
  16. package/dist/commands/dom/form.js +16 -62
  17. package/dist/commands/dom/formInteraction.js +152 -113
  18. package/dist/commands/dom/formSummary.d.ts +49 -0
  19. package/dist/commands/dom/formSummary.js +180 -0
  20. package/dist/commands/dom/frames.d.ts +2 -1
  21. package/dist/commands/dom/frames.js +17 -2
  22. package/dist/commands/dom/get.d.ts +6 -5
  23. package/dist/commands/dom/get.js +92 -82
  24. package/dist/commands/dom/helpers/index.d.ts +1 -1
  25. package/dist/commands/dom/helpers/index.js +1 -1
  26. package/dist/commands/dom/helpers/query.d.ts +44 -17
  27. package/dist/commands/dom/helpers/query.js +244 -97
  28. package/dist/commands/dom/helpers/runElementCommand.d.ts +10 -2
  29. package/dist/commands/dom/helpers/runElementCommand.js +97 -30
  30. package/dist/commands/dom/helpers/screenshot.d.ts +4 -1
  31. package/dist/commands/dom/helpers/screenshot.js +164 -49
  32. package/dist/commands/dom/index.d.ts +3 -1
  33. package/dist/commands/dom/index.js +16 -6
  34. package/dist/commands/dom/layout.d.ts +14 -0
  35. package/dist/commands/dom/layout.js +54 -0
  36. package/dist/commands/dom/listeners.d.ts +5 -1
  37. package/dist/commands/dom/listeners.js +13 -3
  38. package/dist/commands/dom/query.js +2 -3
  39. package/dist/commands/dom/screenshot.d.ts +12 -2
  40. package/dist/commands/dom/screenshot.js +27 -3
  41. package/dist/commands/dom/semanticUtils.d.ts +6 -13
  42. package/dist/commands/dom/semanticUtils.js +15 -19
  43. package/dist/commands/dom/wait.d.ts +13 -0
  44. package/dist/commands/dom/wait.js +83 -0
  45. package/dist/commands/helpJson.js +2 -2
  46. package/dist/commands/network/list.js +4 -11
  47. package/dist/commands/optionBehaviors.js +112 -21
  48. package/dist/commands/page.d.ts +2 -1
  49. package/dist/commands/page.js +41 -5
  50. package/dist/commands/peek.js +4 -11
  51. package/dist/commands/sessions.d.ts +8 -0
  52. package/dist/commands/sessions.js +19 -0
  53. package/dist/commands/shared/CommandRunner.js +4 -4
  54. package/dist/commands/shared/dataFetcher.js +2 -2
  55. package/dist/commands/shared/followMode.d.ts +21 -1
  56. package/dist/commands/shared/followMode.js +29 -2
  57. package/dist/commands/shared/handleValidationError.d.ts +2 -2
  58. package/dist/commands/shared/handleValidationError.js +12 -3
  59. package/dist/commands/shared/optionTypes.d.ts +40 -5
  60. package/dist/commands/shared/startHelpers.js +12 -3
  61. package/dist/commands/shared/validation.d.ts +3 -2
  62. package/dist/commands/shared/validation.js +4 -3
  63. package/dist/commands/start.d.ts +63 -0
  64. package/dist/commands/start.js +115 -15
  65. package/dist/commands/status.js +29 -7
  66. package/dist/commands/stop.js +7 -6
  67. package/dist/commands/tail.js +4 -11
  68. package/dist/commands/types.d.ts +2 -0
  69. package/dist/commands.js +2 -0
  70. package/dist/connection/chromeIdentity.d.ts +65 -0
  71. package/dist/connection/chromeIdentity.js +143 -0
  72. package/dist/connection/launcher/profilePreferences.d.ts +47 -0
  73. package/dist/connection/launcher/profilePreferences.js +151 -0
  74. package/dist/connection/launcher.d.ts +21 -2
  75. package/dist/connection/launcher.js +42 -16
  76. package/dist/connection/portReservation.d.ts +14 -4
  77. package/dist/connection/portReservation.js +21 -6
  78. package/dist/connection/startupExit.d.ts +8 -0
  79. package/dist/connection/startupExit.js +15 -6
  80. package/dist/constants.d.ts +6 -2
  81. package/dist/constants.js +9 -2
  82. package/dist/daemon/SessionController.js +23 -7
  83. package/dist/daemon/errors.d.ts +1 -1
  84. package/dist/daemon/errors.js +1 -1
  85. package/dist/daemon/launcher.d.ts +2 -1
  86. package/dist/daemon/launcher.js +5 -6
  87. package/dist/daemon/server/SocketServer.js +1 -2
  88. package/dist/daemon/session/Session.d.ts +13 -0
  89. package/dist/daemon/session/Session.js +57 -8
  90. package/dist/daemon/session/chromeConnection.d.ts +9 -0
  91. package/dist/daemon/session/chromeConnection.js +45 -8
  92. package/dist/daemon/session/commandRegistry.js +52 -62
  93. package/dist/daemon/session/interactions.d.ts +35 -9
  94. package/dist/daemon/session/interactions.js +36 -9
  95. package/dist/daemon/session/triggeredRequests.d.ts +67 -0
  96. package/dist/daemon/session/triggeredRequests.js +157 -0
  97. package/dist/daemon/session/types.d.ts +5 -1
  98. package/dist/daemon.js +5393 -1600
  99. package/dist/errors/messages.d.ts +387 -24
  100. package/dist/errors/messages.js +761 -67
  101. package/dist/index.js +3976 -1558
  102. package/dist/ipc/client.d.ts +12 -1
  103. package/dist/ipc/client.js +22 -3
  104. package/dist/ipc/protocol/commands.d.ts +89 -4
  105. package/dist/ipc/protocol/commands.js +2 -0
  106. package/dist/ipc/protocol/domTypes.d.ts +258 -7
  107. package/dist/ipc/session/lifecycle.d.ts +8 -1
  108. package/dist/ipc/session/queries.d.ts +5 -1
  109. package/dist/ipc/session/types.d.ts +5 -0
  110. package/dist/ipc/transport/index.d.ts +2 -1
  111. package/dist/ipc/transport/index.js +2 -2
  112. package/dist/runtime/dom/actionEffects.d.ts +106 -0
  113. package/dist/runtime/dom/actionEffects.js +256 -0
  114. package/dist/runtime/dom/actionEffectsScripts.d.ts +52 -0
  115. package/dist/runtime/dom/actionEffectsScripts.js +234 -0
  116. package/dist/runtime/dom/elementGeometry.d.ts +170 -0
  117. package/dist/runtime/dom/elementGeometry.js +553 -0
  118. package/dist/runtime/dom/elementInfo.d.ts +77 -0
  119. package/dist/runtime/dom/elementInfo.js +191 -0
  120. package/dist/runtime/dom/evalHelpers.d.ts +51 -6
  121. package/dist/runtime/dom/evalHelpers.js +136 -26
  122. package/dist/runtime/dom/eventListeners.d.ts +2 -1
  123. package/dist/runtime/dom/eventListeners.js +174 -47
  124. package/dist/runtime/dom/formDiscovery.d.ts +1 -1
  125. package/dist/runtime/dom/formDiscovery.js +116 -16
  126. package/dist/runtime/dom/formFillHelpers/fill.d.ts +10 -0
  127. package/dist/runtime/dom/formFillHelpers/fill.js +125 -10
  128. package/dist/runtime/dom/formFillHelpers/index.d.ts +2 -2
  129. package/dist/runtime/dom/formFillHelpers/index.js +2 -2
  130. package/dist/runtime/dom/formFillHelpers/pressKey.js +14 -3
  131. package/dist/runtime/dom/formFillHelpers/scroll.d.ts +3 -0
  132. package/dist/runtime/dom/formFillHelpers/scroll.js +60 -18
  133. package/dist/runtime/dom/formFillHelpers/shared.d.ts +17 -0
  134. package/dist/runtime/dom/formFillHelpers/shared.js +25 -1
  135. package/dist/runtime/dom/formFillHelpers/stability.d.ts +20 -6
  136. package/dist/runtime/dom/formFillHelpers/stability.js +50 -19
  137. package/dist/runtime/dom/formSubmitHelpers.d.ts +3 -0
  138. package/dist/runtime/dom/formSubmitHelpers.js +89 -15
  139. package/dist/runtime/dom/frameLayout.d.ts +60 -0
  140. package/dist/runtime/dom/frameLayout.js +140 -0
  141. package/dist/runtime/dom/frameOrigin.d.ts +50 -0
  142. package/dist/runtime/dom/frameOrigin.js +62 -0
  143. package/dist/runtime/dom/frameScopedConnection.d.ts +92 -0
  144. package/dist/runtime/dom/frameScopedConnection.js +252 -0
  145. package/dist/runtime/dom/frameSelection.d.ts +1 -1
  146. package/dist/runtime/dom/frameSelection.js +2 -2
  147. package/dist/runtime/dom/frames.d.ts +25 -2
  148. package/dist/runtime/dom/frames.js +202 -63
  149. package/dist/runtime/dom/layout.d.ts +67 -0
  150. package/dist/runtime/dom/layout.js +333 -0
  151. package/dist/runtime/dom/listenerPageScripts.d.ts +66 -0
  152. package/dist/runtime/dom/listenerPageScripts.js +279 -0
  153. package/dist/runtime/dom/listenerSummary.d.ts +132 -11
  154. package/dist/runtime/dom/listenerSummary.js +344 -22
  155. package/dist/runtime/dom/pageActivity.d.ts +41 -0
  156. package/dist/runtime/dom/pageActivity.js +123 -0
  157. package/dist/runtime/dom/reactEventHelpers.d.ts +58 -2
  158. package/dist/runtime/dom/reactEventHelpers.js +212 -41
  159. package/dist/runtime/dom/targetNode.d.ts +80 -27
  160. package/dist/runtime/dom/targetNode.js +249 -33
  161. package/dist/runtime/dom/wait.d.ts +25 -0
  162. package/dist/runtime/dom/wait.js +199 -0
  163. package/dist/runtime/dom/waitCondition.d.ts +71 -0
  164. package/dist/runtime/dom/waitCondition.js +75 -0
  165. package/dist/runtime/page/emulation.d.ts +51 -0
  166. package/dist/runtime/page/emulation.js +80 -0
  167. package/dist/runtime/page/loadingState.d.ts +36 -0
  168. package/dist/runtime/page/loadingState.js +86 -0
  169. package/dist/runtime/page/navigation.d.ts +46 -2
  170. package/dist/runtime/page/navigation.js +69 -33
  171. package/dist/session/QueryCacheManager.d.ts +11 -1
  172. package/dist/session/QueryCacheManager.js +25 -3
  173. package/dist/session/chromeOwners.d.ts +34 -0
  174. package/dist/session/chromeOwners.js +51 -0
  175. package/dist/session/cleanup/staleSession.d.ts +11 -1
  176. package/dist/session/cleanup/staleSession.js +17 -6
  177. package/dist/session/cleanup/userCommands.js +2 -4
  178. package/dist/session/metadata.d.ts +5 -1
  179. package/dist/session/metadata.js +2 -1
  180. package/dist/session/paths.d.ts +77 -3
  181. package/dist/session/paths.js +111 -5
  182. package/dist/session/port.d.ts +31 -7
  183. package/dist/session/port.js +50 -43
  184. package/dist/session/portClaims.d.ts +66 -0
  185. package/dist/session/portClaims.js +284 -0
  186. package/dist/session/sessionList.d.ts +58 -0
  187. package/dist/session/sessionList.js +199 -0
  188. package/dist/session/sessionName.d.ts +46 -0
  189. package/dist/session/sessionName.js +97 -0
  190. package/dist/telemetry/a11y.d.ts +8 -3
  191. package/dist/telemetry/a11y.js +92 -28
  192. package/dist/telemetry/requestKinds.d.ts +32 -0
  193. package/dist/telemetry/requestKinds.js +61 -0
  194. package/dist/telemetry/requestState.d.ts +31 -0
  195. package/dist/telemetry/requestState.js +38 -0
  196. package/dist/types.d.ts +80 -3
  197. package/dist/ui/formatters/a11y.js +3 -0
  198. package/dist/ui/formatters/console/chronological.d.ts +8 -0
  199. package/dist/ui/formatters/console/chronological.js +17 -4
  200. package/dist/ui/formatters/console/json.js +3 -4
  201. package/dist/ui/formatters/console/shared.d.ts +12 -0
  202. package/dist/ui/formatters/console.d.ts +2 -2
  203. package/dist/ui/formatters/console.js +1 -1
  204. package/dist/ui/formatters/details.js +2 -1
  205. package/dist/ui/formatters/dom.d.ts +26 -14
  206. package/dist/ui/formatters/dom.js +65 -52
  207. package/dist/ui/formatters/form.js +29 -18
  208. package/dist/ui/formatters/layout.d.ts +31 -0
  209. package/dist/ui/formatters/layout.js +53 -0
  210. package/dist/ui/formatters/listeners.d.ts +3 -2
  211. package/dist/ui/formatters/listeners.js +73 -9
  212. package/dist/ui/formatters/networkHeaders.js +13 -0
  213. package/dist/ui/formatters/preview.js +2 -1
  214. package/dist/ui/formatters/requestStatus.d.ts +1 -17
  215. package/dist/ui/formatters/requestStatus.js +2 -30
  216. package/dist/ui/formatters/sessions.d.ts +12 -0
  217. package/dist/ui/formatters/sessions.js +40 -0
  218. package/dist/ui/formatters/status.d.ts +21 -2
  219. package/dist/ui/formatters/status.js +47 -10
  220. package/dist/ui/formatters/triggeredRequests.d.ts +36 -0
  221. package/dist/ui/formatters/triggeredRequests.js +65 -0
  222. package/dist/ui/formatting.d.ts +10 -0
  223. package/dist/ui/formatting.js +28 -36
  224. package/dist/ui/messages/chrome.d.ts +9 -0
  225. package/dist/ui/messages/chrome.js +17 -5
  226. package/dist/ui/messages/commands.d.ts +388 -14
  227. package/dist/ui/messages/commands.js +664 -21
  228. package/dist/ui/messages/consoleMessages.d.ts +10 -0
  229. package/dist/ui/messages/consoleMessages.js +17 -0
  230. package/dist/ui/messages/hints.js +2 -1
  231. package/dist/ui/messages/preview.js +5 -4
  232. package/dist/ui/messages/session.d.ts +16 -21
  233. package/dist/ui/messages/session.js +28 -26
  234. package/dist/ui/messages/sessionCommand.d.ts +43 -0
  235. package/dist/ui/messages/sessionCommand.js +52 -0
  236. package/dist/utils/async.d.ts +8 -0
  237. package/dist/utils/async.js +19 -0
  238. package/dist/utils/http.d.ts +22 -1
  239. package/dist/utils/http.js +28 -9
  240. package/dist/utils/selectorFilters.d.ts +36 -8
  241. package/dist/utils/selectorFilters.js +267 -53
  242. package/dist/utils/shellDetection.d.ts +8 -2
  243. package/dist/utils/shellDetection.js +120 -33
  244. package/dist/utils/suggestions.d.ts +26 -0
  245. package/dist/utils/suggestions.js +73 -0
  246. package/dist/utils/taskMappings.js +10 -0
  247. package/dist/utils/url.d.ts +12 -2
  248. package/dist/utils/url.js +69 -7
  249. package/package.json +1 -1
  250. package/dist/ui/formatters/sessionFormatters.d.ts +0 -58
  251. package/dist/ui/formatters/sessionFormatters.js +0 -121
@@ -1,12 +1,22 @@
1
1
  /**
2
2
  * Running page interactions (fill, click, submit, pressKey, scroll) one at a
3
- * time, reporting the dialogs they caused.
3
+ * time, reporting the dialogs, network requests and page changes they caused.
4
4
  */
5
+ import { watchActionEffects } from '../../runtime/dom/actionEffects.js';
6
+ import { UNBIND_TARGET_SCRIPT } from '../../runtime/dom/targetNode.js';
5
7
  import { createLogger } from '../../ui/logging/index.js';
6
8
  import { getErrorMessage } from '../../utils/errors.js';
9
+ import { watchTriggeredRequests } from './triggeredRequests.js';
7
10
  const log = createLogger('dom');
8
- /** Removes the node bound for index-based commands from the page */
9
- const UNBIND_TARGET_SCRIPT = 'delete window.__bdgTarget';
11
+ /**
12
+ * Whether an action result is a success (results without a `success` flag are).
13
+ *
14
+ * @param result - Action result
15
+ * @returns False for `{ success: false }`
16
+ */
17
+ function succeeded(result) {
18
+ return !('success' in result) || result.success !== false;
19
+ }
10
20
  /**
11
21
  * Create the runner for a session's interactions.
12
22
  *
@@ -14,24 +24,41 @@ const UNBIND_TARGET_SCRIPT = 'delete window.__bdgTarget';
14
24
  * commands would interleave keystrokes into each other's field, so they are
15
25
  * queued. After each one, the bound target (`window.__bdgTarget`) is removed
16
26
  * from the page (without waiting: during a pending navigation that takes until
17
- * the new page commits), and the dialogs it opened are added to its result.
18
- * Dialogs are attributed by time: one opened by a page timer or a navigation
19
- * started earlier is reported by whichever interaction is running then.
27
+ * the new page commits), and the dialogs it opened, what it changed on the
28
+ * page (see {@link watchActionEffects}) and the network requests it
29
+ * triggered (see {@link watchTriggeredRequests}) are added to its result.
30
+ * They are attributed by time: a dialog or request started by a page timer
31
+ * or a navigation started earlier is reported by whichever interaction is
32
+ * running then.
20
33
  *
21
- * @param store - Session store recording accepted dialogs
34
+ * @param store - Session store recording accepted dialogs and network requests
22
35
  * @returns Interaction runner
23
36
  */
24
37
  export function createInteractionRunner(store) {
25
38
  let queue = Promise.resolve();
26
- return (cdp, action) => {
39
+ return (cdp, action, options = {}) => {
27
40
  const run = queue.then(async () => {
28
41
  const firstDialog = store.dialogs.length;
42
+ const collectRequests = options.reportRequests === false ? undefined : watchTriggeredRequests(store);
43
+ const effects = options.reportEffects === false ? undefined : watchActionEffects(cdp);
29
44
  try {
30
45
  const result = await action();
31
46
  const dialogs = store.dialogs.slice(firstDialog);
32
- return dialogs.length > 0 ? { ...result, dialogs } : result;
47
+ const changes = succeeded(result)
48
+ ? await effects?.collect({
49
+ dialogs: dialogs.length,
50
+ detectNoEffect: options.detectNoEffect === true,
51
+ })
52
+ : undefined;
53
+ return {
54
+ ...result,
55
+ ...(dialogs.length > 0 && { dialogs }),
56
+ ...changes,
57
+ ...(succeeded(result) && collectRequests?.()),
58
+ };
33
59
  }
34
60
  finally {
61
+ effects?.dispose();
35
62
  void cdp
36
63
  .send('Runtime.evaluate', { expression: UNBIND_TARGET_SCRIPT })
37
64
  .catch((error) => log.debug(`Target not unbound: ${getErrorMessage(error)}`));
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Network requests an interaction triggered, read from the session's network
3
+ * telemetry (no CDP listeners of its own).
4
+ */
5
+ import type { TelemetryStore } from './TelemetryStore.js';
6
+ import type { TriggeredRequest } from '../../ipc/protocol/domTypes.js';
7
+ import type { NetworkRequest } from '../../types.js';
8
+ /**
9
+ * Requests listed in a result (a click that loads a page triggers its whole
10
+ * load); notable ones ({@link isNotableRequest}) are kept before assets
11
+ */
12
+ export declare const MAX_TRIGGERED_REQUESTS = 50;
13
+ /** Requests started since the watch began: the first ones, and how many more there were */
14
+ export interface CollectedRequests {
15
+ triggeredRequests: TriggeredRequest[];
16
+ triggeredRequestsOmitted?: number;
17
+ }
18
+ /** Lists the requests started since the watch began */
19
+ export type TriggeredRequestsCollector = () => CollectedRequests | undefined;
20
+ /**
21
+ * Start attributing requests to an interaction.
22
+ *
23
+ * Requests are attributed by time: every request (and WebSocket connection)
24
+ * bdg saw start between this call and the collector's call belongs to the
25
+ * interaction, including one a page timer or poller happened to start
26
+ * meanwhile. Collecting adds no wait: requests
27
+ * still running then are reported as pending.
28
+ *
29
+ * @param store - Session store holding the network telemetry
30
+ * @returns Collector (at most {@link MAX_TRIGGERED_REQUESTS} requests, plus how
31
+ * many more there were); it returns undefined when network telemetry is off
32
+ */
33
+ export declare function watchTriggeredRequests(store: TelemetryStore): TriggeredRequestsCollector;
34
+ /**
35
+ * At most `limit` requests, notable ones first (pages, API calls, sockets,
36
+ * failures), then assets, still in start order.
37
+ *
38
+ * @param requests - Requests in start order
39
+ * @param limit - How many to keep
40
+ * @returns Kept requests, in start order
41
+ */
42
+ export declare function keepNotableFirst(requests: TriggeredRequest[], limit: number): TriggeredRequest[];
43
+ /**
44
+ * Count a submission's network requests as its request list does (the
45
+ * submit watcher counts every request id CDP reported until the wait ended:
46
+ * `data:` URLs and preflights included, a redirect chain once), so
47
+ * `networkRequests`, the listed requests and JSON agree. Without network
48
+ * telemetry the watcher's count stays.
49
+ *
50
+ * @param result - Submit result with the requests it triggered
51
+ * @returns The result, `networkRequests` matching `triggeredRequests`
52
+ */
53
+ export declare function withTriggeredRequestCount<T extends {
54
+ networkRequests?: number | undefined;
55
+ triggeredRequests?: TriggeredRequest[] | undefined;
56
+ triggeredRequestsOmitted?: number | undefined;
57
+ }>(result: T): T;
58
+ /**
59
+ * Summarize a captured request.
60
+ *
61
+ * @param request - Captured request
62
+ * @param inFlight - Whether it was still in flight (a request with a response
63
+ * is then still loading its body: a stream, a slow download)
64
+ * @returns Triggered request entry
65
+ */
66
+ export declare function toTriggeredRequest(request: NetworkRequest, inFlight?: boolean): TriggeredRequest;
67
+ //# sourceMappingURL=triggeredRequests.d.ts.map
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Network requests an interaction triggered, read from the session's network
3
+ * telemetry (no CDP listeners of its own).
4
+ */
5
+ import { isNotableRequest } from '../../telemetry/requestKinds.js';
6
+ import { failureReason, getRequestState } from '../../telemetry/requestState.js';
7
+ /** URLs that never reach the network (inline data, in-page objects) */
8
+ const LOCAL_URL_PATTERN = /^(data|blob):/i;
9
+ /**
10
+ * Requests listed in a result (a click that loads a page triggers its whole
11
+ * load); notable ones ({@link isNotableRequest}) are kept before assets
12
+ */
13
+ export const MAX_TRIGGERED_REQUESTS = 50;
14
+ /**
15
+ * Start attributing requests to an interaction.
16
+ *
17
+ * Requests are attributed by time: every request (and WebSocket connection)
18
+ * bdg saw start between this call and the collector's call belongs to the
19
+ * interaction, including one a page timer or poller happened to start
20
+ * meanwhile. Collecting adds no wait: requests
21
+ * still running then are reported as pending.
22
+ *
23
+ * @param store - Session store holding the network telemetry
24
+ * @returns Collector (at most {@link MAX_TRIGGERED_REQUESTS} requests, plus how
25
+ * many more there were); it returns undefined when network telemetry is off
26
+ */
27
+ export function watchTriggeredRequests(store) {
28
+ if (!store.activeTelemetry.includes('network'))
29
+ return () => undefined;
30
+ const startedAt = Date.now();
31
+ const firstFinished = store.networkRequests.length;
32
+ const firstWebSocket = store.websocketConnections.length;
33
+ return () => {
34
+ const started = [
35
+ ...store.networkRequests.slice(firstFinished).map((request) => ({ request })),
36
+ ...[...store.pendingNetworkRequests.values()].map((pending) => ({
37
+ request: pending.request,
38
+ inFlight: true,
39
+ })),
40
+ ...store.websocketConnections
41
+ .slice(firstWebSocket)
42
+ .map((connection) => ({ request: webSocketAsRequest(connection) })),
43
+ ]
44
+ .filter(({ request }) => request.timestamp >= startedAt && isReportable(request))
45
+ .sort((a, b) => byStartTime(a.request, b.request));
46
+ const triggered = started.map(({ request, inFlight }) => toTriggeredRequest(request, inFlight));
47
+ const kept = keepNotableFirst(triggered, MAX_TRIGGERED_REQUESTS);
48
+ const omitted = triggered.length - kept.length;
49
+ return {
50
+ triggeredRequests: kept,
51
+ ...(omitted > 0 && { triggeredRequestsOmitted: omitted }),
52
+ };
53
+ };
54
+ }
55
+ /**
56
+ * At most `limit` requests, notable ones first (pages, API calls, sockets,
57
+ * failures), then assets, still in start order.
58
+ *
59
+ * @param requests - Requests in start order
60
+ * @param limit - How many to keep
61
+ * @returns Kept requests, in start order
62
+ */
63
+ export function keepNotableFirst(requests, limit) {
64
+ if (requests.length <= limit)
65
+ return requests;
66
+ const notable = requests.filter(isNotableRequest).slice(0, limit);
67
+ const assets = requests
68
+ .filter((request) => !isNotableRequest(request))
69
+ .slice(0, limit - notable.length);
70
+ const kept = new Set([...notable, ...assets]);
71
+ return requests.filter((request) => kept.has(request));
72
+ }
73
+ /**
74
+ * Count a submission's network requests as its request list does (the
75
+ * submit watcher counts every request id CDP reported until the wait ended:
76
+ * `data:` URLs and preflights included, a redirect chain once), so
77
+ * `networkRequests`, the listed requests and JSON agree. Without network
78
+ * telemetry the watcher's count stays.
79
+ *
80
+ * @param result - Submit result with the requests it triggered
81
+ * @returns The result, `networkRequests` matching `triggeredRequests`
82
+ */
83
+ export function withTriggeredRequestCount(result) {
84
+ if (result.networkRequests === undefined || result.triggeredRequests === undefined)
85
+ return result;
86
+ const total = result.triggeredRequests.length + (result.triggeredRequestsOmitted ?? 0);
87
+ return { ...result, networkRequests: total };
88
+ }
89
+ /**
90
+ * A WebSocket connection as a request: its handshake (`GET ws://…`, 101 once
91
+ * it opened, failed when it closed without one).
92
+ *
93
+ * @param connection - Captured WebSocket connection
94
+ * @returns Request-shaped view of the handshake
95
+ */
96
+ function webSocketAsRequest(connection) {
97
+ const failed = connection.status === undefined && connection.closedTime !== undefined;
98
+ return {
99
+ requestId: connection.requestId,
100
+ url: connection.url,
101
+ method: 'GET',
102
+ timestamp: connection.timestamp,
103
+ resourceType: 'WebSocket',
104
+ ...(connection.status !== undefined && { status: connection.status }),
105
+ ...(failed && { status: 0 }),
106
+ ...(failed && connection.errorMessage !== undefined && { errorText: connection.errorMessage }),
107
+ };
108
+ }
109
+ /**
110
+ * Order requests by when they started: Chrome's start time when both have
111
+ * one (bdg's own receipt times are whole milliseconds, so requests started
112
+ * together tie), otherwise when bdg saw them start.
113
+ *
114
+ * @param a - Request
115
+ * @param b - Request
116
+ * @returns Sort order
117
+ */
118
+ function byStartTime(a, b) {
119
+ if (a.sentTime !== undefined && b.sentTime !== undefined)
120
+ return a.sentTime - b.sentTime;
121
+ return a.timestamp - b.timestamp;
122
+ }
123
+ /**
124
+ * Whether a request is worth reporting: not a local URL and not a CORS
125
+ * preflight (Chrome reports those beside the request they guard).
126
+ *
127
+ * @param request - Captured request
128
+ * @returns True to report it
129
+ */
130
+ function isReportable(request) {
131
+ return request.resourceType !== 'Preflight' && !LOCAL_URL_PATTERN.test(request.url);
132
+ }
133
+ /**
134
+ * Summarize a captured request.
135
+ *
136
+ * @param request - Captured request
137
+ * @param inFlight - Whether it was still in flight (a request with a response
138
+ * is then still loading its body: a stream, a slow download)
139
+ * @returns Triggered request entry
140
+ */
141
+ export function toTriggeredRequest(request, inFlight = false) {
142
+ const state = getRequestState(request);
143
+ const errorText = failureReason(request);
144
+ return {
145
+ requestId: request.requestId,
146
+ method: request.method,
147
+ url: request.url,
148
+ ...(request.resourceType !== undefined && { resourceType: request.resourceType }),
149
+ ...(state === 'complete' && { status: request.status }),
150
+ ...(state === 'complete' && inFlight && { loading: true }),
151
+ ...(state !== 'pending' && request.duration !== undefined && { durationMs: request.duration }),
152
+ ...(state === 'failed' && { failed: true }),
153
+ ...(errorText !== undefined && { errorText }),
154
+ ...(state === 'pending' && { pending: true }),
155
+ };
156
+ }
157
+ //# sourceMappingURL=triggeredRequests.js.map
@@ -1,4 +1,4 @@
1
- import type { TelemetryType } from '../../types.js';
1
+ import type { ColorScheme, TelemetryType, ViewportSize } from '../../types.js';
2
2
  export interface SessionConfig {
3
3
  url: string;
4
4
  port: number;
@@ -11,5 +11,9 @@ export interface SessionConfig {
11
11
  chromeWsUrl?: string;
12
12
  /** Custom Chrome flags (e.g., ['--ignore-certificate-errors']) */
13
13
  chromeFlags?: string[];
14
+ /** Viewport size to emulate (`--viewport`) */
15
+ viewport?: ViewportSize;
16
+ /** `prefers-color-scheme` to emulate (`--color-scheme`) */
17
+ colorScheme?: ColorScheme;
14
18
  }
15
19
  //# sourceMappingURL=types.d.ts.map