browser-debugger-cli 0.8.0 → 0.10.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 (304) hide show
  1. package/README.md +7 -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 +29 -6
  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 +189 -119
  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/keyAttributes.d.ts +20 -0
  27. package/dist/commands/dom/helpers/keyAttributes.js +54 -0
  28. package/dist/commands/dom/helpers/query.d.ts +44 -17
  29. package/dist/commands/dom/helpers/query.js +300 -106
  30. package/dist/commands/dom/helpers/runElementCommand.d.ts +10 -2
  31. package/dist/commands/dom/helpers/runElementCommand.js +98 -30
  32. package/dist/commands/dom/helpers/screenshot.d.ts +4 -1
  33. package/dist/commands/dom/helpers/screenshot.js +239 -51
  34. package/dist/commands/dom/index.d.ts +4 -1
  35. package/dist/commands/dom/index.js +22 -7
  36. package/dist/commands/dom/inspect.d.ts +15 -0
  37. package/dist/commands/dom/inspect.js +82 -0
  38. package/dist/commands/dom/layout.d.ts +14 -0
  39. package/dist/commands/dom/layout.js +54 -0
  40. package/dist/commands/dom/listeners.d.ts +5 -1
  41. package/dist/commands/dom/listeners.js +15 -5
  42. package/dist/commands/dom/query.js +2 -3
  43. package/dist/commands/dom/screenshot.d.ts +12 -2
  44. package/dist/commands/dom/screenshot.js +27 -3
  45. package/dist/commands/dom/semanticUtils.d.ts +16 -10
  46. package/dist/commands/dom/semanticUtils.js +53 -16
  47. package/dist/commands/dom/wait.d.ts +13 -0
  48. package/dist/commands/dom/wait.js +83 -0
  49. package/dist/commands/helpJson.js +2 -2
  50. package/dist/commands/network/list.js +17 -13
  51. package/dist/commands/optionBehaviors.js +154 -21
  52. package/dist/commands/page.d.ts +3 -2
  53. package/dist/commands/page.js +100 -5
  54. package/dist/commands/peek.js +4 -11
  55. package/dist/commands/sessions.d.ts +8 -0
  56. package/dist/commands/sessions.js +19 -0
  57. package/dist/commands/shared/CommandRunner.js +4 -4
  58. package/dist/commands/shared/commonOptions.d.ts +4 -0
  59. package/dist/commands/shared/commonOptions.js +9 -0
  60. package/dist/commands/shared/dataFetcher.js +2 -2
  61. package/dist/commands/shared/followMode.d.ts +21 -1
  62. package/dist/commands/shared/followMode.js +29 -2
  63. package/dist/commands/shared/handleValidationError.d.ts +2 -2
  64. package/dist/commands/shared/handleValidationError.js +12 -3
  65. package/dist/commands/shared/optionTypes.d.ts +61 -5
  66. package/dist/commands/shared/startHelpers.d.ts +66 -0
  67. package/dist/commands/shared/startHelpers.js +103 -13
  68. package/dist/commands/shared/validation.d.ts +14 -2
  69. package/dist/commands/shared/validation.js +20 -3
  70. package/dist/commands/start.d.ts +63 -0
  71. package/dist/commands/start.js +115 -15
  72. package/dist/commands/status.js +29 -7
  73. package/dist/commands/stop.js +7 -6
  74. package/dist/commands/tail.js +4 -11
  75. package/dist/commands/types.d.ts +2 -0
  76. package/dist/commands.js +2 -0
  77. package/dist/connection/chromeIdentity.d.ts +65 -0
  78. package/dist/connection/chromeIdentity.js +143 -0
  79. package/dist/connection/launcher/profilePreferences.d.ts +47 -0
  80. package/dist/connection/launcher/profilePreferences.js +151 -0
  81. package/dist/connection/launcher.d.ts +21 -2
  82. package/dist/connection/launcher.js +42 -16
  83. package/dist/connection/portReservation.d.ts +14 -4
  84. package/dist/connection/portReservation.js +21 -6
  85. package/dist/connection/startupExit.d.ts +8 -0
  86. package/dist/connection/startupExit.js +15 -6
  87. package/dist/constants.d.ts +6 -2
  88. package/dist/constants.js +9 -2
  89. package/dist/daemon/SessionController.js +23 -7
  90. package/dist/daemon/errors.d.ts +1 -1
  91. package/dist/daemon/errors.js +1 -1
  92. package/dist/daemon/launcher.d.ts +10 -2
  93. package/dist/daemon/launcher.js +8 -7
  94. package/dist/daemon/server/SocketServer.js +1 -2
  95. package/dist/daemon/session/Session.d.ts +20 -0
  96. package/dist/daemon/session/Session.js +80 -9
  97. package/dist/daemon/session/chromeConnection.d.ts +9 -0
  98. package/dist/daemon/session/chromeConnection.js +45 -8
  99. package/dist/daemon/session/commandRegistry.d.ts +14 -1
  100. package/dist/daemon/session/commandRegistry.js +113 -67
  101. package/dist/daemon/session/interactions.d.ts +48 -9
  102. package/dist/daemon/session/interactions.js +46 -9
  103. package/dist/daemon/session/triggeredRequests.d.ts +67 -0
  104. package/dist/daemon/session/triggeredRequests.js +157 -0
  105. package/dist/daemon/session/types.d.ts +5 -1
  106. package/dist/daemon.js +10630 -3601
  107. package/dist/errors/messages.d.ts +456 -24
  108. package/dist/errors/messages.js +862 -67
  109. package/dist/index.js +6915 -3401
  110. package/dist/ipc/client.d.ts +21 -1
  111. package/dist/ipc/client.js +35 -3
  112. package/dist/ipc/protocol/commands.d.ts +145 -5
  113. package/dist/ipc/protocol/commands.js +4 -0
  114. package/dist/ipc/protocol/domTypes.d.ts +291 -7
  115. package/dist/ipc/protocol/inspectTypes.d.ts +388 -0
  116. package/dist/ipc/protocol/inspectTypes.js +10 -0
  117. package/dist/ipc/session/lifecycle.d.ts +8 -1
  118. package/dist/ipc/session/queries.d.ts +5 -1
  119. package/dist/ipc/session/types.d.ts +5 -0
  120. package/dist/ipc/transport/index.d.ts +2 -1
  121. package/dist/ipc/transport/index.js +2 -2
  122. package/dist/runtime/dom/actionEffects.d.ts +185 -0
  123. package/dist/runtime/dom/actionEffects.js +402 -0
  124. package/dist/runtime/dom/actionEffectsScripts.d.ts +90 -0
  125. package/dist/runtime/dom/actionEffectsScripts.js +426 -0
  126. package/dist/runtime/dom/elementGeometry.d.ts +170 -0
  127. package/dist/runtime/dom/elementGeometry.js +553 -0
  128. package/dist/runtime/dom/elementInfo.d.ts +103 -0
  129. package/dist/runtime/dom/elementInfo.js +256 -0
  130. package/dist/runtime/dom/evalHelpers.d.ts +51 -6
  131. package/dist/runtime/dom/evalHelpers.js +136 -26
  132. package/dist/runtime/dom/eventListeners.d.ts +2 -1
  133. package/dist/runtime/dom/eventListeners.js +184 -47
  134. package/dist/runtime/dom/formDiscovery.d.ts +1 -1
  135. package/dist/runtime/dom/formDiscovery.js +116 -16
  136. package/dist/runtime/dom/formFillHelpers/fill.d.ts +9 -0
  137. package/dist/runtime/dom/formFillHelpers/fill.js +178 -14
  138. package/dist/runtime/dom/formFillHelpers/index.d.ts +2 -2
  139. package/dist/runtime/dom/formFillHelpers/index.js +2 -2
  140. package/dist/runtime/dom/formFillHelpers/pressKey.js +14 -3
  141. package/dist/runtime/dom/formFillHelpers/scroll.d.ts +3 -0
  142. package/dist/runtime/dom/formFillHelpers/scroll.js +60 -18
  143. package/dist/runtime/dom/formFillHelpers/shared.d.ts +17 -0
  144. package/dist/runtime/dom/formFillHelpers/shared.js +25 -1
  145. package/dist/runtime/dom/formFillHelpers/stability.d.ts +20 -6
  146. package/dist/runtime/dom/formFillHelpers/stability.js +50 -19
  147. package/dist/runtime/dom/formSubmitHelpers.d.ts +3 -0
  148. package/dist/runtime/dom/formSubmitHelpers.js +89 -15
  149. package/dist/runtime/dom/frameLayout.d.ts +60 -0
  150. package/dist/runtime/dom/frameLayout.js +140 -0
  151. package/dist/runtime/dom/frameOrigin.d.ts +50 -0
  152. package/dist/runtime/dom/frameOrigin.js +62 -0
  153. package/dist/runtime/dom/frameScopedConnection.d.ts +92 -0
  154. package/dist/runtime/dom/frameScopedConnection.js +252 -0
  155. package/dist/runtime/dom/frameSelection.d.ts +12 -1
  156. package/dist/runtime/dom/frameSelection.js +22 -3
  157. package/dist/runtime/dom/frames.d.ts +61 -5
  158. package/dist/runtime/dom/frames.js +329 -75
  159. package/dist/runtime/dom/inspect.d.ts +28 -0
  160. package/dist/runtime/dom/inspect.js +557 -0
  161. package/dist/runtime/dom/inspectAllStyles.d.ts +62 -0
  162. package/dist/runtime/dom/inspectAllStyles.js +385 -0
  163. package/dist/runtime/dom/inspectCascade.d.ts +94 -0
  164. package/dist/runtime/dom/inspectCascade.js +371 -0
  165. package/dist/runtime/dom/inspectCascadeModel.d.ts +39 -0
  166. package/dist/runtime/dom/inspectCascadeModel.js +232 -0
  167. package/dist/runtime/dom/inspectHints.d.ts +62 -0
  168. package/dist/runtime/dom/inspectHints.js +305 -0
  169. package/dist/runtime/dom/inspectLayoutModel.d.ts +87 -0
  170. package/dist/runtime/dom/inspectLayoutModel.js +346 -0
  171. package/dist/runtime/dom/inspectModel.d.ts +74 -0
  172. package/dist/runtime/dom/inspectModel.js +184 -0
  173. package/dist/runtime/dom/inspectPaintModel.d.ts +157 -0
  174. package/dist/runtime/dom/inspectPaintModel.js +461 -0
  175. package/dist/runtime/dom/inspectRules.d.ts +37 -0
  176. package/dist/runtime/dom/inspectRules.js +101 -0
  177. package/dist/runtime/dom/inspectScripts.d.ts +132 -0
  178. package/dist/runtime/dom/inspectScripts.js +263 -0
  179. package/dist/runtime/dom/inspectTree.d.ts +40 -0
  180. package/dist/runtime/dom/inspectTree.js +134 -0
  181. package/dist/runtime/dom/inspectVariables.d.ts +33 -0
  182. package/dist/runtime/dom/inspectVariables.js +94 -0
  183. package/dist/runtime/dom/inspectWhyModel.d.ts +20 -0
  184. package/dist/runtime/dom/inspectWhyModel.js +134 -0
  185. package/dist/runtime/dom/layout.d.ts +71 -0
  186. package/dist/runtime/dom/layout.js +340 -0
  187. package/dist/runtime/dom/listenerPageScripts.d.ts +72 -0
  188. package/dist/runtime/dom/listenerPageScripts.js +365 -0
  189. package/dist/runtime/dom/listenerSummary.d.ts +136 -11
  190. package/dist/runtime/dom/listenerSummary.js +361 -22
  191. package/dist/runtime/dom/pageActivity.d.ts +41 -0
  192. package/dist/runtime/dom/pageActivity.js +123 -0
  193. package/dist/runtime/dom/reactEventHelpers.d.ts +63 -2
  194. package/dist/runtime/dom/reactEventHelpers.js +220 -41
  195. package/dist/runtime/dom/targetNode.d.ts +80 -27
  196. package/dist/runtime/dom/targetNode.js +249 -33
  197. package/dist/runtime/dom/wait.d.ts +25 -0
  198. package/dist/runtime/dom/wait.js +199 -0
  199. package/dist/runtime/dom/waitCondition.d.ts +71 -0
  200. package/dist/runtime/dom/waitCondition.js +75 -0
  201. package/dist/runtime/page/emulation.d.ts +71 -0
  202. package/dist/runtime/page/emulation.js +117 -0
  203. package/dist/runtime/page/loadingState.d.ts +36 -0
  204. package/dist/runtime/page/loadingState.js +86 -0
  205. package/dist/runtime/page/navigation.d.ts +46 -2
  206. package/dist/runtime/page/navigation.js +69 -33
  207. package/dist/session/QueryCacheManager.d.ts +11 -1
  208. package/dist/session/QueryCacheManager.js +25 -3
  209. package/dist/session/chromeOwners.d.ts +34 -0
  210. package/dist/session/chromeOwners.js +51 -0
  211. package/dist/session/cleanup/staleSession.d.ts +11 -1
  212. package/dist/session/cleanup/staleSession.js +17 -6
  213. package/dist/session/cleanup/userCommands.js +2 -4
  214. package/dist/session/metadata.d.ts +5 -1
  215. package/dist/session/metadata.js +2 -1
  216. package/dist/session/paths.d.ts +77 -3
  217. package/dist/session/paths.js +111 -5
  218. package/dist/session/port.d.ts +31 -7
  219. package/dist/session/port.js +50 -43
  220. package/dist/session/portClaims.d.ts +66 -0
  221. package/dist/session/portClaims.js +284 -0
  222. package/dist/session/sessionList.d.ts +58 -0
  223. package/dist/session/sessionList.js +199 -0
  224. package/dist/session/sessionName.d.ts +46 -0
  225. package/dist/session/sessionName.js +97 -0
  226. package/dist/telemetry/a11y.d.ts +18 -3
  227. package/dist/telemetry/a11y.js +170 -29
  228. package/dist/telemetry/console.d.ts +1 -0
  229. package/dist/telemetry/console.js +100 -5
  230. package/dist/telemetry/network.js +3 -1
  231. package/dist/telemetry/requestKinds.d.ts +32 -0
  232. package/dist/telemetry/requestKinds.js +61 -0
  233. package/dist/telemetry/requestState.d.ts +31 -0
  234. package/dist/telemetry/requestState.js +38 -0
  235. package/dist/types.d.ts +112 -3
  236. package/dist/ui/formatters/a11y.js +3 -0
  237. package/dist/ui/formatters/console/chronological.d.ts +8 -0
  238. package/dist/ui/formatters/console/chronological.js +17 -4
  239. package/dist/ui/formatters/console/json.js +3 -4
  240. package/dist/ui/formatters/console/shared.d.ts +12 -0
  241. package/dist/ui/formatters/console.d.ts +2 -2
  242. package/dist/ui/formatters/console.js +1 -1
  243. package/dist/ui/formatters/details.d.ts +8 -0
  244. package/dist/ui/formatters/details.js +61 -4
  245. package/dist/ui/formatters/dom.d.ts +27 -14
  246. package/dist/ui/formatters/dom.js +88 -59
  247. package/dist/ui/formatters/form.js +29 -18
  248. package/dist/ui/formatters/inspect.d.ts +39 -0
  249. package/dist/ui/formatters/inspect.js +596 -0
  250. package/dist/ui/formatters/keyAttributes.d.ts +19 -0
  251. package/dist/ui/formatters/keyAttributes.js +84 -0
  252. package/dist/ui/formatters/layout.d.ts +31 -0
  253. package/dist/ui/formatters/layout.js +53 -0
  254. package/dist/ui/formatters/listeners.d.ts +3 -2
  255. package/dist/ui/formatters/listeners.js +73 -9
  256. package/dist/ui/formatters/networkHeaders.d.ts +13 -0
  257. package/dist/ui/formatters/networkHeaders.js +36 -3
  258. package/dist/ui/formatters/networkList.d.ts +29 -1
  259. package/dist/ui/formatters/networkList.js +86 -20
  260. package/dist/ui/formatters/preview.js +2 -1
  261. package/dist/ui/formatters/requestStatus.d.ts +1 -17
  262. package/dist/ui/formatters/requestStatus.js +2 -30
  263. package/dist/ui/formatters/sessions.d.ts +12 -0
  264. package/dist/ui/formatters/sessions.js +40 -0
  265. package/dist/ui/formatters/status.d.ts +21 -2
  266. package/dist/ui/formatters/status.js +47 -10
  267. package/dist/ui/formatters/triggeredRequests.d.ts +36 -0
  268. package/dist/ui/formatters/triggeredRequests.js +65 -0
  269. package/dist/ui/formatting.d.ts +19 -0
  270. package/dist/ui/formatting.js +31 -36
  271. package/dist/ui/messages/chrome.d.ts +9 -0
  272. package/dist/ui/messages/chrome.js +17 -5
  273. package/dist/ui/messages/commands.d.ts +504 -14
  274. package/dist/ui/messages/commands.js +835 -21
  275. package/dist/ui/messages/consoleMessages.d.ts +10 -0
  276. package/dist/ui/messages/consoleMessages.js +17 -0
  277. package/dist/ui/messages/hints.js +2 -1
  278. package/dist/ui/messages/networkMessages.d.ts +14 -0
  279. package/dist/ui/messages/networkMessages.js +18 -0
  280. package/dist/ui/messages/preview.js +5 -4
  281. package/dist/ui/messages/session.d.ts +30 -21
  282. package/dist/ui/messages/session.js +48 -26
  283. package/dist/ui/messages/sessionCommand.d.ts +43 -0
  284. package/dist/ui/messages/sessionCommand.js +52 -0
  285. package/dist/utils/async.d.ts +17 -0
  286. package/dist/utils/async.js +36 -0
  287. package/dist/utils/color.d.ts +84 -0
  288. package/dist/utils/color.js +376 -0
  289. package/dist/utils/cssValues.d.ts +109 -0
  290. package/dist/utils/cssValues.js +236 -0
  291. package/dist/utils/http.d.ts +22 -1
  292. package/dist/utils/http.js +28 -9
  293. package/dist/utils/selectorFilters.d.ts +48 -8
  294. package/dist/utils/selectorFilters.js +296 -53
  295. package/dist/utils/shellDetection.d.ts +8 -2
  296. package/dist/utils/shellDetection.js +120 -33
  297. package/dist/utils/suggestions.d.ts +26 -0
  298. package/dist/utils/suggestions.js +73 -0
  299. package/dist/utils/taskMappings.js +10 -0
  300. package/dist/utils/url.d.ts +12 -2
  301. package/dist/utils/url.js +69 -7
  302. package/package.json +1 -1
  303. package/dist/ui/formatters/sessionFormatters.d.ts +0 -58
  304. package/dist/ui/formatters/sessionFormatters.js +0 -121
