browser-debugger-cli 0.11.0 → 0.13.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 (222) hide show
  1. package/.claude/skills/bdg/SKILL.md +4 -4
  2. package/README.md +143 -79
  3. package/dist/commands/cdp.d.ts +22 -1
  4. package/dist/commands/cdp.js +100 -43
  5. package/dist/commands/console.d.ts +12 -0
  6. package/dist/commands/console.js +62 -12
  7. package/dist/commands/css.d.ts +13 -0
  8. package/dist/commands/css.js +53 -0
  9. package/dist/commands/dom/DomElementResolver.d.ts +3 -1
  10. package/dist/commands/dom/DomElementResolver.js +10 -3
  11. package/dist/commands/dom/a11y.js +3 -2
  12. package/dist/commands/dom/audit.d.ts +14 -0
  13. package/dist/commands/dom/audit.js +87 -0
  14. package/dist/commands/dom/eval.d.ts +3 -2
  15. package/dist/commands/dom/eval.js +11 -5
  16. package/dist/commands/dom/form.js +10 -9
  17. package/dist/commands/dom/formInteraction.js +42 -11
  18. package/dist/commands/dom/get.js +8 -8
  19. package/dist/commands/dom/helpers/index.d.ts +1 -1
  20. package/dist/commands/dom/helpers/index.js +1 -1
  21. package/dist/commands/dom/helpers/keyAttributes.d.ts +3 -2
  22. package/dist/commands/dom/helpers/keyAttributes.js +6 -4
  23. package/dist/commands/dom/helpers/query.d.ts +27 -3
  24. package/dist/commands/dom/helpers/query.js +152 -64
  25. package/dist/commands/dom/helpers/screenshot.d.ts +1 -0
  26. package/dist/commands/dom/helpers/screenshot.js +169 -49
  27. package/dist/commands/dom/index.js +7 -2
  28. package/dist/commands/dom/query.d.ts +19 -2
  29. package/dist/commands/dom/query.js +37 -6
  30. package/dist/commands/dom/screenshot.js +12 -7
  31. package/dist/commands/dom/semanticUtils.d.ts +3 -2
  32. package/dist/commands/dom/semanticUtils.js +40 -9
  33. package/dist/commands/dom/wait.js +5 -3
  34. package/dist/commands/helpJson.d.ts +82 -19
  35. package/dist/commands/helpJson.js +112 -41
  36. package/dist/commands/helpTopic.d.ts +16 -1
  37. package/dist/commands/helpTopic.js +59 -1
  38. package/dist/commands/installSkill.d.ts +15 -5
  39. package/dist/commands/installSkill.js +86 -16
  40. package/dist/commands/network/list.js +22 -12
  41. package/dist/commands/optionBehaviors.js +53 -16
  42. package/dist/commands/page.js +7 -4
  43. package/dist/commands/peek.d.ts +7 -0
  44. package/dist/commands/peek.js +65 -23
  45. package/dist/commands/shared/daemonErrorHandler.d.ts +5 -2
  46. package/dist/commands/shared/daemonErrorHandler.js +20 -9
  47. package/dist/commands/shared/dataFetcher.d.ts +12 -4
  48. package/dist/commands/shared/dataFetcher.js +12 -4
  49. package/dist/commands/shared/followMode.d.ts +9 -1
  50. package/dist/commands/shared/followMode.js +22 -4
  51. package/dist/commands/shared/optionTypes.d.ts +9 -2
  52. package/dist/commands/shared/outputFile.js +6 -1
  53. package/dist/commands/start.d.ts +20 -5
  54. package/dist/commands/start.js +84 -23
  55. package/dist/commands/stop.d.ts +11 -0
  56. package/dist/commands/stop.js +24 -1
  57. package/dist/commands/tail.d.ts +7 -1
  58. package/dist/commands/tail.js +13 -62
  59. package/dist/commands.js +2 -0
  60. package/dist/connection/cdp.d.ts +7 -0
  61. package/dist/connection/cdp.js +9 -0
  62. package/dist/connection/launcher.js +3 -2
  63. package/dist/daemon/SessionController.js +6 -1
  64. package/dist/daemon/launcher.d.ts +3 -2
  65. package/dist/daemon/launcher.js +47 -3
  66. package/dist/daemon/session/Session.d.ts +4 -1
  67. package/dist/daemon/session/Session.js +33 -2
  68. package/dist/daemon/session/TelemetryStore.d.ts +8 -1
  69. package/dist/daemon/session/TelemetryStore.js +13 -1
  70. package/dist/daemon/session/commandRegistry.js +36 -14
  71. package/dist/daemon/session/interactions.d.ts +2 -1
  72. package/dist/daemon/session/interactions.js +13 -1
  73. package/dist/daemon/session/plugins.js +19 -53
  74. package/dist/daemon/session/teardown.js +1 -1
  75. package/dist/daemon.js +9234 -7222
  76. package/dist/errors/messages.d.ts +88 -15
  77. package/dist/errors/messages.js +177 -27
  78. package/dist/index.js +19322 -13961
  79. package/dist/ipc/client.d.ts +22 -2
  80. package/dist/ipc/client.js +34 -5
  81. package/dist/ipc/protocol/auditTypes.d.ts +135 -0
  82. package/dist/ipc/protocol/auditTypes.js +6 -0
  83. package/dist/ipc/protocol/commands.d.ts +35 -0
  84. package/dist/ipc/protocol/commands.js +2 -0
  85. package/dist/ipc/protocol/domTypes.d.ts +16 -0
  86. package/dist/ipc/protocol/inspectTypes.d.ts +73 -8
  87. package/dist/ipc/session/types.d.ts +2 -0
  88. package/dist/runtime/css/search.d.ts +39 -0
  89. package/dist/runtime/css/search.js +122 -0
  90. package/dist/runtime/dom/actionEffects.d.ts +9 -2
  91. package/dist/runtime/dom/actionEffects.js +30 -14
  92. package/dist/runtime/dom/audit.d.ts +19 -0
  93. package/dist/runtime/dom/audit.js +37 -0
  94. package/dist/runtime/dom/auditModel.d.ts +45 -0
  95. package/dist/runtime/dom/auditModel.js +220 -0
  96. package/dist/runtime/dom/auditScripts.d.ts +113 -0
  97. package/dist/runtime/dom/auditScripts.js +148 -0
  98. package/dist/runtime/dom/elementGeometry.d.ts +16 -3
  99. package/dist/runtime/dom/elementGeometry.js +49 -10
  100. package/dist/runtime/dom/elementInfo.d.ts +74 -17
  101. package/dist/runtime/dom/elementInfo.js +187 -34
  102. package/dist/runtime/dom/evalHelpers.d.ts +12 -2
  103. package/dist/runtime/dom/evalHelpers.js +67 -7
  104. package/dist/runtime/dom/formDiscovery.d.ts +6 -2
  105. package/dist/runtime/dom/formDiscovery.js +20 -3
  106. package/dist/runtime/dom/formFillHelpers/fill.js +8 -12
  107. package/dist/runtime/dom/formFillHelpers/pressKey.js +2 -2
  108. package/dist/runtime/dom/formFillHelpers/shared.d.ts +16 -10
  109. package/dist/runtime/dom/formFillHelpers/shared.js +19 -52
  110. package/dist/runtime/dom/formSubmitHelpers.js +4 -3
  111. package/dist/runtime/dom/frameLayout.js +1 -0
  112. package/dist/runtime/dom/inspect.d.ts +7 -0
  113. package/dist/runtime/dom/inspect.js +92 -28
  114. package/dist/runtime/dom/inspectAllStyles.d.ts +16 -4
  115. package/dist/runtime/dom/inspectAllStyles.js +90 -7
  116. package/dist/runtime/dom/inspectCascade.d.ts +19 -2
  117. package/dist/runtime/dom/inspectCascade.js +214 -44
  118. package/dist/runtime/dom/inspectCascadeModel.d.ts +8 -0
  119. package/dist/runtime/dom/inspectCascadeModel.js +108 -34
  120. package/dist/runtime/dom/inspectHints.d.ts +26 -3
  121. package/dist/runtime/dom/inspectHints.js +125 -9
  122. package/dist/runtime/dom/inspectModel.d.ts +5 -1
  123. package/dist/runtime/dom/inspectModel.js +37 -10
  124. package/dist/runtime/dom/inspectPaintModel.d.ts +50 -22
  125. package/dist/runtime/dom/inspectPaintModel.js +182 -68
  126. package/dist/runtime/dom/inspectRules.d.ts +19 -0
  127. package/dist/runtime/dom/inspectRules.js +21 -5
  128. package/dist/runtime/dom/inspectScripts.d.ts +112 -12
  129. package/dist/runtime/dom/inspectScripts.js +357 -32
  130. package/dist/runtime/dom/inspectTree.js +10 -2
  131. package/dist/runtime/dom/inspectWhyModel.d.ts +2 -1
  132. package/dist/runtime/dom/inspectWhyModel.js +52 -10
  133. package/dist/runtime/dom/layout.js +40 -16
  134. package/dist/runtime/dom/reactEventHelpers.d.ts +21 -4
  135. package/dist/runtime/dom/reactEventHelpers.js +90 -36
  136. package/dist/runtime/dom/targetNode.d.ts +18 -5
  137. package/dist/runtime/dom/targetNode.js +268 -8
  138. package/dist/runtime/dom/wait.js +2 -1
  139. package/dist/runtime/page/bdgWorld.d.ts +57 -0
  140. package/dist/runtime/page/bdgWorld.js +180 -0
  141. package/dist/runtime/page/emulation.d.ts +13 -4
  142. package/dist/runtime/page/emulation.js +69 -4
  143. package/dist/runtime/page/replacedBuiltins.d.ts +28 -0
  144. package/dist/runtime/page/replacedBuiltins.js +136 -0
  145. package/dist/runtime/page/userAgent.d.ts +17 -0
  146. package/dist/runtime/page/userAgent.js +57 -0
  147. package/dist/session/QueryCacheManager.d.ts +4 -1
  148. package/dist/session/QueryCacheManager.js +5 -2
  149. package/dist/session/chrome.d.ts +4 -1
  150. package/dist/session/chrome.js +7 -1
  151. package/dist/session/cleanup/staleSession.d.ts +21 -4
  152. package/dist/session/cleanup/staleSession.js +79 -9
  153. package/dist/session/cleanup/userCommands.d.ts +4 -1
  154. package/dist/session/cleanup/userCommands.js +10 -5
  155. package/dist/session/daemonSocket.d.ts +10 -0
  156. package/dist/session/daemonSocket.js +22 -0
  157. package/dist/session/lastSession.d.ts +6 -3
  158. package/dist/session/lastSession.js +11 -5
  159. package/dist/session/paths.d.ts +3 -1
  160. package/dist/session/paths.js +5 -5
  161. package/dist/session/portClaims.js +4 -3
  162. package/dist/session/sessionList.d.ts +13 -5
  163. package/dist/session/sessionList.js +31 -7
  164. package/dist/telemetry/a11y.js +2 -2
  165. package/dist/telemetry/console.d.ts +2 -1
  166. package/dist/telemetry/console.js +30 -21
  167. package/dist/telemetry/pageCrash.d.ts +26 -0
  168. package/dist/telemetry/pageCrash.js +53 -0
  169. package/dist/types.d.ts +20 -0
  170. package/dist/ui/formatters/audit.d.ts +19 -0
  171. package/dist/ui/formatters/audit.js +115 -0
  172. package/dist/ui/formatters/cdp.d.ts +138 -0
  173. package/dist/ui/formatters/cdp.js +131 -0
  174. package/dist/ui/formatters/console/chronological.js +3 -1
  175. package/dist/ui/formatters/console/follow.d.ts +2 -1
  176. package/dist/ui/formatters/console/follow.js +2 -2
  177. package/dist/ui/formatters/console/json.d.ts +2 -2
  178. package/dist/ui/formatters/console/json.js +11 -5
  179. package/dist/ui/formatters/console/shared.d.ts +30 -0
  180. package/dist/ui/formatters/console/shared.js +16 -0
  181. package/dist/ui/formatters/console/summarize.d.ts +9 -2
  182. package/dist/ui/formatters/console/summarize.js +40 -9
  183. package/dist/ui/formatters/console.d.ts +2 -1
  184. package/dist/ui/formatters/console.js +7 -5
  185. package/dist/ui/formatters/details.js +3 -1
  186. package/dist/ui/formatters/dom.d.ts +2 -2
  187. package/dist/ui/formatters/dom.js +10 -8
  188. package/dist/ui/formatters/helpFormatters.js +1 -1
  189. package/dist/ui/formatters/inspect.js +50 -17
  190. package/dist/ui/formatters/installSkill.d.ts +9 -1
  191. package/dist/ui/formatters/installSkill.js +32 -6
  192. package/dist/ui/formatters/layout.js +2 -1
  193. package/dist/ui/formatters/networkList.d.ts +1 -1
  194. package/dist/ui/formatters/networkList.js +1 -2
  195. package/dist/ui/formatters/preview.d.ts +2 -0
  196. package/dist/ui/formatters/preview.js +17 -7
  197. package/dist/ui/formatters/sessions.d.ts +2 -2
  198. package/dist/ui/formatters/sessions.js +9 -2
  199. package/dist/ui/formatters/status.js +1 -1
  200. package/dist/ui/logging/logger.d.ts +1 -1
  201. package/dist/ui/messages/commands.d.ts +168 -11
  202. package/dist/ui/messages/commands.js +245 -18
  203. package/dist/ui/messages/consoleMessages.d.ts +24 -0
  204. package/dist/ui/messages/consoleMessages.js +32 -0
  205. package/dist/ui/messages/preview.d.ts +12 -0
  206. package/dist/ui/messages/preview.js +18 -2
  207. package/dist/ui/messages/session.d.ts +13 -2
  208. package/dist/ui/messages/session.js +22 -3
  209. package/dist/utils/cssValues.js +36 -4
  210. package/dist/utils/decisionTrees.js +0 -5
  211. package/dist/utils/directories.d.ts +34 -0
  212. package/dist/utils/directories.js +88 -0
  213. package/dist/utils/display.d.ts +16 -0
  214. package/dist/utils/display.js +42 -0
  215. package/dist/utils/exitCodes.d.ts +1 -0
  216. package/dist/utils/exitCodes.js +6 -0
  217. package/dist/utils/process.d.ts +12 -0
  218. package/dist/utils/process.js +25 -0
  219. package/dist/utils/suggestions.d.ts +4 -2
  220. package/dist/utils/suggestions.js +7 -5
  221. package/dist/utils/taskMappings.js +1 -1
  222. package/package.json +3 -2
