@orkestrel/browser 0.0.17 → 0.0.19

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.
@@ -0,0 +1,841 @@
1
+ import type { BrowserCallOptions } from '@orkestrel/browser';
2
+ import type { BrowserElementInterface } from '@orkestrel/browser';
3
+ import type { BrowserElementManagerInterface } from '@orkestrel/browser';
4
+ import type { BrowserElementQuery } from '@orkestrel/browser';
5
+ import type { BrowserElementWaitOptions } from '@orkestrel/browser';
6
+ import type { BrowserEpochFunction } from '@orkestrel/browser';
7
+ import type { BrowserOutline } from '@orkestrel/browser';
8
+ import type { BrowserOutlineOptions } from '@orkestrel/browser';
9
+ import type { BrowserReadingInput } from '@orkestrel/browser';
10
+ import type { BrowserReadingInterface } from '@orkestrel/browser';
11
+ import type { BrowserToolsetInterface } from '@orkestrel/browser';
12
+ import type { BrowserToolsetOptions } from '@orkestrel/browser';
13
+ import type { BrowserViewInterface } from '@orkestrel/browser';
14
+ import type { CDPTransportEventMap } from '@orkestrel/browser';
15
+ import type { CDPTransportInterface } from '@orkestrel/browser';
16
+ import type { EmitterErrorHandler } from '@orkestrel/emitter';
17
+ import type { EmitterHooks } from '@orkestrel/emitter';
18
+ import type { EmitterInterface } from '@orkestrel/emitter';
19
+
20
+ /**
21
+ * Names the ARIA roles whose accessible name the accessible-name computation takes from the
22
+ * element's content when no attribute or label names it.
23
+ */
24
+ export declare const BROWSER_CONTENT_NAMED_ROLES: ReadonlySet<string>;
25
+
26
+ /**
27
+ * Names the link and form targets that navigate the current browsing context or one of its
28
+ * ancestors. `_blank` opens another browsing context, and any other name targets the browsing
29
+ * context carrying that name, which `matchesBrowserPopup` resolves.
30
+ */
31
+ export declare const BROWSER_CONTEXT_TARGETS: ReadonlySet<string>;
32
+
33
+ /**
34
+ * Sets the default `wait` deadline for DOM waits in a browser document toolset, `5_000`
35
+ * milliseconds.
36
+ */
37
+ export declare const BROWSER_DOCUMENT_TIMEOUT_MS = 5000;
38
+
39
+ /**
40
+ * Maps an HTML element to the ARIA role the HTML Accessibility API Mappings specification gives
41
+ * it when it carries no `role` attribute.
42
+ *
43
+ * @remarks
44
+ * A key is a lowercase element name, or `input:` followed by the input's `type` state. An element
45
+ * whose mapping depends on more than its name — `a` and `area` without `href`, `select` with
46
+ * `multiple` or a `size` above 1, an `img` with an empty `alt`, a scoped `header` or `footer`, a
47
+ * `section` or `form` without an accessible name, and a text input with a `list` — is resolved
48
+ * by `computeBrowserRole` before this table is read. An element or input state the mapping gives
49
+ * no role has no entry.
50
+ */
51
+ export declare const BROWSER_IMPLICIT_ROLES: ReadonlyMap<string, string>;
52
+
53
+ /**
54
+ * Selects the HTML interactive content a click inside a `label` can land on without activating
55
+ * the label, as the HTML interactive-content category lists it: `a` with `href`, `audio` and
56
+ * `video` with `controls`, `button`, `details`, `embed`, `iframe`, `img` with `usemap` or
57
+ * `controls`, `input` other than `hidden`, `label`, `select`, and `textarea`.
58
+ */
59
+ export declare const BROWSER_INTERACTIVE_CONTENT = "a[href], audio[controls], button, details, embed, iframe, img[usemap], img[controls], input:not([type=\"hidden\" i]), label, select, textarea, video[controls]";
60
+
61
+ /** Names the `input` type states whose value an untrusted `fill` sets as typed text. */
62
+ export declare const BROWSER_TYPED_INPUTS: ReadonlySet<string>;
63
+
64
+ /**
65
+ * Configures a toolset that drives one browser document.
66
+ *
67
+ * @remarks
68
+ * - `document` and `own` — the driven document and the admission of the realm's own document, as
69
+ * {@link BrowserDOMViewOptions} describes them
70
+ * - `source` — a source of page tools, such as `@orkestrel/mcp`'s model context bridge; the
71
+ * toolset adopts its tools and re-adopts on its `change`. Default: no page tools
72
+ * - `tools`, `limit`, `journeys`, `on`, and `error` — as {@link BrowserToolsetOptions}
73
+ * describes them
74
+ */
75
+ export declare interface BrowserDocumentToolsetOptions extends BrowserDOMViewOptions, Pick<BrowserToolsetOptions, 'on' | 'error' | 'tools' | 'source' | 'limit' | 'journeys'> {
76
+ }
77
+
78
+ /**
79
+ * Drives a referenced element of a DOM document without trusted input.
80
+ *
81
+ * @remarks
82
+ * `click` runs `HTMLElement.click()`; `fill` and `select` set the control through its native
83
+ * prototype setter and dispatch `input` and `change`, and `fill` refuses `UNKNOWN` an element
84
+ * that is not a text control and a read-only one; `submit` runs `form.requestSubmit()` and
85
+ * observes the outcome through a `submit` listener registered across the call. Each action
86
+ * refuses with a `BrowserElementError` naming the reason: `DISABLED` for a disabled control,
87
+ * `HIDDEN` for an element that does not render, and `UNTRUSTED` for what an untrusted event
88
+ * cannot do, which is a click or submission that opens another browsing context, a click that
89
+ * opens a file chooser, and typing into a contenteditable element. A click that activates a
90
+ * `label`, on the label itself or on a descendant that `matchesBrowserActivation` admits, is
91
+ * judged by the label's control as well: a disabled control refuses `DISABLED`, and a file input
92
+ * refuses `UNTRUSTED` as a direct click on it does. A click on an interactive descendant of a
93
+ * label keeps only its own checks. `role` and `name` read the description the latest outline or
94
+ * query that encountered the element captured, so a change to the element shows after the next
95
+ * capture, and a dropped reference keeps its last capture. Every action on an element removed
96
+ * from its document, collected, or held across a navigation reports `GONE`.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * const view = createBrowserDOMView({ document: frame.contentDocument })
101
+ * await view.elements.outline()
102
+ * await view.elements.element('e1')?.click()
103
+ * ```
104
+ */
105
+ export declare class BrowserDOMElement implements BrowserDOMElementInterface {
106
+ #private;
107
+ constructor(input: BrowserDOMElementInput);
108
+ get reference(): string;
109
+ get role(): string;
110
+ get name(): string;
111
+ click(options?: BrowserCallOptions): Promise<void>;
112
+ fill(value: string, options?: BrowserCallOptions): Promise<void>;
113
+ select(values: readonly string[], options?: BrowserCallOptions): Promise<void>;
114
+ focus(options?: BrowserCallOptions): Promise<void>;
115
+ read(options?: BrowserCallOptions): Promise<BrowserReadingInterface>;
116
+ submit(options?: BrowserCallOptions): Promise<void>;
117
+ }
118
+
119
+ /**
120
+ * Binds a DOM element to its reference and the manager that minted it.
121
+ *
122
+ * @remarks
123
+ * - `reference` — the reference the manager minted for the element
124
+ * - `description` — returns the role and accessible name the latest capture that encountered
125
+ * the element recorded; after the manager drops the reference it keeps returning that capture
126
+ * - `node` — a weak reference to the element the reference names, so a removed element can be
127
+ * collected; an element that no longer dereferences reports `GONE`
128
+ * - `current` — true while the manager still holds the reference; false otherwise
129
+ * - `navigation` — reads the epoch of the element's own document, which every reading records;
130
+ * it advances when that document or the view's document navigates
131
+ */
132
+ export declare interface BrowserDOMElementInput {
133
+ readonly reference: string;
134
+ readonly description: () => Pick<BrowserElementInterface, 'role' | 'name'>;
135
+ readonly node: WeakRef<Element>;
136
+ readonly current: () => boolean;
137
+ readonly navigation: BrowserEpochFunction;
138
+ }
139
+
140
+ /**
141
+ * Provides DOM actions through a stable element reference, without trusted input.
142
+ *
143
+ * @remarks
144
+ * No action grants user activation, and every event an action dispatches itself carries
145
+ * `isTrusted` `false`. `submit` submits the element's form through `requestSubmit()`, passing the
146
+ * element as the submitter when it is a submit button; the `submit` event that call fires is
147
+ * generated by the browser and carries `isTrusted` `true`.
148
+ */
149
+ export declare interface BrowserDOMElementInterface extends BrowserElementInterface {
150
+ }
151
+
152
+ /**
153
+ * Outlines a DOM document from its elements and binds stable references to the interactive ones.
154
+ *
155
+ * @remarks
156
+ * Rows come in document order from a `TreeWalker` over the flat tree: an open shadow root
157
+ * contributes its rows in place of its host's children, a `slot` its assigned nodes, and a
158
+ * same-origin `iframe` its document's rows, while a cross-origin one renders
159
+ * `iframe "NAME" (cross-origin, not readable)`. An element that `matchesBrowserHidden` reports is
160
+ * omitted with its subtree, a scope root in such a subtree yields no row, and an element that
161
+ * `matchesBrowserInvisible` reports yields no row of its own. An element whose role
162
+ * `BROWSER_INTERACTIVE_ROLES` names receives a reference bound through a `WeakRef`, which never
163
+ * changes while the manager holds it, and a reference number is never reused. Every outline or
164
+ * query that encounters a bound element records its role and name afresh, and the element's
165
+ * wrapper reports that latest capture, also after the manager drops the reference. A reference
166
+ * and a reading from any walked document record that document's epoch, which advances on its own
167
+ * navigation events and on the view's; that document's `pagehide` drops its references. A form
168
+ * carrying a `toolname` attribute renders `[tool=NAME]` after its role and name. A `select` row
169
+ * is followed by one `option` row per option, named by its label. Whitespace between two texts of
170
+ * one block renders as one space, as a rendered `br` between them does, and texts with neither
171
+ * between them stay joined. A CSS query
172
+ * searches the document the view drives, not its child documents or shadow trees. After the
173
+ * input's `signal` aborts, `outline`, `find`, and `wait` reject with its reason.
174
+ *
175
+ * `wait` parks a `BrowserDOMWait` bound to the view's lifetime over every root that
176
+ * `collectBrowserRoots` reaches from its scope, reconciled at every observed mutation and frame
177
+ * `load`. A shadow root attached after the wait began is a declared limit: the wait discovers it
178
+ * at the next observed mutation or `load`, so a match inserted there with no other observed
179
+ * change is not seen before the deadline.
180
+ *
181
+ * @example
182
+ * ```ts
183
+ * const view = createBrowserDOMView({ document: frame.contentDocument })
184
+ * const outline = await view.elements.outline()
185
+ * const [save] = await view.elements.find({ role: 'button', name: 'save' })
186
+ * ```
187
+ */
188
+ export declare class BrowserDOMElementManager implements BrowserElementManagerInterface<BrowserDOMElementInterface> {
189
+ #private;
190
+ constructor(input: BrowserDOMElementManagerInput);
191
+ outline(options?: BrowserOutlineOptions): Promise<BrowserOutline>;
192
+ find(query: BrowserElementQuery, options?: BrowserCallOptions): Promise<readonly BrowserDOMElementInterface[]>;
193
+ wait(query: BrowserElementQuery, options?: BrowserElementWaitOptions): Promise<readonly BrowserDOMElementInterface[]>;
194
+ element(reference: string): BrowserDOMElementInterface | undefined;
195
+ elements(): readonly BrowserDOMElementInterface[];
196
+ clear(): void;
197
+ }
198
+
199
+ /**
200
+ * Binds a DOM element manager to the view that owns it.
201
+ *
202
+ * @remarks
203
+ * - `document` — returns the document the view drives at the moment of the call
204
+ * - `navigation` — reads the view's navigation epoch, which every reading records
205
+ * - `signal` — the view's lifetime; it aborts when the view is destroyed, every wait and
206
+ * navigation listener the manager starts ends with it, and after it aborts `outline`, `find`,
207
+ * and `wait` reject with its reason
208
+ */
209
+ export declare interface BrowserDOMElementManagerInput {
210
+ readonly document: () => Document;
211
+ readonly navigation: BrowserEpochFunction;
212
+ readonly signal: AbortSignal;
213
+ }
214
+
215
+ /**
216
+ * Reads and drives a DOM document from a realm that can reach it, without trusted input.
217
+ *
218
+ * @remarks
219
+ * The view follows the window of the document it was given, so after that window navigates it
220
+ * drives the window's next document. A reading records the view's navigation epoch, and reports
221
+ * stale after the epoch advances. The epoch advances on the Navigation API's `navigatesuccess`
222
+ * where the window has that API, on `popstate` and `hashchange` where it does not, on `pagehide`,
223
+ * and when the window's document changes. A `pushState` in a window without the Navigation API
224
+ * fires none of those events, so a reading there stays current across it. A cross-document
225
+ * navigation also clears every element reference. `destroy()` releases the listeners and every
226
+ * reference, and fails every pending wait with a `BrowserError` coded
227
+ * `BROWSER_DOCUMENT_DESTROYED`; after it, `title()`, `read()`, `wait()`, and the element manager's
228
+ * `outline()`, `find()`, and `wait()` reject with that error, and a second `destroy()` does
229
+ * nothing more. `trusted` is `false`: no action grants user activation, and
230
+ * every event the view's actions dispatch themselves carries `isTrusted` `false`. The `submit`
231
+ * event that `requestSubmit()` fires during a `submit` is generated by the browser and carries
232
+ * `isTrusted` `true`.
233
+ *
234
+ * @example
235
+ * ```ts
236
+ * const view = createBrowserDOMView({ document: frame.contentDocument })
237
+ * const reading = await view.read()
238
+ * reading.text().text
239
+ * ```
240
+ */
241
+ export declare class BrowserDOMView implements BrowserDOMViewInterface {
242
+ #private;
243
+ constructor(options: BrowserDOMViewOptions);
244
+ get url(): string;
245
+ get trusted(): boolean;
246
+ get elements(): BrowserElementManagerInterface<BrowserDOMElementInterface>;
247
+ title(options?: BrowserCallOptions): Promise<string>;
248
+ read(options?: BrowserCallOptions): Promise<BrowserReadingInterface>;
249
+ wait(text: string, options?: BrowserCallOptions): Promise<void>;
250
+ destroy(): void;
251
+ }
252
+
253
+ /** Provides the document operations of a view that drives a DOM document in its own realm. */
254
+ export declare interface BrowserDOMViewInterface extends BrowserViewInterface {
255
+ readonly elements: BrowserElementManagerInterface<BrowserDOMElementInterface>;
256
+ /** Releases the navigation listeners and every element reference. */
257
+ destroy(): void;
258
+ }
259
+
260
+ /**
261
+ * Configures a view that drives one browser document.
262
+ *
263
+ * @remarks
264
+ * - `document` — the document the view reads and acts on; the view follows its window, so a
265
+ * navigation of that window moves the view to the window's next document
266
+ * - `own` — if `true`, admits the realm's own `globalThis.document`; if `false`, refuses it,
267
+ * because an action that navigates the realm's own document cannot return. Default: `false`
268
+ */
269
+ export declare interface BrowserDOMViewOptions {
270
+ readonly document: Document;
271
+ readonly own?: boolean;
272
+ }
273
+
274
+ /**
275
+ * Parks one condition on DOM mutations until it holds, with one deadline and no other timer.
276
+ *
277
+ * @remarks
278
+ * The wait observes every root `roots` returns, each through a `MutationObserver` of that root's
279
+ * realm, and re-reads the roots after every mutation batch and every capture-phase `load` in an
280
+ * observed root: a same-origin frame or an open shadow root that appears joins the observation,
281
+ * and a root that departed (a replaced frame document, a removed shadow root) leaves it, with its
282
+ * observer disconnected and its `load` listener removed. The check runs before the wait parks and
283
+ * again after every subscription, and no check runs once the deadline, counted from `start`, has
284
+ * passed, which the wait reads again after `roots` returns. The wait settles one time: on the
285
+ * check's first value, on the signal's abort with its reason, at the deadline with
286
+ * `BROWSER_WAIT_TIMEOUT`, on a `pagehide` in the first root's window with `GONE`, or with whatever
287
+ * the check or the roots function throws. A signal that aborts while `check` or `roots` runs
288
+ * settles the wait with its reason, and wins over a value that same check returns. Settlement
289
+ * disconnects every observer and removes every listener synchronously, so a mutation queued
290
+ * before it runs no check, and a `roots` or `check` that settles the wait from inside leaves no
291
+ * observer, listener, or further check behind.
292
+ *
293
+ * A shadow root attached after the wait began is a declared limit: attaching one fires no
294
+ * mutation record and no event, so the wait discovers it at the next mutation or `load` it
295
+ * observes, and a match inserted into it with no other observed change is not seen before the
296
+ * deadline. The wait never polls to close that gap.
297
+ *
298
+ * @example
299
+ * ```ts
300
+ * const ready = await new BrowserDOMWait({
301
+ * roots: () => [document],
302
+ * check: () => document.querySelector('#ready') ?? undefined,
303
+ * timeout: 1_000,
304
+ * start: performance.now(),
305
+ * subject: 'Ready wait',
306
+ * }).execute()
307
+ * ```
308
+ */
309
+ export declare class BrowserDOMWait<T> implements BrowserDOMWaitInterface<T> {
310
+ #private;
311
+ constructor(wait: BrowserMutationWait<T>);
312
+ get roots(): readonly Node[];
313
+ execute(): Promise<T>;
314
+ }
315
+
316
+ /** Settles one wait parked on DOM mutations. */
317
+ export declare interface BrowserDOMWaitInterface<T> {
318
+ /** The roots the wait observes at this moment; empty before it parks and after it settles. */
319
+ readonly roots: readonly Node[];
320
+ /**
321
+ * Resolves the first value the check returns other than `undefined`, then releases every
322
+ * observer, the deadline timer, and every listener.
323
+ */
324
+ execute(): Promise<T>;
325
+ }
326
+
327
+ /**
328
+ * Describes one wait parked on DOM mutations.
329
+ *
330
+ * @remarks
331
+ * - `roots` — returns the documents and shadow roots whose mutations re-run the check; the wait
332
+ * re-reads it after every mutation batch and every `load` in an observed root, observing the
333
+ * roots that appeared and releasing the ones that departed, and a `pagehide` in the first
334
+ * root's window fails the wait
335
+ * - `check` — returns the value the wait settles on, or `undefined` to keep waiting
336
+ * - `timeout` — ms from `start` before the wait fails
337
+ * - `start` — the `now()` reading the deadline counts from, taken when the calling method was
338
+ * entered
339
+ * - `now` — reads the clock every remaining-budget calculation uses, the deadline timer's delay
340
+ * included; it shares its time origin with `start`. Default: `performance.now()`
341
+ * - `signal` — aborts the wait with the signal's reason
342
+ * - `subject` — names the wait in its timeout message
343
+ */
344
+ export declare interface BrowserMutationWait<T> {
345
+ readonly roots: () => readonly Node[];
346
+ readonly check: () => T | undefined;
347
+ readonly timeout: number;
348
+ readonly start: number;
349
+ readonly now?: () => number;
350
+ readonly signal?: AbortSignal | undefined;
351
+ readonly subject: string;
352
+ }
353
+
354
+ /**
355
+ * Carries the accessible-name traversal context.
356
+ *
357
+ * @remarks
358
+ * - `hidden` — if `true`, admits hidden and invisible content, as the hidden-reference exception
359
+ * does for a hidden element that `aria-labelledby` references; if `false`, omits it.
360
+ * Default: `false`
361
+ * - `target` — the element whose name is computed; an embedded control that is the target
362
+ * contributes nothing, and any other embedded control contributes its value
363
+ */
364
+ export declare interface BrowserNameContext {
365
+ readonly hidden?: boolean;
366
+ readonly target?: Element;
367
+ }
368
+
369
+ /**
370
+ * Collects the tree roots a wait observes under a node: the node's own root, then every open
371
+ * shadow root and every same-origin frame document at or beneath it, recursively.
372
+ *
373
+ * @param root - The document, shadow root, or element to collect under
374
+ * @returns The roots, the node's own root first; a cross-origin frame contributes none
375
+ *
376
+ * @example
377
+ * ```ts
378
+ * collectBrowserRoots(document) // [document, ...each open shadow root and frame document]
379
+ * ```
380
+ */
381
+ export declare function collectBrowserRoots(root: Document | ShadowRoot | Element): readonly Node[];
382
+
383
+ /**
384
+ * Computes the text one node contributes to an accessible name: its own text alternative, or its
385
+ * content.
386
+ *
387
+ * @remarks
388
+ * A text node contributes its data unless its parent is invisible; a parent without a box of its
389
+ * own, such as a `slot` or a `display: contents` element, is not invisible. An element
390
+ * contributes nothing when it is hidden or is a `script` or `style`, and an element that
391
+ * `matchesBrowserInvisible` reports contributes only what its content contributes, never its
392
+ * value, `aria-label`, `alt`, or `title`. The context's `hidden` admits both. An embedded control
393
+ * that is not the context's `target` contributes its value: a text field or a range its `value`,
394
+ * a `select` its selected options' labels; a password field and the target itself contribute
395
+ * nothing. Any other element contributes its `aria-label`, the `alt` of an image, or its content
396
+ * through `readBrowserContent`, and its `title` when those are empty.
397
+ *
398
+ * @param node - The node whose contribution is computed
399
+ * @param context - The traversal context. Default: no hidden content and no target
400
+ * @returns The untrimmed contribution
401
+ *
402
+ * @example
403
+ * ```ts
404
+ * const image = document.createElement('img')
405
+ * image.alt = 'Save'
406
+ * computeBrowserAlternative(image) // 'Save'
407
+ * ```
408
+ */
409
+ export declare function computeBrowserAlternative(node: Node, context?: BrowserNameContext): string;
410
+
411
+ /**
412
+ * Computes the accessible name of an element, trimmed and whitespace-collapsed.
413
+ *
414
+ * @remarks
415
+ * The steps follow the accessible-name computation, first match wins: the elements
416
+ * that `aria-labelledby` references in the element's own tree, each through
417
+ * `computeBrowserAlternative` with hidden content admitted when the referenced element is itself
418
+ * hidden (`matchesBrowserOmitted` or `matchesBrowserInvisible`), `aria-label`, the `label` of an
419
+ * `option`, the value of an `input` button, the `alt` of an
420
+ * image, the text of every associated `label`, the element's own content for a role in
421
+ * `BROWSER_CONTENT_NAMED_ROLES`, then the `title` attribute, then the `placeholder` of a text
422
+ * control. Every traversal carries the element as its `target`, so an embedded control
423
+ * contributes its value unless it is the element being named. The `title` step follows content because a tooltip names an element only when nothing
424
+ * else does.
425
+ *
426
+ * @param element - The element to name
427
+ * @param role - The element's role. Default: `computeBrowserRole(element)`
428
+ * @returns The name, or the empty string when no step names the element
429
+ *
430
+ * @example
431
+ * ```ts
432
+ * const button = document.createElement('button')
433
+ * button.textContent = ' Save draft '
434
+ * computeBrowserName(button) // 'Save draft'
435
+ * ```
436
+ */
437
+ export declare function computeBrowserName(element: Element, role?: string | undefined): string;
438
+
439
+ /**
440
+ * Computes the ARIA role of an element from its `role` attribute or its implicit mapping.
441
+ *
442
+ * @remarks
443
+ * The explicit role is the first token of the `role` attribute, with `presentation` folded into
444
+ * its synonym `none`. Without one, the role follows the HTML Accessibility API Mappings
445
+ * specification through `BROWSER_IMPLICIT_ROLES`, after the element-specific conditions that
446
+ * table cannot express: a link needs `href`, a `select` with `multiple` or a `size` above 1 is a
447
+ * `listbox`, an `img` with an empty `alt` is `none`, a `header` or `footer` inside sectioning
448
+ * content has no landmark role, a `section` or `form` needs an accessible name, a text input with
449
+ * a `list` is a `combobox`, and a `th` with `scope="row"` is a `rowheader`.
450
+ *
451
+ * @param element - The element to classify
452
+ * @returns The role, or `undefined` when the element maps to no role
453
+ *
454
+ * @example
455
+ * ```ts
456
+ * const input = document.createElement('input')
457
+ * input.type = 'checkbox'
458
+ * computeBrowserRole(input) // 'checkbox'
459
+ * ```
460
+ */
461
+ export declare function computeBrowserRole(element: Element): string | undefined;
462
+
463
+ /**
464
+ * Computes the text an element's content contributes to an accessible name, in the flat tree,
465
+ * trimmed and whitespace-collapsed.
466
+ *
467
+ * @remarks
468
+ * The text is what `readBrowserContent` reads, normalized.
469
+ *
470
+ * @param root - The element or shadow root whose content is read
471
+ * @param context - The traversal context. Default: no hidden content and no target
472
+ * @returns The trimmed, whitespace-collapsed text
473
+ *
474
+ * @example
475
+ * ```ts
476
+ * const link = document.createElement('a')
477
+ * link.innerHTML = '<div>Cars</div><div>Search the fleet</div>'
478
+ * document.body.append(link)
479
+ * computeBrowserText(link) // 'Cars Search the fleet'
480
+ * ```
481
+ */
482
+ export declare function computeBrowserText(root: Element | ShadowRoot, context?: BrowserNameContext): string;
483
+
484
+ /**
485
+ * Creates a view that reads and drives a DOM document without trusted input.
486
+ *
487
+ * @param options - The driven document, and `own` to admit the realm's own document
488
+ * @returns A {@link BrowserDOMViewInterface} over the document's window
489
+ * @throws Thrown when `document` is not a document attached to a window, with the code
490
+ * `BROWSER_DOCUMENT`, and when it is `globalThis.document` without `own: true`, with the code
491
+ * `BROWSER_DOCUMENT_OWN`.
492
+ *
493
+ * @example
494
+ * ```ts
495
+ * const frame = document.createElement('iframe')
496
+ * document.body.append(frame)
497
+ * const view = createBrowserDOMView({ document: frame.contentDocument })
498
+ * await view.elements.outline() // { text: 'page "" about:blank\n(0 of 0 elements)', … }
499
+ * ```
500
+ */
501
+ export declare function createBrowserDOMView(options: BrowserDOMViewOptions): BrowserDOMViewInterface;
502
+
503
+ /**
504
+ * Creates a `BrowserToolsetInterface` that publishes the five view tools over a DOM document and
505
+ * adopts a source's page tools beside them.
506
+ *
507
+ * @remarks
508
+ * The toolset runs over a view {@link createBrowserDOMView} creates for `document`, so it
509
+ * advertises `look`, `read`, `click`, `type`, and `wait`, and a click or type receipt ends with
510
+ * ` (untrusted event)`. `source` supplies page tools, which the toolset adopts during `start()`
511
+ * and again on every `change`; `toolset.native` never includes them, so publishing it to a
512
+ * registry leaves that registry's own tools alone. The view belongs to the toolset: `destroy()`
513
+ * removes the toolset's tools, then destroys the view, which releases its listeners and fails
514
+ * its pending waits, and a construction that throws destroys the view before it rethrows.
515
+ * `journeys` adds `record`, `save`, `journeys`, `edit`, and `replay` at construction; a replay
516
+ * runs the steps the document placement executes.
517
+ *
518
+ * @param options - The driven document, `own`, the page-tool source, the manager, the bound, the
519
+ * journey stores, and the emitter hooks
520
+ * @returns A {@link BrowserToolsetInterface} whose `view` drives the document
521
+ * @throws Thrown when `document` is not a document attached to a window, with the code
522
+ * `BROWSER_DOCUMENT`, when it is `globalThis.document` without `own: true`, with the code
523
+ * `BROWSER_DOCUMENT_OWN`, and when `limit` is not a positive integer.
524
+ *
525
+ * @example
526
+ * ```ts
527
+ * const toolset = createDocumentToolset({ document: frame.contentDocument, source: bridge })
528
+ * await toolset.start()
529
+ * await toolset.tools.execute({ id: '1', name: 'look', arguments: { what: 'form' } })
530
+ * ```
531
+ */
532
+ export declare function createDocumentToolset(options: BrowserDocumentToolsetOptions): BrowserToolsetInterface;
533
+
534
+ /**
535
+ * Creates a CDP transport over the browser's native `WebSocket`.
536
+ *
537
+ * @param options - The CDP WebSocket debugger URL, the opening deadline, and emitter hooks
538
+ * @returns A {@link CDPTransportInterface} a `CDPClient` sends and receives frames over
539
+ *
540
+ * @example
541
+ * ```ts
542
+ * const client = createCDPClient({
543
+ * transport: createSocketCDPTransport({ url: 'ws://127.0.0.1:9222/devtools/browser/abc' }),
544
+ * })
545
+ * await client.connect()
546
+ * ```
547
+ */
548
+ export declare function createSocketCDPTransport(options: SocketCDPTransportOptions): CDPTransportInterface;
549
+
550
+ /**
551
+ * Narrows a value to a `Document` attached to a window.
552
+ *
553
+ * @param value - The value to test
554
+ * @returns `true` for an object that is a `Document` with a `defaultView`, otherwise `false`
555
+ */
556
+ export declare function isBrowserDocument(value: unknown): value is Document;
557
+
558
+ /**
559
+ * Subscribes one listener to a window's navigation events until a signal aborts.
560
+ *
561
+ * @remarks
562
+ * The listener receives the Navigation API's `navigatesuccess` where the window has that API, and
563
+ * `popstate` and `hashchange` where it does not, plus `pagehide` in both cases. A `pushState` in a
564
+ * window without the Navigation API fires none of those events.
565
+ *
566
+ * @param window - The window whose navigation events are observed
567
+ * @param listener - Receives each event; `event.type` tells an unload from a same-document
568
+ * navigation
569
+ * @param signal - Removes every subscription when it aborts
570
+ *
571
+ * @example
572
+ * ```ts
573
+ * const release = new AbortController()
574
+ * listenBrowserNavigation(frame.contentWindow, (event) => console.log(event.type), release.signal)
575
+ * ```
576
+ */
577
+ export declare function listenBrowserNavigation(window: Window, listener: (event: Event) => void, signal: AbortSignal): void;
578
+
579
+ /**
580
+ * Checks whether a click on an element activates the `label` that contains it, following the
581
+ * HTML label activation rule.
582
+ *
583
+ * @remarks
584
+ * The click activates the label when the target is the label itself, or when no element on the
585
+ * path from the target up to the label, the target included, matches
586
+ * `BROWSER_INTERACTIVE_CONTENT`.
587
+ *
588
+ * @param target - The element the click lands on
589
+ * @param label - The label that contains the target, or the target itself
590
+ * @returns True if the click activates the label; false otherwise
591
+ *
592
+ * @example
593
+ * ```ts
594
+ * const label = document.createElement('label')
595
+ * label.innerHTML = '<a href="#help">Help</a> <span>Photo</span>'
596
+ * matchesBrowserActivation(label.querySelector('a'), label) // false
597
+ * matchesBrowserActivation(label.querySelector('span'), label) // true
598
+ * ```
599
+ */
600
+ export declare function matchesBrowserActivation(target: Element, label: Element): boolean;
601
+
602
+ /**
603
+ * Checks whether an element starts a block of its own, the unit that separates runs of text.
604
+ *
605
+ * @param element - The element to test
606
+ * @returns True if the element is a `br`, or its computed `display` is neither inline-level,
607
+ * `contents`, nor `none`; false otherwise
608
+ *
609
+ * @example
610
+ * ```ts
611
+ * const paragraph = document.createElement('p')
612
+ * document.body.append(paragraph)
613
+ * matchesBrowserBlock(paragraph) // true
614
+ * ```
615
+ */
616
+ export declare function matchesBrowserBlock(element: Element): boolean;
617
+
618
+ /**
619
+ * Checks whether an element and its subtree are hidden from the rendered page.
620
+ *
621
+ * @param element - The element to test
622
+ * @returns True if the element carries `hidden` or `aria-hidden="true"`, or its computed
623
+ * `display` is `none`; false otherwise
624
+ *
625
+ * @example
626
+ * ```ts
627
+ * const note = document.createElement('p')
628
+ * note.hidden = true
629
+ * matchesBrowserHidden(note) // true
630
+ * ```
631
+ */
632
+ export declare function matchesBrowserHidden(element: Element): boolean;
633
+
634
+ /**
635
+ * Checks whether an element renders nothing visible of its own.
636
+ *
637
+ * @remarks
638
+ * An element whose computed `visibility` is `hidden` or `collapse` is invisible. An element with
639
+ * `display: contents` has no box of its own but renders its descendants, so it is not invisible.
640
+ * Any other element is invisible when `checkVisibility` with `visibilityProperty` and
641
+ * `contentVisibilityAuto` reports it, which covers an element without a box and one skipped by
642
+ * `content-visibility: auto`. A descendant can still be visible, so the rule omits the element's
643
+ * own row and text and keeps its subtree. An `option` or `optgroup` inside a `select` is
644
+ * invisible where the `select` is, because a drop-down renders its options outside the page's
645
+ * boxes. Zero-size and off-screen elements stay visible. An
646
+ * element in a document without a window is never invisible, because nothing renders it.
647
+ *
648
+ * @param element - The element to test
649
+ * @returns True if the element renders nothing visible of its own; false otherwise
650
+ *
651
+ * @example
652
+ * ```ts
653
+ * const button = document.createElement('button')
654
+ * button.style.visibility = 'hidden'
655
+ * document.body.append(button)
656
+ * matchesBrowserInvisible(button) // true
657
+ * ```
658
+ */
659
+ export declare function matchesBrowserInvisible(element: Element): boolean;
660
+
661
+ /**
662
+ * Checks whether an element sits in an omitted subtree: the element or a flat-tree ancestor that
663
+ * `readBrowserParent` reaches matches `matchesBrowserHidden`, through assigned slots, shadow
664
+ * hosts, and the frame elements of same-origin documents.
665
+ *
666
+ * @param element - The element to test
667
+ * @returns True if the element or an ancestor is hidden; false otherwise
668
+ *
669
+ * @example
670
+ * ```ts
671
+ * const section = document.createElement('section')
672
+ * section.hidden = true
673
+ * const button = section.appendChild(document.createElement('button'))
674
+ * matchesBrowserOmitted(button) // true
675
+ * ```
676
+ */
677
+ export declare function matchesBrowserOmitted(element: Element): boolean;
678
+
679
+ /**
680
+ * Checks whether activating an element opens another browsing context.
681
+ *
682
+ * @remarks
683
+ * A link with `href` navigates its `target`, and a form, or a submit button inside one, navigates
684
+ * the submitter's `formtarget` or the form's `target`; either falls back to the target of the
685
+ * document's `base` element. `_blank` opens another context, and a target in
686
+ * `BROWSER_CONTEXT_TARGETS` does not. A name reuses the browsing context carrying it when the
687
+ * element's window, an ancestor window, or a frame element in one of their documents carries it,
688
+ * and opens another context otherwise; an ancestor this realm cannot read is skipped.
689
+ *
690
+ * @param element - The element an untrusted activation would target
691
+ * @returns True if the activation opens another browsing context; false otherwise, including
692
+ * for an element whose activation navigates nothing
693
+ *
694
+ * @example
695
+ * ```ts
696
+ * const link = document.createElement('a')
697
+ * link.href = '/cars'
698
+ * link.target = '_blank'
699
+ * matchesBrowserPopup(link) // true
700
+ * ```
701
+ */
702
+ export declare function matchesBrowserPopup(element: Element): boolean;
703
+
704
+ /**
705
+ * Reads the nearest block container of an element, the unit that separates runs of text.
706
+ *
707
+ * @param element - The element to start from, or `null` for a node without a parent element
708
+ * @param root - The node that bounds the search
709
+ * @returns The nearest inclusive ancestor, below `root`, that `matchesBrowserBlock` reports;
710
+ * `root` when none is
711
+ *
712
+ * @example
713
+ * ```ts
714
+ * const strong = document.createElement('strong')
715
+ * const paragraph = document.createElement('p')
716
+ * paragraph.append(strong)
717
+ * document.body.append(paragraph)
718
+ * readBrowserBlock(strong, document.body) // paragraph
719
+ * ```
720
+ */
721
+ export declare function readBrowserBlock(element: Element | null, root: Node): Node;
722
+
723
+ /**
724
+ * Reads the URL, title, and serialized markup a DOM reading is built from, refusing a capture
725
+ * over the result limit before any parse.
726
+ *
727
+ * @remarks
728
+ * The measure is the length of `JSON.stringify({ url, title, html })`, the form the CDP capture
729
+ * guard compares with `BROWSER_RESULT_LIMIT`, so a character JSON escapes counts as its escape
730
+ * sequence. A reading a caller builds with `createBrowserReading` passes through no limit.
731
+ *
732
+ * @param node - The element whose `outerHTML` is captured; its owner document supplies `URL`
733
+ * and `title`
734
+ * @returns The capture's `url`, `title`, and `html`
735
+ * @throws Thrown as a `BrowserResultLimitError` when the serialized capture is longer than
736
+ * `BROWSER_RESULT_LIMIT` characters, with `length` and `limit` in its context.
737
+ */
738
+ export declare function readBrowserCapture(node: Element): BrowserReadingInput;
739
+
740
+ /**
741
+ * Reads the untrimmed text an element's content contributes to an accessible name, in the flat
742
+ * tree.
743
+ *
744
+ * @remarks
745
+ * The content is the open shadow root's children for a shadow host, the flattened assigned nodes
746
+ * for a `slot`, and the child nodes otherwise. Each child contributes what
747
+ * `computeBrowserAlternative` returns for it, and a child that `matchesBrowserBlock` reports is
748
+ * set apart from its neighbours by a space. Whitespace at the edges of an inline child is kept,
749
+ * so `<b>Go </b>home` reads `Go home`.
750
+ *
751
+ * @param root - The element or shadow root whose content is read
752
+ * @param context - The traversal context. Default: no hidden content and no target
753
+ * @returns The untrimmed text
754
+ *
755
+ * @example
756
+ * ```ts
757
+ * const label = document.createElement('span')
758
+ * label.innerHTML = '<b>Go </b>home'
759
+ * document.body.append(label)
760
+ * readBrowserContent(label) // 'Go home'
761
+ * ```
762
+ */
763
+ export declare function readBrowserContent(root: Element | ShadowRoot, context?: BrowserNameContext): string;
764
+
765
+ /**
766
+ * Reads an element's parent in the flat tree: the slot it is assigned to in an open shadow root,
767
+ * its parent element, the host of the open shadow root it sits at the top of, or the frame
768
+ * element of its same-origin document.
769
+ *
770
+ * @param element - The element whose parent is read
771
+ * @returns The parent, or `null` at the top of a top-level or cross-origin-framed document
772
+ *
773
+ * @example
774
+ * ```ts
775
+ * readBrowserParent(document.body) // document.documentElement
776
+ * readBrowserParent(document.documentElement) // null in a top-level document
777
+ * ```
778
+ */
779
+ export declare function readBrowserParent(element: Element): Element | null;
780
+
781
+ /**
782
+ * Moves a tree walker past the subtree of its current node.
783
+ *
784
+ * @param walker - The walker to move; its root bounds the move
785
+ * @returns The first node after the subtree in document order, or `null` when the walk is done
786
+ *
787
+ * @example
788
+ * ```ts
789
+ * const walker = document.createTreeWalker(document.body)
790
+ * walker.nextNode()
791
+ * skipBrowserSubtree(walker) // the first node after the body's first child and its descendants
792
+ * ```
793
+ */
794
+ export declare function skipBrowserSubtree(walker: TreeWalker): Node | null;
795
+
796
+ /**
797
+ * Provides a raw CDP text transport over the browser's native `WebSocket`.
798
+ *
799
+ * @remarks
800
+ * `start()` resolves on the socket's `open` event and rejects with a `BrowserConnectionError`
801
+ * carrying `url` for a URL whose scheme is not `ws:` or `wss:`, for a URL the `WebSocket`
802
+ * constructor refuses (one with a fragment), for a socket that fails or closes before it opens,
803
+ * and at the `timeout` deadline. Concurrent and repeated `start()` and `close()`
804
+ * calls share their active transition, and a later `start()` opens a fresh socket after the
805
+ * prior one closes. A close the remote end initiates emits `close`. The driven Chromium must
806
+ * allow the caller's origin through `--remote-allow-origins`.
807
+ *
808
+ * @example
809
+ * ```ts
810
+ * const transport = new SocketCDPTransport({ url: 'ws://127.0.0.1:9222/devtools/browser/abc' })
811
+ * await transport.start()
812
+ * await transport.close()
813
+ * ```
814
+ */
815
+ export declare class SocketCDPTransport implements CDPTransportInterface {
816
+ #private;
817
+ constructor(options: SocketCDPTransportOptions);
818
+ get emitter(): EmitterInterface<CDPTransportEventMap>;
819
+ start(): Promise<void>;
820
+ send(data: string): Promise<void>;
821
+ close(): Promise<void>;
822
+ }
823
+
824
+ /**
825
+ * Configures a CDP transport over the browser's `WebSocket`.
826
+ *
827
+ * @remarks
828
+ * - `url` — the CDP WebSocket debugger URL, with a `ws:` or `wss:` scheme
829
+ * - `timeout` — ms before an opening handshake fails. Default: `BROWSER_DEFAULT_TIMEOUT_MS`
830
+ *
831
+ * The driven Chromium must be started with `--remote-allow-origins` naming the caller's origin;
832
+ * otherwise it refuses the handshake and `start` rejects.
833
+ */
834
+ export declare interface SocketCDPTransportOptions {
835
+ readonly on?: EmitterHooks<CDPTransportEventMap>;
836
+ readonly error?: EmitterErrorHandler;
837
+ readonly url: string;
838
+ readonly timeout?: number;
839
+ }
840
+
841
+ export { }