browser-autopilot 0.1.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/README.md +251 -0
- package/dist/agent/history.d.ts +41 -0
- package/dist/agent/history.js +98 -0
- package/dist/agent/history.js.map +1 -0
- package/dist/agent/loop.d.ts +34 -0
- package/dist/agent/loop.js +278 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/run.d.ts +4 -0
- package/dist/agent/run.js +67 -0
- package/dist/agent/run.js.map +1 -0
- package/dist/agent/state.d.ts +37 -0
- package/dist/agent/state.js +82 -0
- package/dist/agent/state.js.map +1 -0
- package/dist/agent/tools.d.ts +414 -0
- package/dist/agent/tools.js +399 -0
- package/dist/agent/tools.js.map +1 -0
- package/dist/browser/cdp.d.ts +91 -0
- package/dist/browser/cdp.js +470 -0
- package/dist/browser/cdp.js.map +1 -0
- package/dist/browser/dom.d.ts +30 -0
- package/dist/browser/dom.js +79 -0
- package/dist/browser/dom.js.map +1 -0
- package/dist/browser/snapshot.d.ts +19 -0
- package/dist/browser/snapshot.js +70 -0
- package/dist/browser/snapshot.js.map +1 -0
- package/dist/captcha/solver.d.ts +20 -0
- package/dist/captcha/solver.js +101 -0
- package/dist/captcha/solver.js.map +1 -0
- package/dist/config.d.ts +36 -0
- package/dist/config.js +44 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator.d.ts +33 -0
- package/dist/orchestrator.js +197 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/viewer/server.d.ts +14 -0
- package/dist/viewer/server.js +93 -0
- package/dist/viewer/server.js.map +1 -0
- package/dist/x11/agent.d.ts +34 -0
- package/dist/x11/agent.js +103 -0
- package/dist/x11/agent.js.map +1 -0
- package/dist/x11/chrome.d.ts +9 -0
- package/dist/x11/chrome.js +107 -0
- package/dist/x11/chrome.js.map +1 -0
- package/dist/x11/input.d.ts +13 -0
- package/dist/x11/input.js +75 -0
- package/dist/x11/input.js.map +1 -0
- package/dist/x11/login.d.ts +6 -0
- package/dist/x11/login.js +76 -0
- package/dist/x11/login.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDP browser client with reliable element interaction.
|
|
3
|
+
*
|
|
4
|
+
* Click chain: scrollIntoViewIfNeeded → getBoxModel → viewport clamp →
|
|
5
|
+
* mouseMoved → mousePressed → mouseReleased.
|
|
6
|
+
* If coords fail or element is occluded → resolveNode → callFunctionOn(.click()).
|
|
7
|
+
*
|
|
8
|
+
* Input chain: scrollIntoViewIfNeeded → resolveNode → focus → select-all+delete →
|
|
9
|
+
* dispatchKeyEvent(keyDown/char/keyUp) per character (React/Vue compatible).
|
|
10
|
+
*
|
|
11
|
+
* All element targeting uses backendNodeId from the AX tree — no CSS selectors.
|
|
12
|
+
*/
|
|
13
|
+
import CDP from "chrome-remote-interface";
|
|
14
|
+
import { config } from "../config.js";
|
|
15
|
+
import { DOMIndexer } from "./dom.js";
|
|
16
|
+
export class CDPBrowser {
|
|
17
|
+
client = null;
|
|
18
|
+
domIndexer = new DOMIndexer();
|
|
19
|
+
_tabs = [];
|
|
20
|
+
_activeTabId = null;
|
|
21
|
+
_dialogQueue = [];
|
|
22
|
+
_downloadedFiles = [];
|
|
23
|
+
async connect(cdpUrl = config.cdpUrl) {
|
|
24
|
+
const port = parseInt(new URL(cdpUrl).port || "9222");
|
|
25
|
+
this.client = await CDP({ port });
|
|
26
|
+
const { Page, DOM, Runtime, Network } = this.cdp;
|
|
27
|
+
await Promise.all([
|
|
28
|
+
Page.enable(),
|
|
29
|
+
DOM.enable(),
|
|
30
|
+
Runtime.enable(),
|
|
31
|
+
Network.enable(),
|
|
32
|
+
]);
|
|
33
|
+
Page.javascriptDialogOpening((params) => {
|
|
34
|
+
this._dialogQueue.push({ type: params.type, message: params.message });
|
|
35
|
+
});
|
|
36
|
+
await this.refreshTabs();
|
|
37
|
+
}
|
|
38
|
+
async disconnect() {
|
|
39
|
+
await this.client?.close();
|
|
40
|
+
this.client = null;
|
|
41
|
+
}
|
|
42
|
+
get cdp() {
|
|
43
|
+
if (!this.client)
|
|
44
|
+
throw new Error("Not connected");
|
|
45
|
+
return this.client;
|
|
46
|
+
}
|
|
47
|
+
// ── Navigation ──────────────────────────────────────────────────────────
|
|
48
|
+
async navigate(url) {
|
|
49
|
+
await this.cdp.Page.navigate({ url });
|
|
50
|
+
await this.waitForLoad();
|
|
51
|
+
}
|
|
52
|
+
async goBack() {
|
|
53
|
+
await this.cdp.Runtime.evaluate({ expression: "history.back()" });
|
|
54
|
+
await this.waitMs(1500);
|
|
55
|
+
}
|
|
56
|
+
async goForward() {
|
|
57
|
+
await this.cdp.Runtime.evaluate({ expression: "history.forward()" });
|
|
58
|
+
await this.waitMs(1500);
|
|
59
|
+
}
|
|
60
|
+
async reload() {
|
|
61
|
+
await this.cdp.Page.reload();
|
|
62
|
+
await this.waitForLoad();
|
|
63
|
+
}
|
|
64
|
+
async currentUrl() {
|
|
65
|
+
const r = await this.cdp.Runtime.evaluate({ expression: "location.href" });
|
|
66
|
+
return r.result.value;
|
|
67
|
+
}
|
|
68
|
+
async pageTitle() {
|
|
69
|
+
const r = await this.cdp.Runtime.evaluate({ expression: "document.title" });
|
|
70
|
+
return r.result.value;
|
|
71
|
+
}
|
|
72
|
+
// ── Screenshots ─────────────────────────────────────────────────────────
|
|
73
|
+
async screenshot(opts) {
|
|
74
|
+
const { data } = await this.cdp.Page.captureScreenshot({
|
|
75
|
+
format: "png",
|
|
76
|
+
...(opts?.quality ? { format: "jpeg", quality: opts.quality } : {}),
|
|
77
|
+
});
|
|
78
|
+
return data;
|
|
79
|
+
}
|
|
80
|
+
// ── Viewport ────────────────────────────────────────────────────────────
|
|
81
|
+
async getViewportSize() {
|
|
82
|
+
const metrics = await this.cdp.Page.getLayoutMetrics();
|
|
83
|
+
return {
|
|
84
|
+
width: metrics.layoutViewport.clientWidth,
|
|
85
|
+
height: metrics.layoutViewport.clientHeight,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// ── DOM / Accessibility ─────────────────────────────────────────────────
|
|
89
|
+
async getIndexedDOM() {
|
|
90
|
+
const { nodes } = await this.cdp.Accessibility.getFullAXTree();
|
|
91
|
+
return this.domIndexer.index(nodes);
|
|
92
|
+
}
|
|
93
|
+
async getPageText() {
|
|
94
|
+
const r = await this.cdp.Runtime.evaluate({ expression: "document.body?.innerText ?? ''" });
|
|
95
|
+
return r.result.value;
|
|
96
|
+
}
|
|
97
|
+
// ── Resolve backendNodeId → objectId ────────────────────────────────────
|
|
98
|
+
async resolveNode(backendNodeId) {
|
|
99
|
+
const result = await this.cdp.DOM.resolveNode({ backendNodeId });
|
|
100
|
+
if (!result?.object?.objectId) {
|
|
101
|
+
throw new Error(`Cannot resolve backendNodeId ${backendNodeId} — element may be stale`);
|
|
102
|
+
}
|
|
103
|
+
return result.object.objectId;
|
|
104
|
+
}
|
|
105
|
+
async scrollIntoView(backendNodeId) {
|
|
106
|
+
try {
|
|
107
|
+
await this.cdp.DOM.scrollIntoViewIfNeeded({ backendNodeId });
|
|
108
|
+
await this.waitMs(50);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Element detached or not scrollable — continue anyway
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async getElementCenter(backendNodeId) {
|
|
115
|
+
try {
|
|
116
|
+
const { model } = await this.cdp.DOM.getBoxModel({ backendNodeId });
|
|
117
|
+
if (!model || !model.content || model.content.length < 8)
|
|
118
|
+
return null;
|
|
119
|
+
// content quad: [x1,y1, x2,y2, x3,y3, x4,y4]
|
|
120
|
+
const xs = [model.content[0], model.content[2], model.content[4], model.content[6]];
|
|
121
|
+
const ys = [model.content[1], model.content[3], model.content[5], model.content[7]];
|
|
122
|
+
const x = xs.reduce((a, b) => a + b, 0) / 4;
|
|
123
|
+
const y = ys.reduce((a, b) => a + b, 0) / 4;
|
|
124
|
+
// Clamp to viewport
|
|
125
|
+
const vp = await this.getViewportSize();
|
|
126
|
+
return {
|
|
127
|
+
x: Math.max(0, Math.min(vp.width - 1, x)),
|
|
128
|
+
y: Math.max(0, Math.min(vp.height - 1, y)),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async jsClick(objectId) {
|
|
136
|
+
await this.cdp.Runtime.callFunctionOn({
|
|
137
|
+
functionDeclaration: "function() { this.click(); }",
|
|
138
|
+
objectId,
|
|
139
|
+
});
|
|
140
|
+
await this.waitMs(50);
|
|
141
|
+
}
|
|
142
|
+
// ── Element interaction (by index) ──────────────────────────────────────
|
|
143
|
+
async clickByIndex(index) {
|
|
144
|
+
const el = this.domIndexer.getElement(index);
|
|
145
|
+
if (!el)
|
|
146
|
+
throw new Error(`Element [${index}] not found`);
|
|
147
|
+
const bid = el.backendNodeId;
|
|
148
|
+
// Step 1: Scroll into view
|
|
149
|
+
await this.scrollIntoView(bid);
|
|
150
|
+
// Step 2: Try coordinate-based CDP click
|
|
151
|
+
const center = await this.getElementCenter(bid);
|
|
152
|
+
if (center) {
|
|
153
|
+
// Check occlusion: is the node at these coords actually our node?
|
|
154
|
+
const occluded = await this.isOccluded(bid, center.x, center.y);
|
|
155
|
+
if (!occluded) {
|
|
156
|
+
await this.clickAtCoords(center.x, center.y);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Step 3: Fallback — JS click via objectId (bypasses overlays)
|
|
161
|
+
const objectId = await this.resolveNode(bid);
|
|
162
|
+
await this.jsClick(objectId);
|
|
163
|
+
}
|
|
164
|
+
async inputByIndex(index, text, clear = true) {
|
|
165
|
+
const el = this.domIndexer.getElement(index);
|
|
166
|
+
if (!el)
|
|
167
|
+
throw new Error(`Element [${index}] not found`);
|
|
168
|
+
const bid = el.backendNodeId;
|
|
169
|
+
// Scroll into view
|
|
170
|
+
await this.scrollIntoView(bid);
|
|
171
|
+
// Resolve to objectId
|
|
172
|
+
const objectId = await this.resolveNode(bid);
|
|
173
|
+
// Focus the element
|
|
174
|
+
try {
|
|
175
|
+
await this.cdp.DOM.focus({ backendNodeId: bid });
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// Fallback: click to focus
|
|
179
|
+
const center = await this.getElementCenter(bid);
|
|
180
|
+
if (center) {
|
|
181
|
+
await this.clickAtCoords(center.x, center.y);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
await this.jsClick(objectId);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
await this.waitMs(30);
|
|
188
|
+
// Clear existing text
|
|
189
|
+
if (clear) {
|
|
190
|
+
// Select all + delete
|
|
191
|
+
await this.cdp.Input.dispatchKeyEvent({
|
|
192
|
+
type: "keyDown", key: "a", code: "KeyA",
|
|
193
|
+
modifiers: 8, // Ctrl/Cmd
|
|
194
|
+
windowsVirtualKeyCode: 65,
|
|
195
|
+
});
|
|
196
|
+
await this.cdp.Input.dispatchKeyEvent({ type: "keyUp", key: "a", code: "KeyA", modifiers: 8, windowsVirtualKeyCode: 65 });
|
|
197
|
+
await this.waitMs(10);
|
|
198
|
+
await this.cdp.Input.dispatchKeyEvent({
|
|
199
|
+
type: "keyDown", key: "Backspace", code: "Backspace", windowsVirtualKeyCode: 8,
|
|
200
|
+
});
|
|
201
|
+
await this.cdp.Input.dispatchKeyEvent({ type: "keyUp", key: "Backspace", code: "Backspace", windowsVirtualKeyCode: 8 });
|
|
202
|
+
await this.waitMs(10);
|
|
203
|
+
}
|
|
204
|
+
// Type character by character: keyDown → char → keyUp
|
|
205
|
+
for (const char of text) {
|
|
206
|
+
if (char === "\n") {
|
|
207
|
+
await this.cdp.Input.dispatchKeyEvent({
|
|
208
|
+
type: "keyDown", key: "Enter", code: "Enter", windowsVirtualKeyCode: 13,
|
|
209
|
+
});
|
|
210
|
+
await this.cdp.Input.dispatchKeyEvent({ type: "char", text: "\r", key: "Enter" });
|
|
211
|
+
await this.cdp.Input.dispatchKeyEvent({
|
|
212
|
+
type: "keyUp", key: "Enter", code: "Enter", windowsVirtualKeyCode: 13,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
await this.cdp.Input.dispatchKeyEvent({
|
|
217
|
+
type: "keyDown", key: char, code: `Key${char.toUpperCase()}`,
|
|
218
|
+
windowsVirtualKeyCode: char.toUpperCase().charCodeAt(0),
|
|
219
|
+
});
|
|
220
|
+
await this.cdp.Input.dispatchKeyEvent({ type: "char", text: char, key: char });
|
|
221
|
+
await this.cdp.Input.dispatchKeyEvent({
|
|
222
|
+
type: "keyUp", key: char, code: `Key${char.toUpperCase()}`,
|
|
223
|
+
windowsVirtualKeyCode: char.toUpperCase().charCodeAt(0),
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
await this.waitMs(5);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
async clickAtCoords(x, y) {
|
|
230
|
+
// mouseMoved first (some sites need hover state)
|
|
231
|
+
await this.cdp.Input.dispatchMouseEvent({ type: "mouseMoved", x, y });
|
|
232
|
+
await this.waitMs(50);
|
|
233
|
+
await this.cdp.Input.dispatchMouseEvent({
|
|
234
|
+
type: "mousePressed", x, y, button: "left", clickCount: 1,
|
|
235
|
+
});
|
|
236
|
+
await this.waitMs(80);
|
|
237
|
+
await this.cdp.Input.dispatchMouseEvent({
|
|
238
|
+
type: "mouseReleased", x, y, button: "left", clickCount: 1,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
async type(text) {
|
|
242
|
+
for (const char of text) {
|
|
243
|
+
await this.cdp.Input.dispatchKeyEvent({ type: "keyDown", key: char, code: `Key${char.toUpperCase()}`, windowsVirtualKeyCode: char.toUpperCase().charCodeAt(0) });
|
|
244
|
+
await this.cdp.Input.dispatchKeyEvent({ type: "char", text: char, key: char });
|
|
245
|
+
await this.cdp.Input.dispatchKeyEvent({ type: "keyUp", key: char, code: `Key${char.toUpperCase()}`, windowsVirtualKeyCode: char.toUpperCase().charCodeAt(0) });
|
|
246
|
+
await this.waitMs(15);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
async pressKey(key) {
|
|
250
|
+
const keyMap = {
|
|
251
|
+
Enter: [13, "Enter"], Tab: [9, "Tab"], Escape: [27, "Escape"],
|
|
252
|
+
Backspace: [8, "Backspace"], Delete: [46, "Delete"],
|
|
253
|
+
ArrowUp: [38, "ArrowUp"], ArrowDown: [40, "ArrowDown"],
|
|
254
|
+
ArrowLeft: [37, "ArrowLeft"], ArrowRight: [39, "ArrowRight"],
|
|
255
|
+
Home: [36, "Home"], End: [35, "End"],
|
|
256
|
+
PageUp: [33, "PageUp"], PageDown: [34, "PageDown"],
|
|
257
|
+
Space: [32, "Space"],
|
|
258
|
+
};
|
|
259
|
+
const [vk, code] = keyMap[key] ?? [0, key];
|
|
260
|
+
await this.cdp.Input.dispatchKeyEvent({ type: "keyDown", key, code, windowsVirtualKeyCode: vk });
|
|
261
|
+
await this.cdp.Input.dispatchKeyEvent({ type: "keyUp", key, code, windowsVirtualKeyCode: vk });
|
|
262
|
+
}
|
|
263
|
+
async scroll(direction, pixels = 500) {
|
|
264
|
+
const delta = direction === "down" ? pixels : -pixels;
|
|
265
|
+
const vp = await this.getViewportSize();
|
|
266
|
+
await this.cdp.Input.dispatchMouseEvent({
|
|
267
|
+
type: "mouseWheel",
|
|
268
|
+
x: Math.round(vp.width / 2),
|
|
269
|
+
y: Math.round(vp.height / 2),
|
|
270
|
+
deltaX: 0,
|
|
271
|
+
deltaY: delta,
|
|
272
|
+
});
|
|
273
|
+
await this.waitMs(300);
|
|
274
|
+
}
|
|
275
|
+
async scrollToElement(index) {
|
|
276
|
+
const el = this.domIndexer.getElement(index);
|
|
277
|
+
if (!el)
|
|
278
|
+
return false;
|
|
279
|
+
await this.scrollIntoView(el.backendNodeId);
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
async scrollToText(text) {
|
|
283
|
+
const found = await this.cdp.Runtime.evaluate({
|
|
284
|
+
expression: `(() => {
|
|
285
|
+
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
|
|
286
|
+
while (walker.nextNode()) {
|
|
287
|
+
if (walker.currentNode.textContent?.includes(${JSON.stringify(text)})) {
|
|
288
|
+
walker.currentNode.parentElement?.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return false;
|
|
293
|
+
})()`,
|
|
294
|
+
returnByValue: true,
|
|
295
|
+
});
|
|
296
|
+
await this.waitMs(500);
|
|
297
|
+
return found.result.value;
|
|
298
|
+
}
|
|
299
|
+
// ── Occlusion check ─────────────────────────────────────────────────────
|
|
300
|
+
async isOccluded(backendNodeId, x, y) {
|
|
301
|
+
try {
|
|
302
|
+
const objectId = await this.resolveNode(backendNodeId);
|
|
303
|
+
const result = await this.cdp.Runtime.callFunctionOn({
|
|
304
|
+
functionDeclaration: `function(x, y) {
|
|
305
|
+
const hit = document.elementFromPoint(x, y);
|
|
306
|
+
if (!hit) return true;
|
|
307
|
+
return !this.contains(hit) && !hit.contains(this);
|
|
308
|
+
}`,
|
|
309
|
+
objectId,
|
|
310
|
+
arguments: [{ value: x }, { value: y }],
|
|
311
|
+
returnByValue: true,
|
|
312
|
+
});
|
|
313
|
+
return result.result.value === true;
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
// ── Tab management ──────────────────────────────────────────────────────
|
|
320
|
+
async refreshTabs() {
|
|
321
|
+
try {
|
|
322
|
+
const { targetInfos } = await this.cdp.Target.getTargets();
|
|
323
|
+
this._tabs = targetInfos
|
|
324
|
+
.filter((t) => t.type === "page")
|
|
325
|
+
.map((t) => ({ id: t.targetId, url: t.url, title: t.title }));
|
|
326
|
+
}
|
|
327
|
+
catch {
|
|
328
|
+
this._tabs = [];
|
|
329
|
+
}
|
|
330
|
+
return this._tabs;
|
|
331
|
+
}
|
|
332
|
+
get tabs() { return this._tabs; }
|
|
333
|
+
async switchTab(tabId) {
|
|
334
|
+
await this.cdp.Target.activateTarget({ targetId: tabId });
|
|
335
|
+
this._activeTabId = tabId;
|
|
336
|
+
await this.waitMs(500);
|
|
337
|
+
}
|
|
338
|
+
async closeTab(tabId) {
|
|
339
|
+
await this.cdp.Target.closeTarget({ targetId: tabId });
|
|
340
|
+
await this.refreshTabs();
|
|
341
|
+
}
|
|
342
|
+
async newTab(url = "about:blank") {
|
|
343
|
+
const { targetId } = await this.cdp.Target.createTarget({ url });
|
|
344
|
+
await this.refreshTabs();
|
|
345
|
+
return targetId;
|
|
346
|
+
}
|
|
347
|
+
// ── Dialogs ─────────────────────────────────────────────────────────────
|
|
348
|
+
get pendingDialogs() { return this._dialogQueue; }
|
|
349
|
+
async handleDialog(accept, promptText) {
|
|
350
|
+
await this.cdp.Page.handleJavaScriptDialog({ accept, promptText });
|
|
351
|
+
this._dialogQueue.shift();
|
|
352
|
+
}
|
|
353
|
+
// ── JavaScript execution ────────────────────────────────────────────────
|
|
354
|
+
async evaluate(expression) {
|
|
355
|
+
let code = expression.trim();
|
|
356
|
+
// Auto-wrap in IIFE if the code uses statements that can't be top-level expressions
|
|
357
|
+
const needsIIFE = /\b(return\b|let |const |var )/.test(code) && !code.startsWith("(");
|
|
358
|
+
if (needsIIFE) {
|
|
359
|
+
code = `(() => { ${code} })()`;
|
|
360
|
+
}
|
|
361
|
+
const result = await this.cdp.Runtime.evaluate({
|
|
362
|
+
expression: code,
|
|
363
|
+
returnByValue: true,
|
|
364
|
+
awaitPromise: true,
|
|
365
|
+
});
|
|
366
|
+
if (result.exceptionDetails) {
|
|
367
|
+
const desc = result.exceptionDetails.exception?.description
|
|
368
|
+
?? result.exceptionDetails.text
|
|
369
|
+
?? "Unknown JS error";
|
|
370
|
+
throw new Error(`JS error: ${desc}`);
|
|
371
|
+
}
|
|
372
|
+
return result.result.value;
|
|
373
|
+
}
|
|
374
|
+
// ── HTML inspection ──────────────────────────────────────────────────────
|
|
375
|
+
async getElementHtml(index, inner = false) {
|
|
376
|
+
const el = this.domIndexer.getElement(index);
|
|
377
|
+
if (!el)
|
|
378
|
+
return `Element [${index}] not found`;
|
|
379
|
+
const objectId = await this.resolveNode(el.backendNodeId);
|
|
380
|
+
const prop = inner ? "innerHTML" : "outerHTML";
|
|
381
|
+
const result = await this.cdp.Runtime.callFunctionOn({
|
|
382
|
+
functionDeclaration: `function() { return this.${prop}; }`,
|
|
383
|
+
objectId,
|
|
384
|
+
returnByValue: true,
|
|
385
|
+
});
|
|
386
|
+
return result.result.value;
|
|
387
|
+
}
|
|
388
|
+
// ── Cookies ─────────────────────────────────────────────────────────────
|
|
389
|
+
async getCookies() {
|
|
390
|
+
const { cookies } = await this.cdp.Network.getCookies();
|
|
391
|
+
return cookies.map((c) => ({ name: c.name, value: c.value, domain: c.domain }));
|
|
392
|
+
}
|
|
393
|
+
async setCookie(name, value, domain) {
|
|
394
|
+
await this.cdp.Network.setCookie({ name, value, domain, path: "/" });
|
|
395
|
+
}
|
|
396
|
+
async clearCookies() {
|
|
397
|
+
await this.cdp.Network.clearBrowserCookies();
|
|
398
|
+
}
|
|
399
|
+
// ── File upload ─────────────────────────────────────────────────────────
|
|
400
|
+
async uploadFile(selector, filePaths) {
|
|
401
|
+
const doc = await this.cdp.DOM.getDocument();
|
|
402
|
+
const { nodeId } = await this.cdp.DOM.querySelector({
|
|
403
|
+
nodeId: doc.root.nodeId,
|
|
404
|
+
selector,
|
|
405
|
+
});
|
|
406
|
+
if (!nodeId)
|
|
407
|
+
throw new Error(`File input not found: ${selector}`);
|
|
408
|
+
await this.cdp.DOM.setFileInputFiles({ nodeId, files: filePaths });
|
|
409
|
+
}
|
|
410
|
+
// ── Dropdown ────────────────────────────────────────────────────────────
|
|
411
|
+
async getDropdownOptions(selector) {
|
|
412
|
+
return await this.evaluate(`
|
|
413
|
+
Array.from(document.querySelector('${selector}')?.options ?? [])
|
|
414
|
+
.map(o => ({ value: o.value, text: o.textContent?.trim() ?? '' }))
|
|
415
|
+
`);
|
|
416
|
+
}
|
|
417
|
+
async selectDropdown(selector, value) {
|
|
418
|
+
await this.evaluate(`
|
|
419
|
+
(() => {
|
|
420
|
+
const sel = document.querySelector('${selector}');
|
|
421
|
+
if (!sel) return;
|
|
422
|
+
sel.value = ${JSON.stringify(value)};
|
|
423
|
+
sel.dispatchEvent(new Event('change', { bubbles: true }));
|
|
424
|
+
})()
|
|
425
|
+
`);
|
|
426
|
+
}
|
|
427
|
+
// ── Search ──────────────────────────────────────────────────────────────
|
|
428
|
+
async searchPage(query) {
|
|
429
|
+
return await this.evaluate(`
|
|
430
|
+
(() => {
|
|
431
|
+
const text = document.body.innerText;
|
|
432
|
+
const regex = new RegExp(${JSON.stringify(query)}, 'gi');
|
|
433
|
+
const matches = [];
|
|
434
|
+
let match;
|
|
435
|
+
while ((match = regex.exec(text)) !== null) {
|
|
436
|
+
const start = Math.max(0, match.index - 50);
|
|
437
|
+
const end = Math.min(text.length, match.index + match[0].length + 50);
|
|
438
|
+
matches.push('...' + text.slice(start, end) + '...');
|
|
439
|
+
}
|
|
440
|
+
return matches.slice(0, 10);
|
|
441
|
+
})()
|
|
442
|
+
`);
|
|
443
|
+
}
|
|
444
|
+
// ── Helpers ──────────────────────────────────────────────────────────────
|
|
445
|
+
async waitMs(ms) {
|
|
446
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
447
|
+
}
|
|
448
|
+
async waitForLoad(timeoutMs = 8000) {
|
|
449
|
+
try {
|
|
450
|
+
await Promise.race([
|
|
451
|
+
this.cdp.Page.loadEventFired(),
|
|
452
|
+
this.waitMs(timeoutMs),
|
|
453
|
+
]);
|
|
454
|
+
}
|
|
455
|
+
catch { }
|
|
456
|
+
await this.waitMs(500);
|
|
457
|
+
}
|
|
458
|
+
async waitForUrl(substring, timeoutMs = 30_000) {
|
|
459
|
+
const start = Date.now();
|
|
460
|
+
while (Date.now() - start < timeoutMs) {
|
|
461
|
+
const url = await this.currentUrl();
|
|
462
|
+
if (url.includes(substring))
|
|
463
|
+
return;
|
|
464
|
+
await this.waitMs(500);
|
|
465
|
+
}
|
|
466
|
+
throw new Error(`Timeout waiting for URL containing "${substring}"`);
|
|
467
|
+
}
|
|
468
|
+
get downloadedFiles() { return this._downloadedFiles; }
|
|
469
|
+
}
|
|
470
|
+
//# sourceMappingURL=cdp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp.js","sourceRoot":"","sources":["../../src/browser/cdp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM indexing system.
|
|
3
|
+
*
|
|
4
|
+
* Converts the accessibility tree into an indexed representation
|
|
5
|
+
* where the LLM can reference elements by [1], [2], etc.
|
|
6
|
+
*
|
|
7
|
+
* Elements are identified by backendNodeId (stable CDP handle)
|
|
8
|
+
* rather than fragile CSS selectors.
|
|
9
|
+
*/
|
|
10
|
+
export interface IndexedElement {
|
|
11
|
+
index: number;
|
|
12
|
+
role: string;
|
|
13
|
+
name: string;
|
|
14
|
+
value: string;
|
|
15
|
+
backendNodeId: number;
|
|
16
|
+
isInteractive: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare class DOMIndexer {
|
|
19
|
+
private elements;
|
|
20
|
+
private counter;
|
|
21
|
+
/**
|
|
22
|
+
* Index an accessibility tree from CDP Accessibility.getFullAXTree().
|
|
23
|
+
* Returns serialized text (for LLM) and element map (for action execution).
|
|
24
|
+
*/
|
|
25
|
+
index(axNodes: any[]): {
|
|
26
|
+
text: string;
|
|
27
|
+
elements: Map<number, IndexedElement>;
|
|
28
|
+
};
|
|
29
|
+
getElement(index: number): IndexedElement | undefined;
|
|
30
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM indexing system.
|
|
3
|
+
*
|
|
4
|
+
* Converts the accessibility tree into an indexed representation
|
|
5
|
+
* where the LLM can reference elements by [1], [2], etc.
|
|
6
|
+
*
|
|
7
|
+
* Elements are identified by backendNodeId (stable CDP handle)
|
|
8
|
+
* rather than fragile CSS selectors.
|
|
9
|
+
*/
|
|
10
|
+
const INTERACTIVE_ROLES = new Set([
|
|
11
|
+
"button", "link", "textbox", "searchbox", "combobox", "listbox",
|
|
12
|
+
"checkbox", "radio", "switch", "tab", "menuitem", "menuitemcheckbox",
|
|
13
|
+
"menuitemradio", "option", "slider", "spinbutton", "treeitem",
|
|
14
|
+
]);
|
|
15
|
+
const CONTENT_ROLES = new Set([
|
|
16
|
+
"heading", "paragraph", "blockquote", "code", "img", "figure",
|
|
17
|
+
"table", "cell", "row", "list", "listitem", "article", "main",
|
|
18
|
+
"navigation", "banner", "contentinfo", "complementary", "form",
|
|
19
|
+
"region", "status", "alert", "dialog", "tooltip",
|
|
20
|
+
]);
|
|
21
|
+
const SKIP_ROLES = new Set([
|
|
22
|
+
"none", "generic", "InlineTextBox", "RootWebArea", "ignored",
|
|
23
|
+
"presentation", "group",
|
|
24
|
+
]);
|
|
25
|
+
export class DOMIndexer {
|
|
26
|
+
elements = new Map();
|
|
27
|
+
counter = 0;
|
|
28
|
+
/**
|
|
29
|
+
* Index an accessibility tree from CDP Accessibility.getFullAXTree().
|
|
30
|
+
* Returns serialized text (for LLM) and element map (for action execution).
|
|
31
|
+
*/
|
|
32
|
+
index(axNodes) {
|
|
33
|
+
this.elements.clear();
|
|
34
|
+
this.counter = 0;
|
|
35
|
+
const lines = [];
|
|
36
|
+
for (const node of axNodes) {
|
|
37
|
+
const role = node.role?.value ?? "";
|
|
38
|
+
const name = node.name?.value ?? "";
|
|
39
|
+
const value = node.value?.value ?? "";
|
|
40
|
+
const backendNodeId = node.backendDOMNodeId;
|
|
41
|
+
if (SKIP_ROLES.has(role) || !role)
|
|
42
|
+
continue;
|
|
43
|
+
const isInteractive = INTERACTIVE_ROLES.has(role);
|
|
44
|
+
const isContent = CONTENT_ROLES.has(role);
|
|
45
|
+
if (!isInteractive && !isContent)
|
|
46
|
+
continue;
|
|
47
|
+
if (!isInteractive && !name && !value)
|
|
48
|
+
continue;
|
|
49
|
+
let indexLabel = "";
|
|
50
|
+
if (isInteractive && backendNodeId != null) {
|
|
51
|
+
this.counter++;
|
|
52
|
+
const el = {
|
|
53
|
+
index: this.counter,
|
|
54
|
+
role,
|
|
55
|
+
name,
|
|
56
|
+
value,
|
|
57
|
+
backendNodeId,
|
|
58
|
+
isInteractive: true,
|
|
59
|
+
};
|
|
60
|
+
this.elements.set(this.counter, el);
|
|
61
|
+
indexLabel = `[${this.counter}]`;
|
|
62
|
+
}
|
|
63
|
+
const parts = [];
|
|
64
|
+
if (indexLabel)
|
|
65
|
+
parts.push(indexLabel);
|
|
66
|
+
parts.push(role);
|
|
67
|
+
if (name)
|
|
68
|
+
parts.push(`"${name}"`);
|
|
69
|
+
if (value)
|
|
70
|
+
parts.push(`value="${value}"`);
|
|
71
|
+
lines.push(parts.join(" "));
|
|
72
|
+
}
|
|
73
|
+
return { text: lines.join("\n"), elements: this.elements };
|
|
74
|
+
}
|
|
75
|
+
getElement(index) {
|
|
76
|
+
return this.elements.get(index);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=dom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom.js","sourceRoot":"","sources":["../../src/browser/dom.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM snapshot serialization for LLM consumption.
|
|
3
|
+
*
|
|
4
|
+
* Inspired by agent-browser's snapshot.ts — converts the accessibility tree
|
|
5
|
+
* into indexed text the LLM can reason about and reference elements by [ref=eN].
|
|
6
|
+
*/
|
|
7
|
+
export interface ElementRef {
|
|
8
|
+
ref: string;
|
|
9
|
+
role: string;
|
|
10
|
+
name: string;
|
|
11
|
+
selector: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function serializeAXNodes(nodes: any[], opts?: {
|
|
14
|
+
interactive?: boolean;
|
|
15
|
+
maxDepth?: number;
|
|
16
|
+
}): {
|
|
17
|
+
text: string;
|
|
18
|
+
refs: Map<string, ElementRef>;
|
|
19
|
+
};
|