@@ -14,15 +14,67 @@
14
14
  * all, not even to `Runtime.terminateExecution`.
15
15
  */
16
16
  import { CDPConnection } from '../../connection/cdp.js';
17
+ import type { Protocol } from '../../connection/typed-cdp.js';
18
+ import type { CommandError } from '../../errors/index.js';
17
19
  import type { DomEvalData, DomFrame } from '../../ipc/protocol/commands.js';
20
+ import { type CDPSender } from '../../telemetry/objectExpander.js';
21
+ /** The default (main-world) execution context of a frame */
22
+ interface FrameContext {
23
+ /** `ExecutionContextDescription.uniqueId` */
24
+ uniqueId: string;
25
+ /** Origin its scripts run with (`"://"` when opaque) */
26
+ origin: string;
27
+ }
28
+ /** A frame with the session that owns it */
29
+ interface FrameNode {
30
+ frame: Protocol.Page.Frame;
31
+ sessionId?: string;
32
+ context?: FrameContext;
33
+ }
34
+ /** The page's iframes as listed, and the frame id behind each index */
35
+ export interface FrameListing {
36
+ frames: DomFrame[];
37
+ /** Frame id of each listed frame, by index */
38
+ frameIds: string[];
39
+ }
40
+ /**
41
+ * Iframes below the main frame, depth-first, siblings in the document order
42
+ * of their iframe elements (frames without a known place last, in tree order).
43
+ *
44
+ * @param nodes - All frames
45
+ * @param mainFrameId - The page's main frame
46
+ * @param rank - Place of each frame among its siblings, by id
47
+ * @returns Iframes in listing order
48
+ */
49
+ export declare function iframesInOrder<T extends Pick<FrameNode, 'frame'>>(nodes: T[], mainFrameId: string, rank: Map<string, number>): T[];
18
50
  /**
19
51
  * List the page's iframes.
20
52
  *
21
53
  * @param page - The session's connection
22
54
  * @param wsUrl - WebSocket URL of the page target
23
- * @returns Iframes in listing order
55
+ * @returns Iframes in listing order, and the frame id behind each index
56
+ */
57
+ export declare function listFrames(page: CDPConnection, wsUrl: string): Promise<FrameListing>;
58
+ /** A frame whose script lost its context */
59
+ export interface LostFrame {
60
+ frameId: string;
61
+ /** Session of the parent frame, which owns the iframe element */
62
+ ownerSession?: string;
63
+ /** Frame URL when the script started */
64
+ url: string;
65
+ }
66
+ /**
67
+ * The error for a script whose frame context went away: the page was
68
+ * closed, the frame navigated (its iframe element is still there) or was
69
+ * removed.
70
+ *
71
+ * @param conn - Connection the frame was found on
72
+ * @param page - The session's connection to the page
73
+ * @param frame - The frame
74
+ * @returns Command error (83)
75
+ * @throws Errors of the checks other than Chrome saying the frame is gone
24
76
  */
