@browserbasehq/orca 3.0.0-preview.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.
- package/LICENSE +21 -0
- package/README.md +165 -0
- package/dist/index.d.ts +1611 -0
- package/dist/index.js +28681 -0
- package/dist/lib/api.d.ts +23 -0
- package/dist/lib/dom/build/scriptContent.d.ts +1 -0
- package/dist/lib/inference.d.ts +71 -0
- package/dist/lib/inferenceLogUtils.d.ts +12 -0
- package/dist/lib/logger.d.ts +54 -0
- package/dist/lib/prompt.d.ts +12 -0
- package/dist/lib/utils.d.ts +65 -0
- package/dist/lib/v3/agent/AgentClient.d.ts +18 -0
- package/dist/lib/v3/agent/AgentProvider.d.ts +18 -0
- package/dist/lib/v3/agent/AnthropicCUAClient.d.ts +55 -0
- package/dist/lib/v3/agent/OpenAICUAClient.d.ts +64 -0
- package/dist/lib/v3/agent/StagehandAgent.d.ts +15 -0
- package/dist/lib/v3/agent/tools/index.d.ts +229 -0
- package/dist/lib/v3/agent/tools/v3-act.d.ts +29 -0
- package/dist/lib/v3/agent/tools/v3-ariaTree.d.ts +11 -0
- package/dist/lib/v3/agent/tools/v3-close.d.ts +24 -0
- package/dist/lib/v3/agent/tools/v3-extract.d.ts +38 -0
- package/dist/lib/v3/agent/tools/v3-fillform.d.ts +37 -0
- package/dist/lib/v3/agent/tools/v3-goto.d.ts +29 -0
- package/dist/lib/v3/agent/tools/v3-navback.d.ts +17 -0
- package/dist/lib/v3/agent/tools/v3-screenshot.d.ts +13 -0
- package/dist/lib/v3/agent/tools/v3-scroll.d.ts +23 -0
- package/dist/lib/v3/agent/tools/v3-wait.d.ts +19 -0
- package/dist/lib/v3/agent/utils/cuaKeyMapping.d.ts +10 -0
- package/dist/lib/v3/agent/utils/imageCompression.d.ts +18 -0
- package/dist/lib/v3/agent/utils/messageProcessing.d.ts +13 -0
- package/dist/lib/v3/dom/build/scriptV3Content.d.ts +1 -0
- package/dist/lib/v3/dom/genDomScripts.d.ts +1 -0
- package/dist/lib/v3/dom/index.d.ts +1 -0
- package/dist/lib/v3/dom/piercer.entry.d.ts +1 -0
- package/dist/lib/v3/dom/piercer.runtime.d.ts +25 -0
- package/dist/lib/v3/handlers/actHandler.d.ts +18 -0
- package/dist/lib/v3/handlers/extractHandler.d.ts +29 -0
- package/dist/lib/v3/handlers/handlerUtils/actHandlerUtils.d.ts +18 -0
- package/dist/lib/v3/handlers/observeHandler.d.ts +15 -0
- package/dist/lib/v3/handlers/v3AgentHandler.d.ts +17 -0
- package/dist/lib/v3/handlers/v3CuaAgentHandler.d.ts +26 -0
- package/dist/lib/v3/index.d.ts +10 -0
- package/dist/lib/v3/launch/browserbase.d.ts +8 -0
- package/dist/lib/v3/launch/local.d.ts +13 -0
- package/dist/lib/v3/llm/AnthropicClient.d.ts +16 -0
- package/dist/lib/v3/llm/CerebrasClient.d.ts +17 -0
- package/dist/lib/v3/llm/GoogleClient.d.ts +19 -0
- package/dist/lib/v3/llm/GroqClient.d.ts +17 -0
- package/dist/lib/v3/llm/LLMClient.d.ts +99 -0
- package/dist/lib/v3/llm/LLMProvider.d.ts +10 -0
- package/dist/lib/v3/llm/OpenAIClient.d.ts +15 -0
- package/dist/lib/v3/llm/aisdk.d.ts +15 -0
- package/dist/lib/v3/logger.d.ts +48 -0
- package/dist/lib/v3/mcp/connection.d.ts +11 -0
- package/dist/lib/v3/mcp/utils.d.ts +3 -0
- package/dist/lib/v3/tests/default-page-tracking.spec.d.ts +1 -0
- package/dist/lib/v3/tests/perform-understudy-method.spec.d.ts +1 -0
- package/dist/lib/v3/tests/shadow-iframe.spec.d.ts +1 -0
- package/dist/lib/v3/tests/timeouts.spec.d.ts +1 -0
- package/dist/lib/v3/tests/v3.config.d.ts +4 -0
- package/dist/lib/v3/tests/v3.playwright.config.d.ts +2 -0
- package/dist/lib/v3/tests/xpath-for-location-deep.spec.d.ts +1 -0
- package/dist/lib/v3/types/act.d.ts +10 -0
- package/dist/lib/v3/types/agent.d.ts +132 -0
- package/dist/lib/v3/types/api.d.ts +40 -0
- package/dist/lib/v3/types/cache.d.ts +71 -0
- package/dist/lib/v3/types/context.d.ts +2 -0
- package/dist/lib/v3/types/evals.d.ts +71 -0
- package/dist/lib/v3/types/evaluator.d.ts +40 -0
- package/dist/lib/v3/types/llm.d.ts +11 -0
- package/dist/lib/v3/types/log.d.ts +23 -0
- package/dist/lib/v3/types/model.d.ts +20 -0
- package/dist/lib/v3/types/playwright.d.ts +6 -0
- package/dist/lib/v3/types/stagehand.d.ts +113 -0
- package/dist/lib/v3/types/stagehandApiErrors.d.ts +18 -0
- package/dist/lib/v3/types/stagehandErrors.d.ts +104 -0
- package/dist/lib/v3/types.d.ts +176 -0
- package/dist/lib/v3/understudy/a11y/snapshot.d.ts +71 -0
- package/dist/lib/v3/understudy/cdp.d.ts +58 -0
- package/dist/lib/v3/understudy/context.d.ts +120 -0
- package/dist/lib/v3/understudy/deepLocator.d.ts +69 -0
- package/dist/lib/v3/understudy/executionContextRegistry.d.ts +15 -0
- package/dist/lib/v3/understudy/frame.d.ts +63 -0
- package/dist/lib/v3/understudy/frameLocator.d.ts +46 -0
- package/dist/lib/v3/understudy/frameRegistry.d.ts +100 -0
- package/dist/lib/v3/understudy/locator.d.ts +196 -0
- package/dist/lib/v3/understudy/page.d.ts +241 -0
- package/dist/lib/v3/understudy/piercer.d.ts +4 -0
- package/dist/lib/v3/v3.d.ts +156 -0
- package/dist/lib/version.d.ts +5 -0
- package/package.json +130 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Locator } from "./locator";
|
|
2
|
+
import type { Frame } from "./frame";
|
|
3
|
+
import type { Page } from "./page";
|
|
4
|
+
/** Build a Locator scoped to the correct frame for a deep XPath crossing iframes. */
|
|
5
|
+
export declare function deepLocatorThroughIframes(page: Page, root: Frame, xpathOrSelector: string): Promise<Locator>;
|
|
6
|
+
/**
|
|
7
|
+
* Unified resolver that supports '>>' hop notation, deep XPath across iframes,
|
|
8
|
+
* and plain single-frame selectors. Keeps hop logic in one shared place.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveLocatorWithHops(page: Page, root: Frame, selectorRaw: string): Promise<Locator>;
|
|
11
|
+
/**
|
|
12
|
+
* DeepLocatorDelegate: a lightweight wrapper that looks like a Locator and
|
|
13
|
+
* resolves to the correct frame/element on each call using hop/deep-XPath logic.
|
|
14
|
+
*
|
|
15
|
+
* Returned by `page.deepLocator()` for ergonomic, await-free chaining:
|
|
16
|
+
* page.deepLocator('iframe#ifrA >> #btn').click()
|
|
17
|
+
*/
|
|
18
|
+
export declare class DeepLocatorDelegate {
|
|
19
|
+
private readonly page;
|
|
20
|
+
private readonly root;
|
|
21
|
+
private readonly selector;
|
|
22
|
+
constructor(page: Page, root: Frame, selector: string);
|
|
23
|
+
private real;
|
|
24
|
+
click(options?: {
|
|
25
|
+
button?: "left" | "right" | "middle";
|
|
26
|
+
clickCount?: number;
|
|
27
|
+
}): Promise<void>;
|
|
28
|
+
fill(value: string): Promise<void>;
|
|
29
|
+
type(text: string, options?: {
|
|
30
|
+
delay?: number;
|
|
31
|
+
}): Promise<void>;
|
|
32
|
+
selectOption(values: string | string[]): Promise<string[]>;
|
|
33
|
+
scrollTo(percent: number | string): Promise<void>;
|
|
34
|
+
isVisible(): Promise<boolean>;
|
|
35
|
+
isChecked(): Promise<boolean>;
|
|
36
|
+
inputValue(): Promise<string>;
|
|
37
|
+
textContent(): Promise<string>;
|
|
38
|
+
innerHtml(): Promise<string>;
|
|
39
|
+
innerText(): Promise<string>;
|
|
40
|
+
centroid(): Promise<{
|
|
41
|
+
x: number;
|
|
42
|
+
y: number;
|
|
43
|
+
}>;
|
|
44
|
+
backendNodeId(): Promise<number>;
|
|
45
|
+
highlight(options?: {
|
|
46
|
+
durationMs?: number;
|
|
47
|
+
borderColor?: {
|
|
48
|
+
r: number;
|
|
49
|
+
g: number;
|
|
50
|
+
b: number;
|
|
51
|
+
a?: number;
|
|
52
|
+
};
|
|
53
|
+
contentColor?: {
|
|
54
|
+
r: number;
|
|
55
|
+
g: number;
|
|
56
|
+
b: number;
|
|
57
|
+
a?: number;
|
|
58
|
+
};
|
|
59
|
+
}): Promise<void>;
|
|
60
|
+
sendClickEvent(options?: {
|
|
61
|
+
bubbles?: boolean;
|
|
62
|
+
cancelable?: boolean;
|
|
63
|
+
composed?: boolean;
|
|
64
|
+
detail?: number;
|
|
65
|
+
}): Promise<void>;
|
|
66
|
+
first(): this;
|
|
67
|
+
}
|
|
68
|
+
/** Factory to create a deep locator delegate from a Page + root frame. */
|
|
69
|
+
export declare function deepLocatorFromPage(page: Page, root: Frame, selector: string): DeepLocatorDelegate;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Protocol } from "devtools-protocol";
|
|
2
|
+
import type { CDPSessionLike } from "./cdp";
|
|
3
|
+
type FrameId = Protocol.Page.FrameId;
|
|
4
|
+
type ExecId = Protocol.Runtime.ExecutionContextId;
|
|
5
|
+
export declare class ExecutionContextRegistry {
|
|
6
|
+
private readonly byFrame;
|
|
7
|
+
private readonly byExec;
|
|
8
|
+
/** Wire listeners for this session. Call BEFORE Runtime.enable. */
|
|
9
|
+
attachSession(session: CDPSessionLike): void;
|
|
10
|
+
getMainWorld(session: CDPSessionLike, frameId: FrameId): ExecId | null;
|
|
11
|
+
waitForMainWorld(session: CDPSessionLike, frameId: FrameId, timeoutMs?: number): Promise<ExecId>;
|
|
12
|
+
private register;
|
|
13
|
+
}
|
|
14
|
+
export declare const executionContexts: ExecutionContextRegistry;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Protocol } from "devtools-protocol";
|
|
2
|
+
import type { CDPSessionLike } from "./cdp";
|
|
3
|
+
import { Locator } from "./locator";
|
|
4
|
+
interface FrameManager {
|
|
5
|
+
session: CDPSessionLike;
|
|
6
|
+
frameId: string;
|
|
7
|
+
pageId: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Frame
|
|
11
|
+
*
|
|
12
|
+
* A thin, session-bound handle to a specific DOM frame (by frameId).
|
|
13
|
+
* All CDP calls in this class go through `this.session`, which MUST be the
|
|
14
|
+
* owning session for `this.frameId`. Page is responsible for constructing
|
|
15
|
+
* Frames with the correct session.
|
|
16
|
+
*/
|
|
17
|
+
export declare class Frame implements FrameManager {
|
|
18
|
+
session: CDPSessionLike;
|
|
19
|
+
frameId: string;
|
|
20
|
+
pageId: string;
|
|
21
|
+
/** Owning CDP session id (useful for logs); null for root connection (should not happen for targets) */
|
|
22
|
+
readonly sessionId: string | null;
|
|
23
|
+
constructor(session: CDPSessionLike, frameId: string, pageId: string);
|
|
24
|
+
/** DOM.getNodeForLocation → DOM.describeNode */
|
|
25
|
+
getNodeAtLocation(x: number, y: number): Promise<Protocol.DOM.Node>;
|
|
26
|
+
/** CSS selector → DOM.querySelector → DOM.getBoxModel */
|
|
27
|
+
getLocationForSelector(selector: string): Promise<{
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
width: number;
|
|
31
|
+
height: number;
|
|
32
|
+
}>;
|
|
33
|
+
/** Accessibility.getFullAXTree (+ recurse into child frames if requested) */
|
|
34
|
+
getAccessibilityTree(withFrames?: boolean): Promise<Protocol.Accessibility.AXNode[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Evaluate a function or expression in this frame's isolated world.
|
|
37
|
+
* - If a string is provided, treated as a JS expression.
|
|
38
|
+
* - If a function is provided, it is stringified and invoked with the optional argument.
|
|
39
|
+
*/
|
|
40
|
+
evaluate<R = unknown, Arg = unknown>(pageFunctionOrExpression: string | ((arg: Arg) => R | Promise<R>), arg?: Arg): Promise<R>;
|
|
41
|
+
/** Page.captureScreenshot (frame-scoped session) */
|
|
42
|
+
screenshot(options?: {
|
|
43
|
+
fullPage?: boolean;
|
|
44
|
+
clip?: {
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
width: number;
|
|
48
|
+
height: number;
|
|
49
|
+
};
|
|
50
|
+
}): Promise<string>;
|
|
51
|
+
/** Child frames via Page.getFrameTree */
|
|
52
|
+
childFrames(): Promise<Frame[]>;
|
|
53
|
+
/** Wait for a lifecycle state (load/domcontentloaded/networkidle) */
|
|
54
|
+
waitForLoadState(state?: "load" | "domcontentloaded" | "networkidle"): Promise<void>;
|
|
55
|
+
/** Simple placeholder for your own locator abstraction */
|
|
56
|
+
locator(selector: string, options?: {
|
|
57
|
+
deep?: boolean;
|
|
58
|
+
depth?: number;
|
|
59
|
+
}): Locator;
|
|
60
|
+
/** Create/get an isolated world for this frame and return its executionContextId */
|
|
61
|
+
private getExecutionContextId;
|
|
62
|
+
}
|
|
63
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Page } from "./page";
|
|
2
|
+
import { Frame } from "./frame";
|
|
3
|
+
/**
|
|
4
|
+
* FrameLocator: resolves iframe elements to their child Frames and allows
|
|
5
|
+
* creating locators scoped to that frame. Supports chaining.
|
|
6
|
+
*/
|
|
7
|
+
export declare class FrameLocator {
|
|
8
|
+
private readonly parent?;
|
|
9
|
+
private readonly selector;
|
|
10
|
+
private readonly page;
|
|
11
|
+
private readonly root?;
|
|
12
|
+
constructor(page: Page, selector: string, parent?: FrameLocator, root?: Frame);
|
|
13
|
+
/** Create a nested FrameLocator under this one. */
|
|
14
|
+
frameLocator(selector: string): FrameLocator;
|
|
15
|
+
/** Resolve to the concrete Frame for this FrameLocator chain. */
|
|
16
|
+
resolveFrame(): Promise<Frame>;
|
|
17
|
+
/** Return a Locator scoped to this frame. Methods delegate to the frame lazily. */
|
|
18
|
+
locator(selector: string): LocatorDelegate;
|
|
19
|
+
}
|
|
20
|
+
/** A small delegating wrapper that resolves the frame lazily per call. */
|
|
21
|
+
declare class LocatorDelegate {
|
|
22
|
+
private readonly fl;
|
|
23
|
+
private readonly sel;
|
|
24
|
+
constructor(fl: FrameLocator, sel: string);
|
|
25
|
+
private real;
|
|
26
|
+
click(options?: {
|
|
27
|
+
button?: "left" | "right" | "middle";
|
|
28
|
+
clickCount?: number;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
fill(value: string): Promise<void>;
|
|
31
|
+
type(text: string, options?: {
|
|
32
|
+
delay?: number;
|
|
33
|
+
}): Promise<void>;
|
|
34
|
+
selectOption(values: string | string[]): Promise<string[]>;
|
|
35
|
+
scrollTo(percent: number | string): Promise<void>;
|
|
36
|
+
isVisible(): Promise<boolean>;
|
|
37
|
+
isChecked(): Promise<boolean>;
|
|
38
|
+
inputValue(): Promise<string>;
|
|
39
|
+
textContent(): Promise<string>;
|
|
40
|
+
innerHtml(): Promise<string>;
|
|
41
|
+
innerText(): Promise<string>;
|
|
42
|
+
first(): LocatorDelegate;
|
|
43
|
+
}
|
|
44
|
+
/** Factory to start a FrameLocator chain from an arbitrary root Frame. */
|
|
45
|
+
export declare function frameLocatorFromFrame(page: Page, root: Frame, selector: string): FrameLocator;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { Protocol } from "devtools-protocol";
|
|
2
|
+
/**
|
|
3
|
+
* FrameRegistry
|
|
4
|
+
*
|
|
5
|
+
* Purpose:
|
|
6
|
+
* A single, authoritative source of truth for **both**:
|
|
7
|
+
* 1) Frame topology (parent/children, current main/root id, last-seen CDP `Frame`)
|
|
8
|
+
* 2) Frame → Session ownership (which CDP session owns a given frameId)
|
|
9
|
+
* 3) Optional iframe-owner metadata (backendNodeId of the <iframe> element in the parent doc)
|
|
10
|
+
*
|
|
11
|
+
*
|
|
12
|
+
* Model:
|
|
13
|
+
* - This class is **CDP-agnostic**; it stores **sessionId strings** (not session objects).
|
|
14
|
+
* - Context bridges (wiring Target/Page events) must call the mutators below (onAttached,
|
|
15
|
+
* onNavigated, onDetached, adoptChildSession, seedFromFrameTree, setOwnerBackendNodeId).
|
|
16
|
+
* - Consumers ask read APIs (getOwnerSessionId, getParent, asProtocolFrameTree, listAll, …)
|
|
17
|
+
* and never probe ownership at run time.
|
|
18
|
+
*/
|
|
19
|
+
type FrameId = string;
|
|
20
|
+
type SessionId = string;
|
|
21
|
+
export declare class FrameRegistry {
|
|
22
|
+
/** Owner target id (top-level target); informational only */
|
|
23
|
+
private readonly ownerTargetId;
|
|
24
|
+
/** Current main/root frame id (changes on root swaps) */
|
|
25
|
+
private rootFrameId;
|
|
26
|
+
/** frameId → FrameInfo */
|
|
27
|
+
private frames;
|
|
28
|
+
/** sessionId → Set<frameId> (inverse map for diagnostics/fast membership checks) */
|
|
29
|
+
private framesBySession;
|
|
30
|
+
constructor(ownerTargetId: string, mainFrameId: FrameId);
|
|
31
|
+
/**
|
|
32
|
+
* Record that a frame attached. If `parentId` is null and `frameId` differs from the current
|
|
33
|
+
* root, this is a root swap and we rename the root id.
|
|
34
|
+
*
|
|
35
|
+
* IMPORTANT: The emitter's `sessionId` is the **owner** for the new/attached frame.
|
|
36
|
+
*/
|
|
37
|
+
onFrameAttached(frameId: FrameId, parentId: FrameId | null, sessionId: SessionId): void;
|
|
38
|
+
/**
|
|
39
|
+
* Record a navigation with the full CDP `Frame`. Also updates ownership based on the emitting
|
|
40
|
+
* session id. Handles root swap if the navigated frame is the new main (no parentId).
|
|
41
|
+
*/
|
|
42
|
+
onFrameNavigated(frame: Protocol.Page.Frame, sessionId: SessionId): void;
|
|
43
|
+
/**
|
|
44
|
+
* Record that a frame detached. If `reason !== "swap"`, remove the subtree from the graph,
|
|
45
|
+
* and clean the inverse maps. For “swap” we keep the node to preserve continuity.
|
|
46
|
+
*/
|
|
47
|
+
onFrameDetached(frameId: FrameId, reason?: "remove" | "swap" | string): void;
|
|
48
|
+
/**
|
|
49
|
+
* An adopted OOPIF child session was created whose **main** frame id equals the parent iframe’s frameId.
|
|
50
|
+
* We mark the entire child subtree as owned by `childSessionId`.
|
|
51
|
+
* (Topology edges remain aligned by the parent session’s `frameAttached` events.)
|
|
52
|
+
*/
|
|
53
|
+
adoptChildSession(childSessionId: SessionId, childMainFrameId: FrameId): void;
|
|
54
|
+
/**
|
|
55
|
+
* Seed topology and ownership from an existing `Page.getFrameTree` snapshot, typically right after
|
|
56
|
+
* a session is attached. This is a best-effort: we record frames and set the provided `sessionId`
|
|
57
|
+
* as owner for the subtree **if** an owner isn't already set.
|
|
58
|
+
*/
|
|
59
|
+
seedFromFrameTree(sessionId: SessionId, frameTree: Protocol.Page.FrameTree): void;
|
|
60
|
+
/**
|
|
61
|
+
* Set the backendNodeId of the `<iframe>` element for a child frame **as seen from its parent**.
|
|
62
|
+
* This is useful for building absolute XPath prefixes later (from the parent document).
|
|
63
|
+
*/
|
|
64
|
+
setOwnerBackendNodeId(childFrameId: FrameId, backendNodeId: number): void;
|
|
65
|
+
mainFrameId(): FrameId;
|
|
66
|
+
/**
|
|
67
|
+
* Return the owner session id for this frame. If unknown, returns `undefined`.
|
|
68
|
+
*/
|
|
69
|
+
getOwnerSessionId(frameId: FrameId): SessionId | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Return the owner backendNodeId (iframe element) if recorded.
|
|
72
|
+
* This is in the **parent** document; pair it with `getParent`.
|
|
73
|
+
*/
|
|
74
|
+
getOwnerBackendNodeId(frameId: FrameId): number | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* Return the parent frame id, or null for root/unknown.
|
|
77
|
+
*/
|
|
78
|
+
getParent(frameId: FrameId): FrameId | null;
|
|
79
|
+
/**
|
|
80
|
+
* List frame ids in root-first DFS order (same shape as CDP’s FrameTree traversal).
|
|
81
|
+
*/
|
|
82
|
+
listAllFrames(): FrameId[];
|
|
83
|
+
/**
|
|
84
|
+
* Serialize to `Protocol.Page.FrameTree` starting at the given root id (typically mainFrameId()).
|
|
85
|
+
*/
|
|
86
|
+
asProtocolFrameTree(rootId: FrameId): Protocol.Page.FrameTree;
|
|
87
|
+
/**
|
|
88
|
+
* For diagnostics: return the current owner sessions for a frame id (0..n),
|
|
89
|
+
* usually 0 or 1, but helpful to see potential inconsistencies during wiring.
|
|
90
|
+
*/
|
|
91
|
+
sessionsForFrame(frameId: FrameId): SessionId[];
|
|
92
|
+
/**
|
|
93
|
+
* For diagnostics: return current frame set per session.
|
|
94
|
+
*/
|
|
95
|
+
framesForSession(sessionId: SessionId): FrameId[];
|
|
96
|
+
private ensureNode;
|
|
97
|
+
private renameNodeId;
|
|
98
|
+
private setOwnerSessionIdInternal;
|
|
99
|
+
}
|
|
100
|
+
export {};
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { Protocol } from "devtools-protocol";
|
|
2
|
+
import { Buffer } from "buffer";
|
|
3
|
+
import type { Frame } from "./frame";
|
|
4
|
+
type MouseButton = "left" | "right" | "middle";
|
|
5
|
+
/**
|
|
6
|
+
* Locator
|
|
7
|
+
*
|
|
8
|
+
* Purpose:
|
|
9
|
+
* A small, CDP-based element interaction helper scoped to a specific `Frame`.
|
|
10
|
+
* It resolves a CSS/XPath selector inside the frame’s **isolated world**, and then
|
|
11
|
+
* performs low-level actions (click, type, select) using DOM/Runtime/Input
|
|
12
|
+
* protocol domains with minimal abstraction.
|
|
13
|
+
*
|
|
14
|
+
* Key change:
|
|
15
|
+
* - Prefer **objectId**-based CDP calls (scroll, geometry) to avoid brittle
|
|
16
|
+
* frontend nodeId mappings. nodeId is resolved on a best-effort basis and
|
|
17
|
+
* returned for compatibility, but actions do not depend on it.
|
|
18
|
+
*
|
|
19
|
+
* Notes:
|
|
20
|
+
* - Resolution is lazy: every action resolves the selector again.
|
|
21
|
+
* - Uses `Page.createIsolatedWorld` so evaluation is isolated from page scripts.
|
|
22
|
+
* - Releases remote objects (`Runtime.releaseObject`) where appropriate.
|
|
23
|
+
*/
|
|
24
|
+
export declare class Locator {
|
|
25
|
+
private readonly frame;
|
|
26
|
+
private readonly selector;
|
|
27
|
+
private readonly options?;
|
|
28
|
+
constructor(frame: Frame, selector: string, options?: {
|
|
29
|
+
deep?: boolean;
|
|
30
|
+
depth?: number;
|
|
31
|
+
});
|
|
32
|
+
/** Return the owning Frame for this locator (typed accessor, no private access). */
|
|
33
|
+
getFrame(): Frame;
|
|
34
|
+
/**
|
|
35
|
+
* Set files on an <input type="file"> element.
|
|
36
|
+
*
|
|
37
|
+
* Mirrors Playwright's Locator.setInputFiles basics:
|
|
38
|
+
* - Accepts file path(s) or payload object(s) { name, mimeType, buffer }.
|
|
39
|
+
* - Uses CDP DOM.setFileInputFiles under the hood.
|
|
40
|
+
* - Best‑effort dispatches change/input via CDP (Chrome does by default).
|
|
41
|
+
* - Passing an empty array clears the selection.
|
|
42
|
+
*/
|
|
43
|
+
setInputFiles(files: string | string[] | {
|
|
44
|
+
name: string;
|
|
45
|
+
mimeType: string;
|
|
46
|
+
buffer: ArrayBuffer | Uint8Array | Buffer | string;
|
|
47
|
+
} | Array<{
|
|
48
|
+
name: string;
|
|
49
|
+
mimeType: string;
|
|
50
|
+
buffer: ArrayBuffer | Uint8Array | Buffer | string;
|
|
51
|
+
}>): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Return the DOM backendNodeId for this locator's target element.
|
|
54
|
+
* Useful for identity comparisons without needing element handles.
|
|
55
|
+
*/
|
|
56
|
+
backendNodeId(): Promise<Protocol.DOM.BackendNodeId>;
|
|
57
|
+
/**
|
|
58
|
+
* Return the center of the element's bounding box in the owning frame's viewport
|
|
59
|
+
* (CSS pixels), rounded to integers. Scrolls into view best-effort.
|
|
60
|
+
*/
|
|
61
|
+
centroid(): Promise<{
|
|
62
|
+
x: number;
|
|
63
|
+
y: number;
|
|
64
|
+
}>;
|
|
65
|
+
/**
|
|
66
|
+
* Highlight the element's bounding box using the CDP Overlay domain.
|
|
67
|
+
* - Scrolls element into view best-effort.
|
|
68
|
+
* - Shows a semi-transparent overlay briefly, then hides it.
|
|
69
|
+
*/
|
|
70
|
+
highlight(options?: {
|
|
71
|
+
durationMs?: number;
|
|
72
|
+
borderColor?: {
|
|
73
|
+
r: number;
|
|
74
|
+
g: number;
|
|
75
|
+
b: number;
|
|
76
|
+
a?: number;
|
|
77
|
+
};
|
|
78
|
+
contentColor?: {
|
|
79
|
+
r: number;
|
|
80
|
+
g: number;
|
|
81
|
+
b: number;
|
|
82
|
+
a?: number;
|
|
83
|
+
};
|
|
84
|
+
}): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Click the element at its visual center.
|
|
87
|
+
* Steps:
|
|
88
|
+
* 1) Resolve selector to { objectId } in the frame world.
|
|
89
|
+
* 2) Scroll into view via `DOM.scrollIntoViewIfNeeded({ objectId })`.
|
|
90
|
+
* 3) Read geometry via `DOM.getBoxModel({ objectId })` → compute a center point.
|
|
91
|
+
* 4) Synthesize mouse press + release via `Input.dispatchMouseEvent`.
|
|
92
|
+
*/
|
|
93
|
+
click(options?: {
|
|
94
|
+
button?: MouseButton;
|
|
95
|
+
clickCount?: number;
|
|
96
|
+
}): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Dispatch a DOM 'click' MouseEvent on the element itself.
|
|
99
|
+
* - Does not synthesize real pointer input; directly dispatches an event.
|
|
100
|
+
* - Useful for elements that rely on click handlers without needing hit-testing.
|
|
101
|
+
*/
|
|
102
|
+
sendClickEvent(options?: {
|
|
103
|
+
bubbles?: boolean;
|
|
104
|
+
cancelable?: boolean;
|
|
105
|
+
composed?: boolean;
|
|
106
|
+
detail?: number;
|
|
107
|
+
}): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Scroll the element vertically to a given percentage (0–100).
|
|
110
|
+
* - If the element is <html> or <body>, scrolls the window/document.
|
|
111
|
+
* - Otherwise, scrolls the element itself via element.scrollTo.
|
|
112
|
+
*/
|
|
113
|
+
scrollTo(percent: number | string): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Fill an input/textarea/contenteditable element.
|
|
116
|
+
* - Sets the value/text directly in DOM.
|
|
117
|
+
* - Dispatches `input` and `change` events to mimic user input.
|
|
118
|
+
* - Releases the underlying `objectId` afterwards to avoid leaks.
|
|
119
|
+
*/
|
|
120
|
+
fill(value: string): Promise<void>;
|
|
121
|
+
/**
|
|
122
|
+
* Type text into the element (focuses first).
|
|
123
|
+
* - Focus via element.focus() in page JS (no DOM.focus(nodeId)).
|
|
124
|
+
* - If no delay, uses `Input.insertText` for efficiency.
|
|
125
|
+
* - With delay, synthesizes `keyDown`/`keyUp` per character.
|
|
126
|
+
*/
|
|
127
|
+
type(text: string, options?: {
|
|
128
|
+
delay?: number;
|
|
129
|
+
}): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Select one or more options on a `<select>` element.
|
|
132
|
+
* Returns the values actually selected after the operation.
|
|
133
|
+
*/
|
|
134
|
+
selectOption(values: string | string[]): Promise<string[]>;
|
|
135
|
+
/**
|
|
136
|
+
* Return true if the element is attached and visible (rough heuristic).
|
|
137
|
+
*/
|
|
138
|
+
isVisible(): Promise<boolean>;
|
|
139
|
+
/**
|
|
140
|
+
* Return true if the element is an input[type=checkbox|radio] and is checked.
|
|
141
|
+
* Also considers aria-checked for ARIA widgets.
|
|
142
|
+
*/
|
|
143
|
+
isChecked(): Promise<boolean>;
|
|
144
|
+
/**
|
|
145
|
+
* Return the element's input value (for input/textarea/select/contenteditable).
|
|
146
|
+
*/
|
|
147
|
+
inputValue(): Promise<string>;
|
|
148
|
+
/**
|
|
149
|
+
* Return the element's textContent (raw, not innerText).
|
|
150
|
+
*/
|
|
151
|
+
textContent(): Promise<string>;
|
|
152
|
+
/**
|
|
153
|
+
* Return the element's innerHTML string.
|
|
154
|
+
*/
|
|
155
|
+
innerHtml(): Promise<string>;
|
|
156
|
+
/**
|
|
157
|
+
* Return the element's innerText (layout-aware, visible text).
|
|
158
|
+
*/
|
|
159
|
+
innerText(): Promise<string>;
|
|
160
|
+
/**
|
|
161
|
+
* For API parity, returns the same locator (querySelector already returns the first match).
|
|
162
|
+
*/
|
|
163
|
+
first(): Locator;
|
|
164
|
+
/**
|
|
165
|
+
* Resolve `this.selector` within the frame to `{ objectId, nodeId? }`:
|
|
166
|
+
* - Ensures Runtime/DOM are enabled.
|
|
167
|
+
* - Creates (or reuses) an isolated world for this frame.
|
|
168
|
+
* - Evaluates a CSS or XPath query in that isolated world.
|
|
169
|
+
* - Best-effort: attempts to convert `objectId` to `nodeId`; failure is non-fatal.
|
|
170
|
+
*
|
|
171
|
+
* - For XPath: first try page-side resolver (__stagehandV3__.resolveSimpleXPath).
|
|
172
|
+
* If it returns null (e.g. closed DSD not captured), fall back to CDP DOM with
|
|
173
|
+
* `pierce: true` to traverse closed shadow roots and resolve by backendNodeId.
|
|
174
|
+
*/
|
|
175
|
+
resolveNode(): Promise<{
|
|
176
|
+
nodeId: Protocol.DOM.NodeId | null;
|
|
177
|
+
objectId: Protocol.Runtime.RemoteObjectId;
|
|
178
|
+
}>;
|
|
179
|
+
/**
|
|
180
|
+
* CDP fallback for XPath resolution that needs to cross *closed* shadow roots
|
|
181
|
+
* created via Declarative Shadow DOM (no attachShadow call to intercept).
|
|
182
|
+
*
|
|
183
|
+
* Strategy:
|
|
184
|
+
* - Fetch full DOM with `pierce: true` so closed shadow roots are included.
|
|
185
|
+
* - Run a small, tolerant XPath stepper over the CDP node tree:
|
|
186
|
+
* • supports absolute paths like `/html/body/...`
|
|
187
|
+
* • supports `//` descendant jumps
|
|
188
|
+
* • supports `tag[n]` numeric predicates per sibling group
|
|
189
|
+
* • supports `*`
|
|
190
|
+
* - Resolve the winning backendNodeId to an objectId for downstream actions.
|
|
191
|
+
*/
|
|
192
|
+
private resolveViaDomPierceXPath;
|
|
193
|
+
/** Compute a center point from a BoxModel content quad */
|
|
194
|
+
private centerFromBoxContent;
|
|
195
|
+
}
|
|
196
|
+
export {};
|