@@ -178,8 +178,10 @@ export declare function getNetworkHeaders(options?: {
178
178
  *
179
179
  * @param method - CDP method name (e.g., 'Network.getCookies')
180
180
  * @param params - Optional method parameters
181
+ * @param options - `isolated`: a bdg page script, run in bdg's isolated world
182
+ * (`Runtime.evaluate`, `DOM.resolveNode`)
181
183
  * @returns Response with CDP method result
182
- * @throws Error if connection fails; CommandError (102) when the page was busy and its scripts were terminated
184
+ * @throws Error if connection fails; CommandError (102) when the page was busy and its scripts were terminated, (107) when the page crashed
183
185
  *
184
186
  * @example
185
187
  * ```typescript
@@ -189,7 +191,21 @@ export declare function getNetworkHeaders(options?: {
189
191
  * }
190
192
  * ```
191
193
  */
192
- export declare function callCDP(method: string, params?: Record<string, unknown>): Promise<ClientResponse<'cdp_call'>>;
194
+ export declare function callCDP(method: string, params?: Record<string, unknown>, options?: {
195
+ isolated?: boolean;
196
+ }): Promise<ClientResponse<'cdp_call'>>;
197
+ /**
198
+ * Send a CDP call for one of bdg's own page scripts: `Runtime.evaluate` and
199
+ * `DOM.resolveNode` run in bdg's isolated world, so a page that replaced
200
+ * built-ins (`querySelectorAll`, `JSON.stringify`) cannot change what they
201
+ * find or return.
202
+ *
203
+ * @param method - CDP method name
204
+ * @param params - Method parameters
205
+ * @returns Response with the CDP method result
206
+ * @throws Like {@link callCDP}
207
+ */
208
+ export declare function callBdgScript(method: string, params?: Record<string, unknown>): Promise<ClientResponse<'cdp_call'>>;
193
209
  /**
194
210
  * Evaluate a JavaScript expression in the active page (or one of its iframes) via the daemon.
195
211
  */
@@ -231,6 +247,10 @@ export declare function domFormDiscover(): Promise<ClientResponse<'dom_form_disc
231
247
  export declare function domListeners(params: NoType<(typeof COMMANDS)['dom_listeners']['requestSchema']>): Promise<ClientResponse<'dom_listeners'>>;
232
248
  /** Positions, sizes and visibility of elements. */
233
249
  export declare function domLayout(params: NoType<(typeof COMMANDS)['dom_layout']['requestSchema']>): Promise<ClientResponse<'dom_layout'>>;
250
+ /** Page-wide checks: contrast, overflow, layers, animations. */
251
+ export declare function domAudit(params: NoType<(typeof COMMANDS)['dom_audit']['requestSchema']>): Promise<ClientResponse<'dom_audit'>>;
252
+ /** Find text in the page's stylesheets. */
253
+ export declare function cssSearch(params: NoType<(typeof COMMANDS)['css_search']['requestSchema']>): Promise<ClientResponse<'css_search'>>;
234
254
  /** What one element looks like: styles, box, layout and child tree. */
235
255
  export declare function domInspect(params: NoType<(typeof COMMANDS)['dom_inspect']['requestSchema']>): Promise<ClientResponse<'dom_inspect'>>;
236
256
  /**
@@ -251,8 +251,10 @@ export async function getNetworkHeaders(options) {
251
251
  *
252
252
  * @param method - CDP method name (e.g., 'Network.getCookies')
253
253
  * @param params - Optional method parameters
254
+ * @param options - `isolated`: a bdg page script, run in bdg's isolated world
255
+ * (`Runtime.evaluate`, `DOM.resolveNode`)
254
256
  * @returns Response with CDP method result
255
- * @throws Error if connection fails; CommandError (102) when the page was busy and its scripts were terminated
257
+ * @throws Error if connection fails; CommandError (102) when the page was busy and its scripts were terminated, (107) when the page crashed
256
258
  *
257
259
  * @example
258
260
  * ```typescript
@@ -262,13 +264,32 @@ export async function getNetworkHeaders(options) {
262
264
  * }
263
265
  * ```
264
266
  */
265
- export async function callCDP(method, params) {
266
- const response = await sendCommand('cdp_call', { method, ...(params && { params }) });
267
- if (response.status === 'error' && response.exitCode === EXIT_CODES.CDP_TIMEOUT) {
268
- throw new CommandError(response.error ?? `${method} timed out`, response.suggestion ? { suggestion: response.suggestion } : {}, EXIT_CODES.CDP_TIMEOUT);
267
+ export async function callCDP(method, params, options = {}) {
268
+ const response = await sendCommand('cdp_call', {
269
+ method,
270
+ ...(params && { params }),
271
+ ...(options.isolated && { isolated: true }),
272
+ });
273
+ const fatal = [EXIT_CODES.CDP_TIMEOUT, EXIT_CODES.PAGE_CRASHED];
274
+ if (response.status === 'error' && response.exitCode && fatal.includes(response.exitCode)) {
275
+ throw new CommandError(response.error ?? `${method} failed`, response.suggestion ? { suggestion: response.suggestion } : {}, response.exitCode);
269
276
  }
270
277
  return response;
271
278
  }
279
+ /**
280
+ * Send a CDP call for one of bdg's own page scripts: `Runtime.evaluate` and
281
+ * `DOM.resolveNode` run in bdg's isolated world, so a page that replaced
282
+ * built-ins (`querySelectorAll`, `JSON.stringify`) cannot change what they
283
+ * find or return.
284
+ *
285
+ * @param method - CDP method name
286
+ * @param params - Method parameters
287
+ * @returns Response with the CDP method result
288
+ * @throws Like {@link callCDP}
289
+ */
290
+ export function callBdgScript(method, params) {
291
+ return callCDP(method, params, { isolated: true });
292
+ }
272
293
  /**
273
294
  * Evaluate a JavaScript expression in the active page (or one of its iframes) via the daemon.
274
295
  */
@@ -334,6 +355,14 @@ export async function domListeners(params) {
334
355
  export async function domLayout(params) {
335
356
  return sendCommand('dom_layout', params);
336
357
  }
358
+ /** Page-wide checks: contrast, overflow, layers, animations. */
359
+ export async function domAudit(params) {
360
+ return sendCommand('dom_audit', params);
361
+ }
362
+ /** Find text in the page's stylesheets. */
363
+ export async function cssSearch(params) {
364
+ return sendCommand('css_search', params);
365
+ }
337
366
  /** What one element looks like: styles, box, layout and child tree. */
338
367
  export async function domInspect(params) {
339
368
  return sendCommand('dom_inspect', params);
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Types of `bdg dom audit` (page-wide checks) and `bdg css search`.
3
+ */
4
+ /** A check `dom audit` can run */
5
+ export type AuditCheck = 'contrast' | 'overflow' | 'layers' | 'animations';
6
+ /** Every check, in the order they are shown */
7
+ export declare const AUDIT_CHECKS: readonly AuditCheck[];
8
+ /** Text below the contrast level */
9
+ export interface AuditContrastItem {
10
+ /** `tag#id` or `tag.firstClass` */
11
+ element: string;
12
+ text: string;
13
+ /** WCAG ratio, rounded down to 2 decimals */
14
+ ratio: number;
15
+ color: string;
16
+ /** Background behind the text, composited */
17
+ background: string;
18
+ /** Font size (px) and weight: large text needs less contrast */
19
+ size: number;
20
+ weight: number;
21
+ inView: boolean;
22
+ /** Opacity of the text and its ancestors, when below 1 (the colors are faded by it) */
23
+ opacity?: number;
24
+ /** Why the ratio is approximate (blend modes, filters, an element behind or on top, out of view) */
25
+ approximate?: string[];
26
+ }
27
+ /** An image drawn larger than its pixels, or with another aspect ratio */
28
+ export interface AuditImage {
29
+ element: string;
30
+ natural: {
31
+ w: number;
32
+ h: number;
33
+ };
34
+ rendered: {
35
+ w: number;
36
+ h: number;
37
+ };
38
+ /** Pixels needed (rendered size × pixel ratio) over the image's pixels, the larger of width and height */
39
+ scale: number;
40
+ /** Identical findings this one stands for (2 or more) */
41
+ count?: number;
42
+ upscaled?: true;
43
+ distorted?: true;
44
+ }
45
+ /** What `dom audit` found */
46
+ export interface AuditResult {
47
+ checks: AuditCheck[];
48
+ /** Elements walked */
49
+ walked: number;
50
+ /** The walk stopped at its cap: the page has more elements */
51
+ capped?: true;
52
+ contrast?: {
53
+ level: 'AA' | 'AAA';
54
+ /** Text holders checked */
55
+ checked: number;
56
+ /** How many are below the level (measured exactly) */
57
+ failing: number;
58
+ /** How many more look below the level but cannot be measured exactly (text over images, blend modes, layers): not listed, `dom inspect` them */
59
+ uncertain?: number;
60
+ /** The weakest ones, at most `--limit` */
61
+ items: AuditContrastItem[];
62
+ };
63
+ overflow?: {
64
+ pageWidth: number;
65
+ viewportWidth: number;
66
+ /** The page is wider than its viewport (it scrolls sideways) */
67
+ scrollsSideways: boolean;
68
+ /** Elements reaching past the viewport's right edge (not inside a scroller), farthest first */
69
+ wide: Array<{
70
+ element: string;
71
+ right: number;
72
+ width: number;
73
+ }>;
74
+ /** Text cut off: `ellipsis`, `clamp` or `clip` */
75
+ truncated: Array<{
76
+ element: string;
77
+ text: string;
78
+ kind: string;
79
+ count?: number;
80
+ }>;
81
+ images: AuditImage[];
82
+ /** Device pixel ratio the image scale counts in (an image needs that many pixels per CSS px) */
83
+ pixelRatio: number;
84
+ /** Elements whose content scrolls sideways inside them (carousels, tab strips): fine, but cut off at first sight */
85
+ scrollers: Array<{
86
+ element: string;
87
+ scrollWidth: number;
88
+ width: number;
89
+ }>;
90
+ };
91
+ layers?: Array<{
92
+ element: string;
93
+ position: string;
94
+ zIndex: string;
95
+ /** Viewport position and size */
96
+ rect: {
97
+ x: number;
98
+ y: number;
99
+ w: number;
100
+ h: number;
101
+ };
102
+ inView: boolean;
103
+ }>;
104
+ animations?: Array<{
105
+ element: string;
106
+ name: string;
107
+ type: string;
108
+ /** Duration (ms) */
109
+ duration: number | string;
110
+ iterations: number | string;
111
+ /** Driven by scrolling, not time */
112
+ scrollDriven?: true;
113
+ /** Identical animations this one stands for (2 or more) */
114
+ count?: number;
115
+ }>;
116
+ /** Visible `<canvas>` elements: scripts may animate them, which `animations` cannot see */
117
+ canvases?: number;
118
+ }
119
+ /** A stylesheet line where `css search` found the text */
120
+ export interface CssSearchMatch {
121
+ /** `app.css:12`, `bootstrap.min.css:5:52628`, `<style> in index.html:40` */
122
+ source: string;
123
+ /** The rule (or line) around the match, cut to a few hundred characters */
124
+ text: string;
125
+ }
126
+ /** What `css search` found */
127
+ export interface CssSearchResult {
128
+ query: string;
129
+ /** Stylesheets searched */
130
+ sheets: number;
131
+ /** Matches found (the list may be shorter: `--limit`) */
132
+ total: number;
133
+ matches: CssSearchMatch[];
134
+ }
135
+ //# sourceMappingURL=auditTypes.d.ts.map
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Types of `bdg dom audit` (page-wide checks) and `bdg css search`.
3
+ */
4
+ /** Every check, in the order they are shown */
5
+ export const AUDIT_CHECKS = ['contrast', 'overflow', 'layers', 'animations'];
6
+ //# sourceMappingURL=auditTypes.js.map
@@ -5,6 +5,7 @@
5
5
  * Each command has a request schema (input) and response data schema (output).
6
6
  */
7
7
  import type { HintDetails } from '../../errors/notices.js';
8
+ import type { AuditCheck, AuditResult, CssSearchResult } from './auditTypes.js';
8
9
  import type { ClickResult, FillResult, LayoutResult, ListenersResult, PressKeyResult, RawFormData, ScrollResult, SubmitResult } from './domTypes.js';
9
10
  import type { InspectResult } from './inspectTypes.js';
10
11
  import type { PageState, SessionActivity } from '../session/types.js';
@@ -65,10 +66,14 @@ export interface SessionPeekData {
65
66
  }>;
66
67
  /** Navigation id of the page currently loaded. */
67
68
  currentNavigationId: number;
69
+ /** When the page's renderer crashed (epoch ms), while it is not loaded again */
70
+ pageCrashedAt?: number;
68
71
  /** Total number of network requests (for pagination). */
69
72
  totalNetwork: number;
70
73
  /** Total number of console messages (for pagination). */
71
74
  totalConsole: number;
75
+ /** Console messages dropped at the limit (the oldest; indices start after them) */
76
+ droppedConsole?: number;
72
77
  /** Whether there are more network items available. */
73
78
  hasMoreNetwork?: boolean;
74
79
  /** Whether there are more console items available. */
@@ -98,6 +103,12 @@ export interface CdpCallCommand {
98
103
  method: string;
99
104
  /** Optional parameters for the CDP method. */
100
105
  params?: Record<string, unknown>;
106
+ /**
107
+ * A bdg page script: `Runtime.evaluate` and `DOM.resolveNode` run in bdg's
108
+ * isolated world, out of reach of built-ins the page replaced (not for
109
+ * `bdg cdp`, whose calls stay in the page's world)
110
+ */
111
+ isolated?: boolean;
101
112
  }
102
113
  /**
103
114
  * CDP call command response data.
@@ -182,6 +193,8 @@ export interface DomEvalData {
182
193
  subtype?: string;
183
194
  /** URL of the iframe the script ran in (with `frame`; empty when it has none) */
184
195
  frame?: string;
196
+ /** Set when the page replaced built-ins bdg's copy of the result uses */
197
+ warning?: string;
185
198
  }
186
199
  /** An iframe of the page, as listed by `bdg dom frames` */
187
200
  export interface DomFrame {
@@ -312,6 +325,26 @@ export interface DomLayoutCommand {
312
325
  backendNodeId?: number;
313
326
  }
314
327
  export type DomLayoutData = LayoutResult;
328
+ /**
329
+ * dom_audit: page-wide checks (contrast, overflow, layers, animations).
330
+ */
331
+ export interface DomAuditCommand {
332
+ checks: AuditCheck[];
333
+ /** WCAG level text must reach (default AA) */
334
+ level?: 'AA' | 'AAA';
335
+ /** Findings listed per check */
336
+ limit?: number;
337
+ }
338
+ export type DomAuditData = AuditResult;
339
+ /**
340
+ * css_search: find text in the page's stylesheets.
341
+ */
342
+ export interface CssSearchCommand {
343
+ query: string;
344
+ /** Matches listed at most */
345
+ limit?: number;
346
+ }
347
+ export type CssSearchData = CssSearchResult;
315
348
  /**
316
349
  * dom_inspect: what one element looks like (styles, box, layout, child tree).
317
350
  */
@@ -369,6 +402,8 @@ export type RegistryShape = {
369
402
  dom_form_discover: CommandDef<DomFormDiscoverCommand, DomFormDiscoverData>;
370
403
  dom_listeners: CommandDef<DomListenersCommand, DomListenersData>;
371
404
  dom_layout: CommandDef<DomLayoutCommand, DomLayoutData>;
405
+ dom_audit: CommandDef<DomAuditCommand, DomAuditData>;
406
+ css_search: CommandDef<CssSearchCommand, CssSearchData>;
372
407
  dom_inspect: CommandDef<DomInspectCommand, DomInspectData>;
373
408
  dom_wait: CommandDef<DomWaitCommand, DomWaitData>;
374
409
  page_navigate: CommandDef<PageNavigateCommand, PageNavigationResult>;
@@ -35,6 +35,8 @@ export const COMMANDS = {
35
35
  dom_form_discover: defineCommand(),
36
36
  dom_listeners: defineCommand(),
37
37
  dom_layout: defineCommand(),
38
+ dom_audit: defineCommand(),
39
+ css_search: defineCommand(),
38
40
  dom_inspect: defineCommand(),
39
41
  dom_wait: defineCommand(),
40
42
  };
@@ -86,6 +86,8 @@ export interface ActionEffects {
86
86
  navigation?: PageNavigation;
87
87
  /** Messages that appeared or changed (at most 3; absent when none did) */
88
88
  messages?: NewMessage[];
89
+ /** How many more new messages there were than `messages` lists */
90
+ moreMessages?: number;
89
91
  /** Elements a hover or key press showed (at most 3, outermost first; absent when none) */
90
92
  shown?: ShownElement[];
91
93
  /** "none" when the action had no visible effect: no DOM change, request or navigation */
@@ -94,6 +96,8 @@ export interface ActionEffects {
94
96
  settled?: false;
95
97
  /** What the page was still working on (with `settled: false`) */
96
98
  pending?: PendingChanges;
99
+ /** All built-ins the page replaced that bdg's action scripts use (when the warning mentions them) */
100
+ replacedBuiltins?: string[];
97
101
  }
98
102
  /** A filled field's value differing from the one given */
99
103
  export interface FillValueMismatch {
@@ -163,6 +167,11 @@ export interface ClickResult extends ActionEffects {
163
167
  method?: 'mouse' | 'dom';
164
168
  /** What was done: click, double (click), right (click) or hover */
165
169
  action?: 'click' | 'double' | 'right' | 'hover';
170
+ /** How far the page scrolled to bring the element into view (CSS px; absent when it did not move) */
171
+ scrolledBy?: {
172
+ x: number;
173
+ y: number;
174
+ };
166
175
  /** Exit code for a failure */
167
176
  exitCode?: number;
168
177
  /** Why the DOM fallback was used (element covered or without size) */
@@ -405,6 +414,8 @@ export interface ElementLayout {
405
414
  scrollBy?: LayoutPoint;
406
415
  /** Ancestor or iframe cutting it off (scroll that container instead of the page) */
407
416
  clippedBy?: string;
417
+ /** It or a container is `position: fixed`: page scroll does not move it */
418
+ fixed?: true;
408
419
  /** Why page scroll cannot bring it fully into view: it is fixed, or beyond the page's scroll range */
409
420
  offScreenReason?: string;
410
421
  /** Topmost element at the center of its visible part, when that is another element */
@@ -421,6 +432,11 @@ export interface ElementLayout {
421
432
  * `opacity: 0 on div#menu` (`inViewport` still says where it is)
422
433
  */
423
434
  invisible?: string;
435
+ /**
436
+ * A `mask-image` on it or an ancestor, e.g. `mask-image on div.hero`: part
437
+ * or all of it may not show (how much is not evaluated)
438
+ */
439
+ masked?: string;
424
440
  /** Inside an `inert` element: shown, but a user cannot interact with it */
425
441
  inert?: true;
426
442
  computed: LayoutComputedStyle;
@@ -14,6 +14,13 @@ export interface InspectRect {
14
14
  y: number;
15
15
  w: number;
16
16
  h: number;
17
+ /** `viewport`: x and y are in the viewport (a fixed element stays there however the page scrolls) */
18
+ in?: 'viewport';
19
+ /** Size of the box it covers on screen when a transform (rotation, skew) makes that differ; x and y are its corner */
20
+ screen?: {
21
+ w: number;
22
+ h: number;
23
+ };
17
24
  }
18
25
  /** Sides top, right, bottom, left */
19
26
  export type Sides = [CssLength, CssLength, CssLength, CssLength];
@@ -104,17 +111,29 @@ export interface InspectContrast {
104
111
  /** A background image or gradient is behind the text: the ratio uses the colors only */
105
112
  overImage?: boolean;
106
113
  /**
107
- * Opacity of the element and its ancestors (below 1): the text color is
108
- * faded by it before the ratio is taken (backgrounds inside the faded
109
- * subtree are not, so the ratio is approximate)
114
+ * Opacity of the element and its ancestors (below 1): each translucent
115
+ * element fades its background and the text over it before the ratio is
116
+ * taken
110
117
  */
111
118
  opacity?: number;
119
+ /**
120
+ * Why the ratio is approximate: `mix-blend-mode hard-light on h1`,
121
+ * `filter on div.skin-invert`, `canvas behind`, `div.overlay on top`
122
+ */
123
+ approximate?: string[];
112
124
  }
113
125
  /** Typography (for containers without text of their own: only what differs from the parent) */
114
126
  export interface InspectText {
127
+ /**
128
+ * Label of the descendant that draws most of the text when it is not the
129
+ * element (`abbr`, `slot.button__label`): the fields describe its text
130
+ */
131
+ holder?: string;
115
132
  family?: string;
116
- /** Font Chrome rendered the text with, when it is not the first family */
133
+ /** Font Chrome rendered the text with, when it is a fallback for the first family */
117
134
  rendered?: string;
135
+ /** Font a generic first family (`sans-serif`, `system-ui`) resolved to */
136
+ resolved?: string;
118
137
  /** The rendered font is a web font */
119
138
  webfont?: boolean;
120
139
  weight?: number;
@@ -132,19 +151,30 @@ export interface InspectText {
132
151
  clamp?: string;
133
152
  shadow?: string;
134
153
  features?: string;
154
+ /** The text is cut off (clipped by overflow, with or without an ellipsis, or by a line clamp) */
155
+ truncated?: true;
156
+ /** The text is painted with its background (`background-clip: text`, transparent fill): no single color, so no contrast */
157
+ gradientFill?: true;
135
158
  }
136
159
  /** A background layer */
137
160
  export type InspectFill = {
138
161
  type: 'solid';
139
162
  color: string;
140
163
  } | {
141
- type: 'gradient';
142
- value: string;
143
- } | {
144
- type: 'image';
164
+ type: 'gradient' | 'image';
145
165
  value: string;
146
166
  size?: string;
167
+ position?: string;
147
168
  };
169
+ /** How an SVG element is painted */
170
+ export interface InspectSvgPaint {
171
+ /** Fill color (hex), `none` or a paint server (`url(#grad)`) */
172
+ fill: string;
173
+ /** Stroke color, `none` or a paint server */
174
+ stroke: string;
175
+ /** Stroke width (px), when there is a stroke */
176
+ strokeWidth?: CssLength;
177
+ }
148
178
  /** A border side (or all four) */
149
179
  export interface InspectStroke {
150
180
  side: 'all' | 'top' | 'right' | 'bottom' | 'left';
@@ -184,6 +214,8 @@ export interface InspectPseudo {
184
214
  content?: string;
185
215
  display?: string;
186
216
  position?: string;
217
+ /** Offsets of a positioned one (top right bottom left) */
218
+ inset?: string;
187
219
  size?: {
188
220
  w: number;
189
221
  h: number;
@@ -212,6 +244,12 @@ export interface InspectTreeNode {
212
244
  /** `flex` or `grid` container */
213
245
  layout?: 'flex' | 'grid';
214
246
  text?: string;
247
+ /** `display: contents` (a text-only slot): no box of its own */
248
+ contents?: true;
249
+ /** Reached through a slot or a `display: contents` wrapper (`slot.label`, `div.row (contents)`) */
250
+ via?: string;
251
+ /** In the shadow root of its parent */
252
+ shadow?: true;
215
253
  /** Identical siblings this row stands for (2 or more) */
216
254
  count?: number;
217
255
  children?: InspectTreeNode[];
@@ -232,6 +270,8 @@ export interface InspectVisibility {
232
270
  coveredBy?: string;
233
271
  /** The cover paints nothing there: the element shows, but clicks land on the cover */
234
272
  coverTransparent?: true;
273
+ /** A `mask-image` on it or an ancestor, e.g. `mask-image on div.hero` (how much it hides is not evaluated) */
274
+ masked?: string;
235
275
  }
236
276
  /** A property asked for with `--props` */
237
277
  export interface InspectProp {
@@ -251,6 +291,10 @@ export interface InspectHint {
251
291
  reason: string;
252
292
  /** e.g. `use display: flex or grid on this element` */
253
293
  fix: string;
294
+ /** The longhands of a shorthand that have no effect, when the others do (`margin-top`, `margin-bottom`) */
295
+ only?: string[];
296
+ /** The custom properties that are not set (`unset-variable`) */
297
+ variables?: string[];
254
298
  /** e.g. `.hero (app.css:12)` */
255
299
  source: string;
256
300
  }
@@ -264,6 +308,8 @@ export interface InspectRule {
264
308
  computed?: string;
265
309
  /** e.g. `.btn-primary (bootstrap.min.css:5:52628)`, `style attribute` */
266
310
  source: string;
311
+ /** The rule as written (selector and declarations); a rule over 300 characters is cut to its selector and this declaration */
312
+ rule?: string;
267
313
  /** Selectors of the declarations it beats */
268
314
  overrides?: string[];
269
315
  /** Set on an ancestor this many levels up (inherited) */
@@ -286,8 +332,15 @@ export interface InspectWhyEntry {
286
332
  source: string;
287
333
  /** Specificity of the rule's selector (ids, classes, types) */
288
334
  specificity?: [number, number, number];
335
+ /** The rule as written (selector and declarations); a rule over 300 characters is cut to its selector and this declaration */
336
+ rule?: string;
289
337
  /** `applied` (wins), `overridden`, or `inherited` (from an ancestor: the winner, or one it beat there) */
290
338
  status: 'applied' | 'overridden' | 'inherited';
339
+ /**
340
+ * Why the winner changes nothing: `no effect: position is static`, or for
341
+ * an invalid `var()`, what applies instead (`falls back to the initial value`)
342
+ */
343
+ note?: string;
291
344
  important?: true;
292
345
  layer?: string;
293
346
  condition?: string;
@@ -300,6 +353,12 @@ export interface InspectWhy {
300
353
  chain: InspectWhyEntry[];
301
354
  /** Where the custom properties of the winning value are set */
302
355
  variables?: InspectVariable[];
356
+ /** Rules for the element that set it under a `@media`/`@supports` condition that does not apply now */
357
+ inactive?: Array<{
358
+ value: string;
359
+ selector: string;
360
+ condition: string;
361
+ }>;
303
362
  }
304
363
  /** A custom property a winning value uses, and where it is set */
305
364
  export interface InspectVariable {
@@ -324,6 +383,8 @@ export interface InspectResult {
324
383
  * rendered) or the first
325
384
  */
326
385
  picked?: 'first-visible' | 'first';
386
+ /** The selector named a pseudo-element (`a::after`): its element was inspected, the pseudo-element is under `pseudo` */
387
+ pseudoOf?: '::before' | '::after';
327
388
  /** `tag#id.c1.c2(+N)` */
328
389
  element: string;
329
390
  /** Its text (innerText) or form value, at most 30 characters; not for containers */
@@ -341,6 +402,8 @@ export interface InspectResult {
341
402
  * theme's
342
403
  */
343
404
  theme?: 'dark';
405
+ /** The dark preference behind `theme` comes from `page emulate`, not the system */
406
+ themeFrom?: 'emulation';
344
407
  /**
345
408
  * Running CSS transitions (their property) and animations (their name):
346
409
  * the values read are mid-way and will still change
@@ -352,6 +415,8 @@ export interface InspectResult {
352
415
  layout?: InspectLayout;
353
416
  text?: InspectText;
354
417
  fills?: InspectFill[];
418
+ /** SVG paint: `fill` and `stroke` (with its width) of an SVG element */
419
+ paint?: InspectSvgPaint;
355
420
  opacity?: number;
356
421
  blend?: string;
357
422
  strokes?: InspectStroke[];
@@ -29,5 +29,7 @@ export interface PageState {
29
29
  viewport?: ViewportSize;
30
30
  /** `prefers-color-scheme` the page sees (left out when the page did not answer in time). */
31
31
  colorScheme?: ColorScheme;
32
+ /** When the page's renderer crashed (epoch ms); `bdg page reload` brings it back */
33
+ crashedAt?: number;
32
34
  }
33
35
  //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,39 @@
1
+ /**
2
+ * `bdg css search <text>`: find text in the page's stylesheets, cross-origin
3
+ * ones included (CDP reads every stylesheet's text), and show the rule
4
+ * around each match with its `file:line`.
5
+ */
6
+ import type { CDPConnection } from '../../connection/cdp.js';
7
+ import type { CssSearchResult } from '../../ipc/protocol/auditTypes.js';
8
+ import type { CssSearchCommand } from '../../ipc/protocol/commands.js';
9
+ /** Matches listed without `--limit` */
10
+ export declare const DEFAULT_CSS_SEARCH_LIMIT = 20;
11
+ /**
12
+ * Search the stylesheets for a text (case-insensitive).
13
+ *
14
+ * @param cdp - CDP connection
15
+ * @param params - Text and limit
16
+ * @returns Matches with their place
17
+ */
18
+ export declare function searchStyleSheets(cdp: CDPConnection, params: CssSearchCommand): Promise<CssSearchResult>;
19
+ /**
20
+ * Where a text occurs in a stylesheet (case-insensitive): how many times,
21
+ * and for the first `limit` matches the 0-based line and column and the
22
+ * rule around it (from the end of the previous rule to the end of this one,
23
+ * whitespace collapsed, at most {@link RULE_CONTEXT} characters each side).
24
+ * Lines are counted as the search moves on, so a big sheet is read once.
25
+ *
26
+ * @param text - Stylesheet text
27
+ * @param query - Text to find
28
+ * @param limit - Matches described at most
29
+ * @returns Match count and the described matches
30
+ */
31
+ export declare function findInSheet(text: string, query: string, limit?: number): {
32
+ total: number;
33
+ matches: Array<{
34
+ line: number;
35
+ column: number;
36
+ rule: string;
37
+ }>;
38
+ };
39
+ //# sourceMappingURL=search.d.ts.map