25
- export declare function listFrames(page: CDPConnection, wsUrl: string): Promise<DomFrame[]>;
77
+ export declare function frameContextLostError(conn: Pick<CDPConnection, 'send'>, page: CDPSender, frame: LostFrame): Promise<CommandError>;
26
78
  /**
27
79
  * Evaluate a `bdg dom eval` script in one iframe, like {@link evaluateScript}
28
80
  * does in the page.
@@ -30,9 +82,13 @@ export declare function listFrames(page: CDPConnection, wsUrl: string): Promise<
30
82
  * @param page - The session's connection
31
83
  * @param wsUrl - WebSocket URL of the page target
32
84
  * @param script - JavaScript expression
33
- * @param query - Requested frame (index, name/id attribute, or part of the URL)
85
+ * @param query - Requested frame (index, name/id attribute, or part of the name, id or URL)
86
+ * @param listedIds - Frame id behind each index of the last `dom frames` listing, if any
34
87
  * @returns Value, type and the frame's URL
35
- * @throws CommandError (81/83) when the frame is ambiguous or missing, else as evaluateScript
88
+ * @throws CommandError (81/83) when the frame is ambiguous or missing, (87)
89
+ * when an index names another frame than when it was listed, (83) when it
90
+ * navigated or was removed while the script ran, else as evaluateScript
36
91
  */
