browser-pilot 0.0.9 → 0.0.11
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 +1 -0
- package/dist/actions.cjs +16 -7
- package/dist/actions.d.cts +2 -2
- package/dist/actions.d.ts +2 -2
- package/dist/actions.mjs +1 -1
- package/dist/browser.cjs +1619 -303
- package/dist/browser.d.cts +22 -5
- package/dist/browser.d.ts +22 -5
- package/dist/browser.mjs +3 -3
- package/dist/{chunk-R3PS4PCM.mjs → chunk-BRAFQUMG.mjs} +34 -12
- package/dist/{chunk-KKW2SZLV.mjs → chunk-FAUNIZR7.mjs} +18 -8
- package/dist/{chunk-7OSR2CAE.mjs → chunk-JHAF52FA.mjs} +1611 -301
- package/dist/cli.mjs +2349 -351
- package/dist/index.cjs +1669 -327
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +3 -3
- package/dist/providers.cjs +34 -12
- package/dist/providers.mjs +1 -1
- package/dist/{types-DOGsEYQa.d.ts → types-DtGF3yGl.d.ts} +39 -11
- package/dist/{types-CYw-7vx1.d.cts → types-GWuQJs_e.d.cts} +39 -11
- package/package.json +1 -1
package/dist/browser.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { C as CDPClient } from './client-7Nqka5MV.cjs';
|
|
2
2
|
import { b as ConnectOptions } from './types--wXNHUwt.cjs';
|
|
3
|
-
import { y as Page } from './types-
|
|
4
|
-
export { k as ActionOptions, l as ActionResult, m as ConsoleHandler, n as ConsoleMessage, o as ConsoleMessageType, p as CustomSelectConfig, D as Dialog, q as DialogHandler, r as DialogType, s as Download, E as ElementInfo, t as ElementNotFoundError, u as EmulationState, v as ErrorHandler, ae as FailureHint, F as FileInput, w as FillOptions, G as GeolocationOptions, I as InteractiveElement, N as NavigationError, x as NetworkIdleOptions, z as PageError, H as PageSnapshot, J as SnapshotNode, K as SubmitOptions, T as TimeoutError, L as TypeOptions, U as UserAgentMetadata, M as UserAgentOptions, V as ViewportOptions, W as WaitForOptions } from './types-
|
|
3
|
+
import { y as Page } from './types-GWuQJs_e.cjs';
|
|
4
|
+
export { k as ActionOptions, l as ActionResult, m as ConsoleHandler, n as ConsoleMessage, o as ConsoleMessageType, p as CustomSelectConfig, D as Dialog, q as DialogHandler, r as DialogType, s as Download, E as ElementInfo, t as ElementNotFoundError, u as EmulationState, v as ErrorHandler, ae as FailureHint, F as FileInput, w as FillOptions, G as GeolocationOptions, I as InteractiveElement, N as NavigationError, x as NetworkIdleOptions, z as PageError, H as PageSnapshot, J as SnapshotNode, K as SubmitOptions, T as TimeoutError, L as TypeOptions, U as UserAgentMetadata, M as UserAgentOptions, V as ViewportOptions, W as WaitForOptions } from './types-GWuQJs_e.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Browser class - manages CDP connection and pages
|
|
@@ -14,6 +14,18 @@ interface BrowserOptions extends ConnectOptions {
|
|
|
14
14
|
interface PageOptions {
|
|
15
15
|
/** Specific target ID to attach to */
|
|
16
16
|
targetId?: string;
|
|
17
|
+
/** Filter targets to those whose URL contains this string */
|
|
18
|
+
targetUrl?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Minimum acceptable viewport dimensions.
|
|
21
|
+
* If the attached target's viewport is smaller, it will be overridden.
|
|
22
|
+
* Defaults to { width: 200, height: 200 }.
|
|
23
|
+
* Set to false to disable viewport validation.
|
|
24
|
+
*/
|
|
25
|
+
minViewport?: {
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
} | false;
|
|
17
29
|
}
|
|
18
30
|
declare class Browser {
|
|
19
31
|
private cdp;
|
|
@@ -25,8 +37,13 @@ declare class Browser {
|
|
|
25
37
|
*/
|
|
26
38
|
static connect(options: BrowserOptions): Promise<Browser>;
|
|
27
39
|
/**
|
|
28
|
-
* Get or create a page by name
|
|
29
|
-
* If no name is provided, returns the first available page or creates a new one
|
|
40
|
+
* Get or create a page by name.
|
|
41
|
+
* If no name is provided, returns the first available page or creates a new one.
|
|
42
|
+
*
|
|
43
|
+
* Target selection heuristics (when no targetId is specified):
|
|
44
|
+
* - Prefer http/https URLs over chrome://, devtools://, about:blank
|
|
45
|
+
* - Prefer unattached targets (not already controlled by another client)
|
|
46
|
+
* - Filter by targetUrl if provided
|
|
30
47
|
*/
|
|
31
48
|
page(name?: string, options?: PageOptions): Promise<Page>;
|
|
32
49
|
/**
|
|
@@ -72,4 +89,4 @@ declare class Browser {
|
|
|
72
89
|
*/
|
|
73
90
|
declare function connect(options: BrowserOptions): Promise<Browser>;
|
|
74
91
|
|
|
75
|
-
export { Browser, type BrowserOptions, Page, connect };
|
|
92
|
+
export { Browser, type BrowserOptions, Page, type PageOptions, connect };
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { C as CDPClient } from './client-7Nqka5MV.js';
|
|
2
2
|
import { b as ConnectOptions } from './types--wXNHUwt.js';
|
|
3
|
-
import { y as Page } from './types-
|
|
4
|
-
export { k as ActionOptions, l as ActionResult, m as ConsoleHandler, n as ConsoleMessage, o as ConsoleMessageType, p as CustomSelectConfig, D as Dialog, q as DialogHandler, r as DialogType, s as Download, E as ElementInfo, t as ElementNotFoundError, u as EmulationState, v as ErrorHandler, ae as FailureHint, F as FileInput, w as FillOptions, G as GeolocationOptions, I as InteractiveElement, N as NavigationError, x as NetworkIdleOptions, z as PageError, H as PageSnapshot, J as SnapshotNode, K as SubmitOptions, T as TimeoutError, L as TypeOptions, U as UserAgentMetadata, M as UserAgentOptions, V as ViewportOptions, W as WaitForOptions } from './types-
|
|
3
|
+
import { y as Page } from './types-DtGF3yGl.js';
|
|
4
|
+
export { k as ActionOptions, l as ActionResult, m as ConsoleHandler, n as ConsoleMessage, o as ConsoleMessageType, p as CustomSelectConfig, D as Dialog, q as DialogHandler, r as DialogType, s as Download, E as ElementInfo, t as ElementNotFoundError, u as EmulationState, v as ErrorHandler, ae as FailureHint, F as FileInput, w as FillOptions, G as GeolocationOptions, I as InteractiveElement, N as NavigationError, x as NetworkIdleOptions, z as PageError, H as PageSnapshot, J as SnapshotNode, K as SubmitOptions, T as TimeoutError, L as TypeOptions, U as UserAgentMetadata, M as UserAgentOptions, V as ViewportOptions, W as WaitForOptions } from './types-DtGF3yGl.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Browser class - manages CDP connection and pages
|
|
@@ -14,6 +14,18 @@ interface BrowserOptions extends ConnectOptions {
|
|
|
14
14
|
interface PageOptions {
|
|
15
15
|
/** Specific target ID to attach to */
|
|
16
16
|
targetId?: string;
|
|
17
|
+
/** Filter targets to those whose URL contains this string */
|
|
18
|
+
targetUrl?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Minimum acceptable viewport dimensions.
|
|
21
|
+
* If the attached target's viewport is smaller, it will be overridden.
|
|
22
|
+
* Defaults to { width: 200, height: 200 }.
|
|
23
|
+
* Set to false to disable viewport validation.
|
|
24
|
+
*/
|
|
25
|
+
minViewport?: {
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
} | false;
|
|
17
29
|
}
|
|
18
30
|
declare class Browser {
|
|
19
31
|
private cdp;
|
|
@@ -25,8 +37,13 @@ declare class Browser {
|
|
|
25
37
|
*/
|
|
26
38
|
static connect(options: BrowserOptions): Promise<Browser>;
|
|
27
39
|
/**
|
|
28
|
-
* Get or create a page by name
|
|
29
|
-
* If no name is provided, returns the first available page or creates a new one
|
|
40
|
+
* Get or create a page by name.
|
|
41
|
+
* If no name is provided, returns the first available page or creates a new one.
|
|
42
|
+
*
|
|
43
|
+
* Target selection heuristics (when no targetId is specified):
|
|
44
|
+
* - Prefer http/https URLs over chrome://, devtools://, about:blank
|
|
45
|
+
* - Prefer unattached targets (not already controlled by another client)
|
|
46
|
+
* - Filter by targetUrl if provided
|
|
30
47
|
*/
|
|
31
48
|
page(name?: string, options?: PageOptions): Promise<Page>;
|
|
32
49
|
/**
|
|
@@ -72,4 +89,4 @@ declare class Browser {
|
|
|
72
89
|
*/
|
|
73
90
|
declare function connect(options: BrowserOptions): Promise<Browser>;
|
|
74
91
|
|
|
75
|
-
export { Browser, type BrowserOptions, Page, connect };
|
|
92
|
+
export { Browser, type BrowserOptions, Page, type PageOptions, connect };
|
package/dist/browser.mjs
CHANGED
|
@@ -2,14 +2,14 @@ import {
|
|
|
2
2
|
Browser,
|
|
3
3
|
Page,
|
|
4
4
|
connect
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-JHAF52FA.mjs";
|
|
6
6
|
import "./chunk-BCOZUKWS.mjs";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-BRAFQUMG.mjs";
|
|
8
8
|
import {
|
|
9
9
|
ElementNotFoundError,
|
|
10
10
|
NavigationError,
|
|
11
11
|
TimeoutError
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-FAUNIZR7.mjs";
|
|
13
13
|
export {
|
|
14
14
|
Browser,
|
|
15
15
|
ElementNotFoundError,
|
|
@@ -129,6 +129,34 @@ var BrowserlessProvider = class {
|
|
|
129
129
|
};
|
|
130
130
|
|
|
131
131
|
// src/providers/generic.ts
|
|
132
|
+
function sleep(ms) {
|
|
133
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
134
|
+
}
|
|
135
|
+
async function fetchDevToolsJson(host, path, errorPrefix, options = {}) {
|
|
136
|
+
const protocol = host.includes("://") ? "" : "http://";
|
|
137
|
+
const attempts = options.attempts ?? 1;
|
|
138
|
+
let delayMs = options.initialDelayMs ?? 50;
|
|
139
|
+
const maxDelayMs = options.maxDelayMs ?? 250;
|
|
140
|
+
let lastError;
|
|
141
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
142
|
+
try {
|
|
143
|
+
const response = await fetch(`${protocol}${host}${path}`);
|
|
144
|
+
if (response.ok) {
|
|
145
|
+
return await response.json();
|
|
146
|
+
}
|
|
147
|
+
lastError = new Error(`${errorPrefix}: ${response.status}`);
|
|
148
|
+
} catch (error) {
|
|
149
|
+
lastError = new Error(
|
|
150
|
+
`${errorPrefix}: ${error instanceof Error ? error.message : String(error)}`
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
if (attempt < attempts) {
|
|
154
|
+
await sleep(delayMs);
|
|
155
|
+
delayMs = Math.min(delayMs * 2, maxDelayMs);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
throw lastError ?? new Error(errorPrefix);
|
|
159
|
+
}
|
|
132
160
|
var GenericProvider = class {
|
|
133
161
|
name = "generic";
|
|
134
162
|
wsUrl;
|
|
@@ -147,20 +175,14 @@ var GenericProvider = class {
|
|
|
147
175
|
}
|
|
148
176
|
};
|
|
149
177
|
async function discoverTargets(host = "localhost:9222") {
|
|
150
|
-
|
|
151
|
-
const response = await fetch(`${protocol}${host}/json/list`);
|
|
152
|
-
if (!response.ok) {
|
|
153
|
-
throw new Error(`Failed to discover targets: ${response.status}`);
|
|
154
|
-
}
|
|
155
|
-
return await response.json();
|
|
178
|
+
return fetchDevToolsJson(host, "/json/list", "Failed to discover targets");
|
|
156
179
|
}
|
|
157
180
|
async function getBrowserWebSocketUrl(host = "localhost:9222") {
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
const info = await response.json();
|
|
181
|
+
const info = await fetchDevToolsJson(host, "/json/version", "Failed to get browser info", {
|
|
182
|
+
attempts: 10,
|
|
183
|
+
initialDelayMs: 50,
|
|
184
|
+
maxDelayMs: 250
|
|
185
|
+
});
|
|
164
186
|
return info.webSocketDebuggerUrl;
|
|
165
187
|
}
|
|
166
188
|
|
|
@@ -4,7 +4,12 @@ var ElementNotFoundError = class extends Error {
|
|
|
4
4
|
hints;
|
|
5
5
|
constructor(selectors, hints) {
|
|
6
6
|
const selectorList = Array.isArray(selectors) ? selectors : [selectors];
|
|
7
|
-
|
|
7
|
+
let msg = `Element not found: ${selectorList.join(", ")}`;
|
|
8
|
+
if (hints?.length) {
|
|
9
|
+
msg += `. Did you mean: ${hints.slice(0, 3).map((h) => `${h.element.ref} (${h.element.role} "${h.element.name}")`).join(", ")}`;
|
|
10
|
+
}
|
|
11
|
+
msg += `. Run 'bp snapshot' to see available elements.`;
|
|
12
|
+
super(msg);
|
|
8
13
|
this.name = "ElementNotFoundError";
|
|
9
14
|
this.selectors = selectorList;
|
|
10
15
|
this.hints = hints;
|
|
@@ -12,7 +17,8 @@ var ElementNotFoundError = class extends Error {
|
|
|
12
17
|
};
|
|
13
18
|
var TimeoutError = class extends Error {
|
|
14
19
|
constructor(message = "Operation timed out") {
|
|
15
|
-
|
|
20
|
+
const msg = message.includes("bp snapshot") ? message : `${message}. Run 'bp snapshot' to check current page state.`;
|
|
21
|
+
super(msg);
|
|
16
22
|
this.name = "TimeoutError";
|
|
17
23
|
}
|
|
18
24
|
};
|
|
@@ -95,7 +101,7 @@ var BatchExecutor = class {
|
|
|
95
101
|
}
|
|
96
102
|
case "click": {
|
|
97
103
|
if (!step.selector) throw new Error("click requires selector");
|
|
98
|
-
if (step.waitForNavigation) {
|
|
104
|
+
if (step.waitForNavigation === true) {
|
|
99
105
|
const navPromise = this.page.waitForNavigation({ timeout, optional });
|
|
100
106
|
await this.page.click(step.selector, { timeout, optional });
|
|
101
107
|
await navPromise;
|
|
@@ -110,7 +116,6 @@ var BatchExecutor = class {
|
|
|
110
116
|
await this.page.fill(step.selector, step.value, {
|
|
111
117
|
timeout,
|
|
112
118
|
optional,
|
|
113
|
-
clear: step.clear ?? true,
|
|
114
119
|
blur: step.blur
|
|
115
120
|
});
|
|
116
121
|
return { selectorUsed: this.getUsedSelector(step.selector) };
|
|
@@ -158,7 +163,8 @@ var BatchExecutor = class {
|
|
|
158
163
|
await this.page.submit(step.selector, {
|
|
159
164
|
timeout,
|
|
160
165
|
optional,
|
|
161
|
-
method: step.method ?? "enter+click"
|
|
166
|
+
method: step.method ?? "enter+click",
|
|
167
|
+
waitForNavigation: step.waitForNavigation
|
|
162
168
|
});
|
|
163
169
|
return { selectorUsed: this.getUsedSelector(step.selector) };
|
|
164
170
|
}
|
|
@@ -380,7 +386,6 @@ var ACTION_RULES = {
|
|
|
380
386
|
fill: {
|
|
381
387
|
required: { selector: { type: "string|string[]" }, value: { type: "string" } },
|
|
382
388
|
optional: {
|
|
383
|
-
clear: { type: "boolean" },
|
|
384
389
|
blur: { type: "boolean" }
|
|
385
390
|
}
|
|
386
391
|
},
|
|
@@ -411,7 +416,8 @@ var ACTION_RULES = {
|
|
|
411
416
|
submit: {
|
|
412
417
|
required: { selector: { type: "string|string[]" } },
|
|
413
418
|
optional: {
|
|
414
|
-
method: { type: "string", enum: ["enter", "click", "enter+click"] }
|
|
419
|
+
method: { type: "string", enum: ["enter", "click", "enter+click"] },
|
|
420
|
+
waitForNavigation: { type: "boolean|auto" }
|
|
415
421
|
}
|
|
416
422
|
},
|
|
417
423
|
press: {
|
|
@@ -489,7 +495,6 @@ var KNOWN_STEP_FIELDS = /* @__PURE__ */ new Set([
|
|
|
489
495
|
"timeout",
|
|
490
496
|
"optional",
|
|
491
497
|
"method",
|
|
492
|
-
"clear",
|
|
493
498
|
"blur",
|
|
494
499
|
"delay",
|
|
495
500
|
"waitForNavigation",
|
|
@@ -570,6 +575,11 @@ function checkFieldType(value, rule) {
|
|
|
570
575
|
case "boolean":
|
|
571
576
|
if (typeof value !== "boolean") return `expected boolean, got ${typeof value}`;
|
|
572
577
|
return null;
|
|
578
|
+
case "boolean|auto":
|
|
579
|
+
if (typeof value !== "boolean" && value !== "auto") {
|
|
580
|
+
return `expected boolean or "auto", got ${typeof value}`;
|
|
581
|
+
}
|
|
582
|
+
return null;
|
|
573
583
|
}
|
|
574
584
|
}
|
|
575
585
|
function validateSteps(steps) {
|