37
- export declare function evaluateInFrame(page: CDPConnection, wsUrl: string, script: string, query: string): Promise<DomEvalData>;
92
+ export declare function evaluateInFrame(page: CDPConnection, wsUrl: string, script: string, query: string, listedIds?: string[]): Promise<DomEvalData>;
93
+ export {};
38
94
  //# sourceMappingURL=frames.d.ts.map
@@ -14,9 +14,11 @@
14
14
  * all, not even to `Runtime.terminateExecution`.
15
15
  */
16
16
  import { CDPConnection } from '../../connection/cdp.js';
17
- import { frameNotReadyError } from '../../errors/messages.js';
18
- import { evaluateScript, withBusyPageRecovery } from './evalHelpers.js';
19
- import { frameError, selectFrame } from './frameSelection.js';
17
+ import { CDPProtocolError } from '../../connection/errors.js';
18
+ import { frameLostDuringEvalError, frameNavigatedDuringEvalError, frameNotReadyError, frameRemovedDuringEvalError, pageClosedDuringEvalError, } from '../../errors/messages.js';
19
+ import { evaluateScript, isContextLostError, pageStillOpen, settledWithin, withBusyPageRecovery, } from './evalHelpers.js';
20
+ import { effectiveFrameOrigin, isCrossOrigin } from './frameOrigin.js';
21
+ import { assertFrameIndexCurrent, frameError, selectFrame } from './frameSelection.js';
20
22
  import { attachedSessionOf } from '../../telemetry/attachedTargets.js';
21
23
  import { senderFor } from '../../telemetry/objectExpander.js';
22
24
  import { createLogger } from '../../ui/logging/index.js';
@@ -25,6 +27,32 @@ import { EXIT_CODES } from '../../utils/exitCodes.js';
25
27
  const log = createLogger('dom');
26
28
  /** Auto-attach without pausing new targets: only existing frames are needed */
27
29
  const AUTO_ATTACH = { autoAttach: true, waitForDebuggerOnStart: false, flatten: true };
30
+ /**
31
+ * Page function, called with iframe elements of one document: their
32
+ * indices in document order. Shadow roots are walked through their host
33
+ * (a shadow root's content comes before the host's children, as in
34
+ * shadow-including tree order).
35
+ */
36
+ const DOCUMENT_ORDER_JS = `function (...nodes) {
37
+ const path = (node) => {
38
+ const nodesUp = [];
39
+ for (let n = node; n; n = n.parentNode || (n.nodeType === 11 ? n.host : null)) nodesUp.unshift(n);
40
+ return nodesUp;
41
+ };
42
+ const paths = nodes.map(path);
43
+ const compare = (i, j) => {
44
+ const a = paths[i];
45
+ const b = paths[j];
46
+ let depth = 0;
47
+ while (depth < a.length && depth < b.length && a[depth] === b[depth]) depth++;
48
+ const x = a[depth];
49
+ const y = b[depth];
50
+ if (!x || !y) return a.length - b.length;
51
+ if (x.nodeType === 11 || y.nodeType === 11) return x.nodeType === 11 ? -1 : 1;
52
+ return x.compareDocumentPosition(y) & 4 ? -1 : 1;
53
+ };
54
+ return nodes.map((_, i) => i).sort(compare);
55
+ }`;
28
56
  /**
29
57
  * Run `work` on a second connection to the page, closed afterwards.
30
58
  *
@@ -70,18 +98,45 @@ function recoverySender(fc, sessionId) {
70
98
  */
71
99
  async function sendToSession(fc, method, params, sessionId) {
72
100
  const command = fc.conn.send(method, params, sessionId);
73
- return (await withBusyPageRecovery(recoverySender(fc, sessionId), command));
101
+ const scope = sessionId === undefined ? 'page' : 'frame';
102
+ return (await withBusyPageRecovery(recoverySender(fc, sessionId), command, { scope }));
74
103
  }
75
104
  /**
76
- * Frame tree of a session.
105
+ * Default execution contexts of a session's frames, reported when Runtime is
106
+ * enabled.
107
+ *
108
+ * @param fc - Frame connection
109
+ * @param sessionId - Session, undefined for the page
110
+ * @returns Context of each frame, by frame id
111
+ */
112
+ async function defaultContexts(fc, sessionId) {
113
+ const contexts = new Map();
114
+ const stop = fc.conn.on('Runtime.executionContextCreated', ({ context }, eventSession) => {
115
+ const auxData = (context.auxData ?? {});
116
+ const frameId = auxData['frameId'];
117
+ if (eventSession !== sessionId || !auxData['isDefault'] || typeof frameId !== 'string')
118
+ return;
119
+ contexts.set(frameId, { uniqueId: context.uniqueId, origin: context.origin });
120
+ });
121
+ try {
122
+ await sendToSession(fc, 'Runtime.enable', {}, sessionId);
123
+ }
124
+ finally {
125
+ stop();
126
+ }
127
+ return contexts;
128
+ }
129
+ /**
130
+ * Frame tree of a session and the default contexts of its frames.
77
131
  *
78
132
  * @param fc - Frame connection
79
133
  * @param sessionId - Session, undefined for the page
80
134
  * @returns The tree
81
135
  */
82
- async function frameTree(fc, sessionId) {
136
+ async function readSession(fc, sessionId) {
137
+ const contexts = await defaultContexts(fc, sessionId);
83
138
  const { frameTree: tree } = await sendToSession(fc, 'Page.getFrameTree', {}, sessionId);
84
- return { tree, ...(sessionId && { sessionId }) };
139
+ return { tree, contexts, ...(sessionId && { sessionId }) };
85
140
  }
86
141
  /**
87
142
  * Attach to the out-of-process iframes directly below a session. Chrome
@@ -116,38 +171,63 @@ async function attachChildFrames(fc, parentSession) {
116
171
  */
117
172
  async function outOfProcessTrees(fc, parentSession) {
118
173
  const sessions = await attachChildFrames(fc, parentSession);
119
- const nested = await Promise.all(sessions.map(async (sessionId) => [
120
- await frameTree(fc, sessionId),
121
- ...(await outOfProcessTrees(fc, sessionId)),
122
- ]));
174
+ const nested = await Promise.all(sessions.map((sessionId) => childSessionTrees(fc, sessionId)));
123
175
  return nested.flat();
124
176
  }
125
177
  /**
126
- * All frames of the trees, each with its session.
178
+ * Trees of an out-of-process iframe and the ones nested in it. A frame
179
+ * removed while the page is being listed (its session is gone) is skipped.
180
+ *
181
+ * @param fc - Frame connection
182
+ * @param sessionId - The iframe's session
183
+ * @returns Its tree and the nested ones, or none when it went away
184
+ */
185
+ async function childSessionTrees(fc, sessionId) {
186
+ try {
187
+ return [await readSession(fc, sessionId), ...(await outOfProcessTrees(fc, sessionId))];
188
+ }
189
+ catch (error) {
190
+ if (!(error instanceof CDPProtocolError))
191
+ throw error;
192
+ log.debug(`Frame session ${sessionId} went away while listing: ${error.message}`);
193
+ return [];
194
+ }
195
+ }
196
+ /**
197
+ * All frames of the trees, each with its session and default context.
127
198
  *
128
199
  * @param trees - Frame trees
129
200
  * @returns Frames in tree order
130
201
  */
131
202
  function flattenTrees(trees) {
132
203
  const nodes = [];
133
- const walk = (tree, sessionId) => {
134
- nodes.push({ frame: tree.frame, ...(sessionId && { sessionId }) });
135
- tree.childFrames?.forEach((child) => walk(child, sessionId));
204
+ const walk = (tree, owner) => {
205
+ const context = owner.contexts.get(tree.frame.id);
206
+ nodes.push({
207
+ frame: tree.frame,
208
+ ...(owner.sessionId && { sessionId: owner.sessionId }),
209
+ ...(context && { context }),
210
+ });
211
+ tree.childFrames?.forEach((child) => walk(child, owner));
136
212
  };
137
- trees.forEach(({ tree, sessionId }) => walk(tree, sessionId));
213
+ trees.forEach((owner) => walk(owner.tree, owner));
138
214
  return nodes;
139
215
  }
140
216
  /**
141
- * Iframes below the main frame, depth-first.
217
+ * Iframes below the main frame, depth-first, siblings in the document order
218
+ * of their iframe elements (frames without a known place last, in tree order).
142
219
  *
143
220
  * @param nodes - All frames
144
221
  * @param mainFrameId - The page's main frame
222
+ * @param rank - Place of each frame among its siblings, by id
145
223
  * @returns Iframes in listing order
146
224
  */
147
- function iframesInOrder(nodes, mainFrameId) {
225
+ export function iframesInOrder(nodes, mainFrameId, rank) {
148
226
  const ordered = [];
227
+ const place = (node) => rank.get(node.frame.id) ?? Number.MAX_SAFE_INTEGER;
149
228
  const visit = (parentId) => {
150
- for (const node of nodes.filter((n) => n.frame.parentId === parentId)) {
229
+ const children = nodes.filter((n) => n.frame.parentId === parentId);
230
+ for (const node of children.sort((a, b) => place(a) - place(b))) {
151
231
  ordered.push(node);
152
232
  visit(node.frame.id);
153
233
  }
@@ -170,116 +250,275 @@ function attributeValue(attributes = [], key) {
170
250
  return undefined;
171
251
  }
172
252
  /**
173
- * Attributes of the iframe element of a frame (read in its parent's session).
253
+ * The iframe element of a frame (read in its parent's session).
174
254
  *
175
255
  * @param fc - Frame connection
176
256
  * @param frameId - Frame
177
257
  * @param ownerSession - Session of the parent frame
178
- * @returns `name` and `id` attributes when set
258
+ * @returns Its node, and `name`, `id` and `sandbox` attributes when set
179
259
  */
180
- async function ownerAttributes(fc, frameId, ownerSession) {
260
+ async function frameOwner(fc, frameId, ownerSession) {
181
261
  try {
182
262
  const { backendNodeId } = await sendToSession(fc, 'DOM.getFrameOwner', { frameId }, ownerSession);
183
263
  const { node } = await sendToSession(fc, 'DOM.describeNode', { backendNodeId }, ownerSession);
184
264
  const name = attributeValue(node.attributes, 'name');
185
265
  const id = attributeValue(node.attributes, 'id');
186
- return { ...(name && { name }), ...(id && { id }) };
266
+ const sandbox = attributeValue(node.attributes, 'sandbox');
267
+ return {
268
+ backendNodeId,
269
+ ...(name && { name }),
270
+ ...(id && { id }),
271
+ ...(sandbox !== undefined && { sandbox }),
272
+ };
187
273
  }
188
274
  catch (error) {
189
275
  log.debug(`No iframe element for frame ${frameId}: ${getErrorMessage(error)}`);
190
276
  return {};
191
277
  }
192
278
  }
279
+ /**
280
+ * Where a frame sits in the listing: its origin, and the index of its parent.
281
+ * Parents are placed before their children, so a child can inherit its
282
+ * parent's origin.
283
+ *
284
+ * @param node - The frame
285
+ * @param index - Its position
286
+ * @param owner - Attributes of its iframe element
287
+ * @param state - Frames placed so far (updated)
288
+ * @returns Origin and parent index
289
+ */
290
+ function placeFrame(node, index, owner, state) {
291
+ const { frame, context } = node;
292
+ const parentId = frame.parentId ?? '';
293
+ const origin = effectiveFrameOrigin({
294
+ url: frame.url,
295
+ securityOrigin: frame.securityOrigin,
296
+ contextOrigin: context?.origin,
297
+ parentOrigin: state.originOf.get(parentId),
298
+ sandbox: owner.sandbox,
299
+ });
300
+ const parentIndex = state.indexOf.get(parentId);
301
+ state.originOf.set(frame.id, origin);
302
+ state.indexOf.set(frame.id, index);
303
+ return { origin, ...(parentIndex !== undefined && { parentIndex }) };
304
+ }
193
305
  /**
194
306
  * Describe an iframe for listing. Chrome names a frame after its element's
195
307
  * `id` when it has no `name`, so such a name is not repeated.
196
308
  *
197
- * @param fc - Frame connection
198
309
  * @param node - The frame
199
310
  * @param index - Its position
200
- * @param context - The page's origin and the session of each frame
311
+ * @param owner - Attributes of its iframe element
312
+ * @param state - Frames described so far (updated)
201
313
  * @returns The located frame
202
314
  */
203
- async function locateFrame(fc, node, index, context) {
204
- const { frame, sessionId } = node;
205
- const owner = await ownerAttributes(fc, frame.id, context.sessionOf.get(frame.parentId ?? ''));
315
+ function describeFrame(node, index, owner, state) {
316
+ const { frame, sessionId, context } = node;
206
317
  const name = owner.name ?? (frame.name === owner.id ? undefined : frame.name);
318
+ const { origin, parentIndex } = placeFrame(node, index, owner, state);
207
319
  const info = {
208
320
  index,
209
321
  url: frame.url + (frame.urlFragment ?? ''),
210
322
  ...(name && { name }),
211
323
  ...(owner.id && { id: owner.id }),
212
- origin: frame.securityOrigin,
213
- crossOrigin: frame.securityOrigin !== context.topOrigin,
324
+ origin,
325
+ crossOrigin: isCrossOrigin(origin, state.topOrigin),
214
326
  outOfProcess: sessionId !== undefined,
327
+ ...(parentIndex !== undefined && { parentIndex }),
328
+ };
329
+ const ownerSession = state.sessionOf.get(frame.parentId ?? '');
330
+ return {
331
+ info,
332
+ frameId: frame.id,
333
+ ...(sessionId && { sessionId }),
334
+ ...(ownerSession && { ownerSession }),
335
+ ...(context && { context }),
215
336
  };
216
- return { info, frameId: frame.id, ...(sessionId && { sessionId }) };
217
337
  }
218
338
  /**
219
- * Find every iframe of the page, nested and out-of-process ones included.
339
+ * The listing state before the first iframe: the page's own origin.
340
+ *
341
+ * @param page - The page's session tree
342
+ * @param sessionOf - Session of each frame
343
+ * @returns Initial state
344
+ */
345
+ function initialListingState(page, sessionOf) {
346
+ const top = page.tree.frame;
347
+ const topOrigin = effectiveFrameOrigin({
348
+ url: top.url,
349
+ securityOrigin: top.securityOrigin,
350
+ contextOrigin: page.contexts.get(top.id)?.origin,
351
+ });
352
+ return { topOrigin, originOf: new Map([[top.id, topOrigin]]), indexOf: new Map(), sessionOf };
353
+ }
354
+ /**
355
+ * Indices of iframe elements of one document, in document order.
220
356
  *
221
357
  * @param fc - Frame connection
222
- * @returns Iframes in listing order
358
+ * @param backendNodeIds - The iframe elements
359
+ * @param ownerSession - Session of the document
360
+ * @returns Their indices in document order
361
+ * @throws Errors of CDP (e.g. an element removed meanwhile)
223
362
  */
224
- async function discoverFrames(fc) {
225
- const [page, outOfProcess] = await Promise.all([frameTree(fc), outOfProcessTrees(fc)]);
226
- const nodes = flattenTrees([page, ...outOfProcess]);
227
- const sessionOf = new Map(nodes.map((node) => [node.frame.id, node.sessionId]));
228
- const context = { topOrigin: page.tree.frame.securityOrigin, sessionOf };
229
- const iframes = iframesInOrder(nodes, page.tree.frame.id);
230
- return Promise.all(iframes.map((node, index) => locateFrame(fc, node, index, context)));
363
+ async function documentOrder(fc, backendNodeIds, ownerSession) {
364
+ const objectIds = await Promise.all(backendNodeIds.map(async (backendNodeId) => {
365
+ const { object } = await sendToSession(fc, 'DOM.resolveNode', { backendNodeId }, ownerSession);
366
+ return object.objectId ?? '';
367
+ }));
368
+ const { result } = await sendToSession(fc, 'Runtime.callFunctionOn', {
369
+ objectId: objectIds[0],
370
+ functionDeclaration: DOCUMENT_ORDER_JS,
371
+ arguments: objectIds.map((objectId) => ({ objectId })),
372
+ returnByValue: true,
373
+ }, ownerSession);
374
+ return result.value;
375
+ }
376
+ /**
377
+ * Frames grouped by their parent.
378
+ *
379
+ * @param iframes - Frames
380
+ * @returns Frames of each parent, by parent id
381
+ */
382
+ function groupByParent(iframes) {
383
+ const byParent = new Map();
384
+ for (const node of iframes) {
385
+ const parentId = node.frame.parentId ?? '';
386
+ byParent.set(parentId, [...(byParent.get(parentId) ?? []), node]);
387
+ }
388
+ return byParent;
231
389
  }
232
390
  /**
233
- * The default (main-world) execution context of a frame, so the script sees
234
- * the frame's own globals.
391
+ * Place of each frame among its siblings, from the document order of their
392
+ * iframe elements. Chrome's frame tree lists frames in the order they were
393
+ * attached and leaves out-of-process ones to their own sessions, so neither
394
+ * gives a stable order. Siblings that cannot be ordered get no place.
235
395
  *
236
396
  * @param fc - Frame connection
237
- * @param frame - The frame
238
- * @returns The context's unique id
239
- * @throws CommandError (83) when the frame has no context yet
397
+ * @param iframes - All iframes
398
+ * @param owners - Iframe element of each frame, by id
399
+ * @param sessionOf - Session of each frame, by id
400
+ * @returns Place of each frame among its siblings, by id
240
401
  */
241
- async function defaultContext(fc, frame) {
242
- const contexts = [];
243
- const stop = fc.conn.on('Runtime.executionContextCreated', ({ context }, sessionId) => {
244
- if (sessionId === frame.sessionId)
245
- contexts.push(context);
402
+ async function siblingRanks(fc, iframes, owners, sessionOf) {
403
+ const rank = new Map();
404
+ const groups = [...groupByParent(iframes)].map(async ([parentId, siblings]) => {
405
+ const placed = siblings.flatMap((node) => {
406
+ const backendNodeId = owners.get(node.frame.id)?.backendNodeId;
407
+ return backendNodeId === undefined ? [] : [{ id: node.frame.id, backendNodeId }];
408
+ });
409
+ if (placed.length < 2)
410
+ return;
411
+ try {
412
+ const nodeIds = placed.map((item) => item.backendNodeId);
413
+ const order = await documentOrder(fc, nodeIds, sessionOf.get(parentId));
414
+ order.forEach((index, place) => rank.set(placed[index]?.id ?? '', place));
415
+ }
416
+ catch (error) {
417
+ log.debug(`Frames of ${parentId} not ordered: ${getErrorMessage(error)}`);
418
+ }
246
419
  });
247
- try {
248
- await sendToSession(fc, 'Runtime.enable', {}, frame.sessionId);
249
- }
250
- finally {
251
- stop();
252
- }
253
- const auxData = (c) => (c.auxData ?? {});
254
- const context = contexts.find((c) => auxData(c)['frameId'] === frame.frameId && auxData(c)['isDefault']);
255
- if (!context)
256
- throw frameError(frameNotReadyError(frame.info.url), EXIT_CODES.RESOURCE_NOT_FOUND);
257
- return context.uniqueId;
420
+ await Promise.all(groups);
421
+ return rank;
422
+ }
423
+ /**
424
+ * Find every iframe of the page, nested and out-of-process ones included,
425
+ * siblings in the document order of their iframe elements. Frames that go
426
+ * away while they are being listed are skipped.
427
+ *
428
+ * @param fc - Frame connection
429
+ * @returns Iframes in listing order
430
+ */
431
+ async function discoverFrames(fc) {
432
+ const [page, outOfProcess] = await Promise.all([readSession(fc), outOfProcessTrees(fc)]);
433
+ const nodes = flattenTrees([page, ...outOfProcess]);
434
+ const sessionOf = new Map(nodes.map((node) => [node.frame.id, node.sessionId]));
435
+ const mainFrameId = page.tree.frame.id;
436
+ const iframes = nodes.filter((node) => node.frame.id !== mainFrameId);
437
+ const owners = new Map(await Promise.all(iframes.map(async (node) => [
438
+ node.frame.id,
439
+ await frameOwner(fc, node.frame.id, sessionOf.get(node.frame.parentId ?? '')),
440
+ ])));
441
+ const rank = await siblingRanks(fc, iframes, owners, sessionOf);
442
+ const state = initialListingState(page, sessionOf);
443
+ return iframesInOrder(iframes, mainFrameId, rank).map((node, index) => describeFrame(node, index, owners.get(node.frame.id) ?? {}, state));
258
444
  }
259
445
  /**
260
446
  * List the page's iframes.
261
447
  *
262
448
  * @param page - The session's connection
263
449
  * @param wsUrl - WebSocket URL of the page target
264
- * @returns Iframes in listing order
450
+ * @returns Iframes in listing order, and the frame id behind each index
265
451
  */
266
452
  export async function listFrames(page, wsUrl) {
267
453
  const frames = await withFrameConnection(page, wsUrl, discoverFrames);
268
- return frames.map((frame) => frame.info);
454
+ return { frames: frames.map((frame) => frame.info), frameIds: frames.map((f) => f.frameId) };
269
455
  }
270
456
  /**
271
457
  * Find the requested frame and its default execution context.
272
458
  *
273
459
  * @param fc - Frame connection
274
460
  * @param query - Requested frame
461
+ * @param listedIds - Frame id behind each index of the last `dom frames` listing, if any
275
462
  * @returns The frame and its context's unique id
276
- * @throws CommandError (81/83) when the frame is ambiguous, missing or has no context
463
+ * @throws CommandError (81/83) when the frame is ambiguous, missing or has no
464
+ * context, (87) when an index names another frame than when it was listed
277
465
  */
278
- async function resolveFrame(fc, query) {
466
+ async function resolveFrame(fc, query, listedIds) {
279
467
  const frames = await discoverFrames(fc);
468
+ assertFrameIndexCurrent(query, frames.map((frame) => frame.frameId), listedIds);
280
469
  const selected = selectFrame(frames.map((frame) => frame.info), query);
281
470
  const frame = frames[selected.index];
282
- return { frame, uniqueContextId: await defaultContext(fc, frame) };
471
+ if (!frame.context) {
472
+ throw frameError(frameNotReadyError(frame.info.url), EXIT_CODES.RESOURCE_NOT_FOUND);
473
+ }
474
+ return { frame, uniqueContextId: frame.context.uniqueId };
475
+ }
476
+ /** Chrome's messages when a frame (or the session of its parent) no longer exists */
477
+ const FRAME_GONE_PATTERN = /not found|no frame|no node/i;
478
+ /** How long the frame's parent gets to say whether the frame is still there */
479
+ const OWNER_CHECK_MS = 2_000;
480
+ /**
481
+ * Whether the frame's iframe element is still in its parent.
482
+ *
483
+ * @param conn - Connection the frame was found on
484
+ * @param frame - The frame
485
+ * @returns `attached`, `removed`, or `unknown` when the parent did not answer in time
486
+ * @throws Errors other than Chrome saying the frame is gone (e.g. a lost connection)
487
+ */
488
+ async function frameOwnerState(conn, frame) {
489
+ try {
490
+ const owner = conn.send('DOM.getFrameOwner', { frameId: frame.frameId }, frame.ownerSession);
491
+ return (await settledWithin(owner, OWNER_CHECK_MS)).settled ? 'attached' : 'unknown';
492
+ }
493
+ catch (error) {
494
+ if (!(error instanceof CDPProtocolError) || !FRAME_GONE_PATTERN.test(error.message))
495
+ throw error;
496
+ log.debug(`Frame ${frame.frameId} is gone: ${error.message}`);
497
+ return 'removed';
498
+ }
499
+ }
500
+ /**
501
+ * The error for a script whose frame context went away: the page was
502
+ * closed, the frame navigated (its iframe element is still there) or was
503
+ * removed.
504
+ *
505
+ * @param conn - Connection the frame was found on
506
+ * @param page - The session's connection to the page
507
+ * @param frame - The frame
508
+ * @returns Command error (83)
509
+ * @throws Errors of the checks other than Chrome saying the frame is gone
510
+ */
511
+ export async function frameContextLostError(conn, page, frame) {
512
+ if (!(await pageStillOpen(page))) {
513
+ return frameError(pageClosedDuringEvalError(), EXIT_CODES.RESOURCE_NOT_FOUND);
514
+ }
515
+ const messages = {
516
+ attached: frameNavigatedDuringEvalError,
517
+ removed: frameRemovedDuringEvalError,
518
+ unknown: frameLostDuringEvalError,
519
+ };
520
+ const err = messages[await frameOwnerState(conn, frame)](frame.url);
521
+ return frameError(err, EXIT_CODES.RESOURCE_NOT_FOUND);
283
522
  }
284
523
  /**
285
524
  * Evaluate a `bdg dom eval` script in one iframe, like {@link evaluateScript}
@@ -288,18 +527,33 @@ async function resolveFrame(fc, query) {
288
527
  * @param page - The session's connection
289
528
  * @param wsUrl - WebSocket URL of the page target
290
529
  * @param script - JavaScript expression
291
- * @param query - Requested frame (index, name/id attribute, or part of the URL)
530
+ * @param query - Requested frame (index, name/id attribute, or part of the name, id or URL)
531
+ * @param listedIds - Frame id behind each index of the last `dom frames` listing, if any
292
532
  * @returns Value, type and the frame's URL
293
- * @throws CommandError (81/83) when the frame is ambiguous or missing, else as evaluateScript
533
+ * @throws CommandError (81/83) when the frame is ambiguous or missing, (87)
534
+ * when an index names another frame than when it was listed, (83) when it
535
+ * navigated or was removed while the script ran, else as evaluateScript
294
536
  */
295
- export async function evaluateInFrame(page, wsUrl, script, query) {
537
+ export async function evaluateInFrame(page, wsUrl, script, query, listedIds) {
296
538
  return withFrameConnection(page, wsUrl, async (fc) => {
297
- const { frame, uniqueContextId } = await resolveFrame(fc, query);
298
- const result = await evaluateScript(fc.conn, script, {
299
- ...(frame.sessionId && { sessionId: frame.sessionId }),
300
- uniqueContextId,
301
- });
302
- return { ...result, frame: frame.info.url };
539
+ const { frame, uniqueContextId } = await resolveFrame(fc, query, listedIds);
540
+ try {
541
+ const result = await evaluateScript(fc.conn, script, {
542
+ ...(frame.sessionId && { sessionId: frame.sessionId }),
543
+ uniqueContextId,
544
+ recovery: recoverySender(fc, frame.sessionId),
545
+ });
546
+ return { ...result, frame: frame.info.url };
547
+ }
548
+ catch (error) {
549
+ if (!isContextLostError(error))
550
+ throw error;
551
+ throw await frameContextLostError(fc.conn, fc.page, {
552
+ frameId: frame.frameId,
553
+ url: frame.info.url,
554
+ ...(frame.ownerSession && { ownerSession: frame.ownerSession }),
555
+ });
556
+ }
303
557
  });
304
558
  }
305
559
  //# sourceMappingURL=frames.js.map
@@ -0,0 +1,28 @@
1
+ /**
2
+ * `bdg dom inspect`: what one element looks like, read in the daemon.
3
+ *
4
+ * The element is found like the other element commands find it (selector
5
+ * with filters through open shadow roots and same-origin iframes, or the
6
+ * exact cached node). Then, in parallel: one page-side walk on the element
7
+ * ({@link INSPECT_PAGE_JS}: text, placement in the parent, backgrounds, child
8
+ * tree), `dom layout`'s measurement (page position, hidden, covered,
9
+ * offscreen) and, once the nodes are pushed to CDP, `CSS.getComputedStyleForNode`
10
+ * for the element, its layout parent and its `::before`/`::after`,
11
+ * `CSS.getPlatformFontsForNode` for its text and `DOM.getBoxModel`. DOM and
12
+ * CSS are enabled on the first inspect and kept on. Matched rules are not
13
+ * read (no cascade).
14
+ */
15
+ import type { CDPConnection } from '../../connection/cdp.js';
16
+ import type { DomInspectCommand } from '../../ipc/protocol/commands.js';
17
+ import type { InspectResult } from '../../ipc/protocol/inspectTypes.js';
18
+ /**
19
+ * Inspect one element.
20
+ *
21
+ * @param cdp - CDP connection
22
+ * @param params - Selector (and index) or backend node id, and options
23
+ * @returns Inspect result
24
+ * @throws CommandError (83) no match, (81) index out of range, invalid
25
+ * selector or unknown property, (87) the cached element left the page
26
+ */
27
+ export declare function inspectElement(cdp: CDPConnection, params: DomInspectCommand): Promise<InspectResult>;
28
+ //# sourceMappingURL=inspect.d.ts.map