@xbrowser/cli 1.0.2 → 1.0.3
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/dist/{browser-GITRHHFO.js → browser-5CTOA2WS.js} +3 -3
- package/dist/{browser-R56O3CW6.js → browser-ITLZZDHJ.js} +4 -2
- package/dist/{browser-ZJOZB5CR.js → browser-IUJXXNBT.js} +5 -4
- package/dist/{cdp-driver-BE3FOMRN.js → cdp-driver-4X3DK6PS.js} +19 -5
- package/dist/{cdp-driver-TOPYJIFL.js → cdp-driver-D6WMSMWX.js} +3 -2
- package/dist/{chunk-Q4IGYTKR.js → chunk-6WOSXSCQ.js} +6 -2
- package/dist/{chunk-ZZ2TFWIV.js → chunk-ABXMBNQ6.js} +1 -1
- package/dist/{chunk-JPHCY4TC.js → chunk-AMI64BSD.js} +9 -1
- package/dist/{chunk-CAFNSGYM.js → chunk-DKWR54XQ.js} +24 -8
- package/dist/chunk-GDKLH7ZY.js +8 -0
- package/dist/{chunk-QIK2I3VQ.js → chunk-LRBSUKUZ.js} +7 -4
- package/dist/{chunk-PPG4D2EW.js → chunk-N2JFPWMI.js} +21 -5
- package/dist/{chunk-BBMRDUYQ.js → chunk-TNEN6VQ2.js} +4 -1
- package/dist/{chunk-JPA2ZT2R.js → chunk-TWWOIJM7.js} +7 -4
- package/dist/cli.js +134 -56
- package/dist/{daemon-client-UZZEHHIV.js → daemon-client-3JOKX2L2.js} +2 -1
- package/dist/{daemon-client-DRCUMNHK.js → daemon-client-DIEHGP5B.js} +5 -2
- package/dist/daemon-main.js +122 -57
- package/dist/index.d.ts +1 -1
- package/dist/index.js +140 -65
- package/dist/{launcher-QUJ4M2VS.js → launcher-L2JNDB2H.js} +2 -1
- package/dist/{launcher-YARP45UY.js → launcher-OZXJQPNG.js} +1 -1
- package/dist/{proxy-LV4BJ5RC.js → proxy-C6CK3UH5.js} +1 -1
- package/dist/{session-replayer-GLTUICSD.js → session-replayer-MY27H4DX.js} +1 -1
- package/package.json +1 -1
|
@@ -20,9 +20,9 @@ import {
|
|
|
20
20
|
saveSessionDiskMeta,
|
|
21
21
|
setActivePage,
|
|
22
22
|
touchSession
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-DKWR54XQ.js";
|
|
24
|
+
import "./chunk-TNEN6VQ2.js";
|
|
25
|
+
import "./chunk-GDKLH7ZY.js";
|
|
26
26
|
import "./chunk-KFQGP6VL.js";
|
|
27
27
|
export {
|
|
28
28
|
closeAllSessions,
|
|
@@ -20,8 +20,10 @@ import {
|
|
|
20
20
|
saveSessionDiskMeta,
|
|
21
21
|
setActivePage,
|
|
22
22
|
touchSession
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-LRBSUKUZ.js";
|
|
24
|
+
import "./chunk-N2JFPWMI.js";
|
|
25
|
+
import "./chunk-TNEN6VQ2.js";
|
|
26
|
+
import "./chunk-GDKLH7ZY.js";
|
|
25
27
|
import "./chunk-KFQGP6VL.js";
|
|
26
28
|
export {
|
|
27
29
|
closeAllSessions,
|
|
@@ -20,10 +20,11 @@ import {
|
|
|
20
20
|
saveSessionDiskMeta,
|
|
21
21
|
setActivePage,
|
|
22
22
|
touchSession
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
26
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-TWWOIJM7.js";
|
|
24
|
+
import "./chunk-N2JFPWMI.js";
|
|
25
|
+
import "./chunk-TNEN6VQ2.js";
|
|
26
|
+
import "./chunk-GDKLH7ZY.js";
|
|
27
|
+
import "./chunk-ABXMBNQ6.js";
|
|
27
28
|
import "./chunk-KFQGP6VL.js";
|
|
28
29
|
export {
|
|
29
30
|
closeAllSessions,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
connectToCDP,
|
|
3
|
+
errMsg,
|
|
3
4
|
findChrome,
|
|
4
5
|
getCDPTargets,
|
|
5
6
|
killChrome,
|
|
6
7
|
launchChrome
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-AMI64BSD.js";
|
|
8
9
|
import {
|
|
9
10
|
__require
|
|
10
11
|
} from "./chunk-3RG5ZIWI.js";
|
|
@@ -1200,7 +1201,7 @@ var XBPageImpl = class _XBPageImpl {
|
|
|
1200
1201
|
);
|
|
1201
1202
|
if (result) return result;
|
|
1202
1203
|
} catch (err) {
|
|
1203
|
-
lastError = err;
|
|
1204
|
+
lastError = err instanceof Error ? err : new Error(errMsg(err));
|
|
1204
1205
|
}
|
|
1205
1206
|
const pollMs = typeof polling === "number" ? polling : 16;
|
|
1206
1207
|
await this.waitForTimeout(pollMs);
|
|
@@ -1610,6 +1611,19 @@ Last error: ${lastError.message}` : "";
|
|
|
1610
1611
|
async _cdpSend(method, params) {
|
|
1611
1612
|
return this.conn.send(method, params, this.sessionId);
|
|
1612
1613
|
}
|
|
1614
|
+
/**
|
|
1615
|
+
* 开启/关闭原生文件选择框拦截(CDP stateful 开关)。
|
|
1616
|
+
*
|
|
1617
|
+
* - enabled=true(执行期默认):点击上传按钮时不弹系统文件框,改发 Page.fileChooserOpened 事件,
|
|
1618
|
+
* page 的 'filechooser' 监听器拿到 chooser 后用 setFiles/setInputFiles 注入文件。
|
|
1619
|
+
* - enabled=false(录制期默认):真实文件选择框正常弹出,用户手动选文件;
|
|
1620
|
+
* 前端 input[type=file] 的 change 事件由 action signal 脚本捕获记录。
|
|
1621
|
+
*
|
|
1622
|
+
* 可多次调用切换状态(CDP 协议是 stateful 的)。
|
|
1623
|
+
*/
|
|
1624
|
+
async setFileDialogInterception(enabled) {
|
|
1625
|
+
await this.conn.send("Page.setInterceptFileChooserDialog", { enabled }, this.sessionId).catch((e) => console.error("[XBPage] setInterceptFileChooserDialog failed:", errMsg(e)));
|
|
1626
|
+
}
|
|
1613
1627
|
/** Subscribe to a CDP event on this page's session. Returns unsubscribe function. */
|
|
1614
1628
|
_subscribe(event, handler) {
|
|
1615
1629
|
return this.conn.subscribe(event, this.sessionId, handler);
|
|
@@ -2310,7 +2324,7 @@ var XBBrowserImpl = class {
|
|
|
2310
2324
|
this._exitHandler = null;
|
|
2311
2325
|
}
|
|
2312
2326
|
if (this.childProcess) {
|
|
2313
|
-
const { killChrome: killChrome2 } = await import("./launcher-
|
|
2327
|
+
const { killChrome: killChrome2 } = await import("./launcher-OZXJQPNG.js");
|
|
2314
2328
|
await killChrome2(this.childProcess, this.tmpDir);
|
|
2315
2329
|
}
|
|
2316
2330
|
await this.conn.close();
|
|
@@ -2445,7 +2459,7 @@ var XBBrowserImpl = class {
|
|
|
2445
2459
|
if (pageTargets.length === 0 && httpFallbackUrl) {
|
|
2446
2460
|
console.log(`[discoverContexts] Target.getTargets returned ${targetInfos.length} targets (0 page type). Falling back to HTTP /json/list at ${httpFallbackUrl}`);
|
|
2447
2461
|
try {
|
|
2448
|
-
const { getCDPTargets: getCDPTargets2 } = await import("./launcher-
|
|
2462
|
+
const { getCDPTargets: getCDPTargets2 } = await import("./launcher-OZXJQPNG.js");
|
|
2449
2463
|
const httpPages = await getCDPTargets2(httpFallbackUrl);
|
|
2450
2464
|
console.log(`[discoverContexts] HTTP /json/list returned ${httpPages.length} pages`);
|
|
2451
2465
|
for (const p of httpPages) {
|
|
@@ -2460,7 +2474,7 @@ var XBBrowserImpl = class {
|
|
|
2460
2474
|
}
|
|
2461
2475
|
console.log(`[discoverContexts] After HTTP fallback: ${targetInfos.length} total targets, ${targetInfos.filter((t) => t.type === "page").length} pages`);
|
|
2462
2476
|
} catch (err) {
|
|
2463
|
-
console.log(`[discoverContexts] HTTP fallback failed: ${err
|
|
2477
|
+
console.log(`[discoverContexts] HTTP fallback failed: ${errMsg(err)}`);
|
|
2464
2478
|
}
|
|
2465
2479
|
}
|
|
2466
2480
|
const pagesByContext = /* @__PURE__ */ new Map();
|
|
@@ -14,14 +14,15 @@ import {
|
|
|
14
14
|
scrollIntoView,
|
|
15
15
|
waitForActionable,
|
|
16
16
|
waitForNetworkIdle
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-N2JFPWMI.js";
|
|
18
18
|
import {
|
|
19
19
|
connectToCDP,
|
|
20
20
|
findChrome,
|
|
21
21
|
getCDPTargets,
|
|
22
22
|
killChrome,
|
|
23
23
|
launchChrome
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-TNEN6VQ2.js";
|
|
25
|
+
import "./chunk-GDKLH7ZY.js";
|
|
25
26
|
import "./chunk-KFQGP6VL.js";
|
|
26
27
|
export {
|
|
27
28
|
CDPConnection,
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
errMsg
|
|
3
|
+
} from "./chunk-GDKLH7ZY.js";
|
|
4
|
+
|
|
1
5
|
// src/daemon/daemon.ts
|
|
2
6
|
import { spawn } from "child_process";
|
|
3
7
|
import { join, dirname } from "path";
|
|
@@ -170,7 +174,7 @@ async function forwardExec(command, params, session = "default", cdpEndpoint, ti
|
|
|
170
174
|
try {
|
|
171
175
|
return await rpcCall("exec", rpcParams, timeoutMs);
|
|
172
176
|
} catch (e) {
|
|
173
|
-
return { success: false, data: null, message: e
|
|
177
|
+
return { success: false, data: null, message: errMsg(e), duration: 0 };
|
|
174
178
|
}
|
|
175
179
|
}
|
|
176
180
|
async function forwardChain(input, session = "default", cdpEndpoint) {
|
|
@@ -179,7 +183,7 @@ async function forwardChain(input, session = "default", cdpEndpoint) {
|
|
|
179
183
|
try {
|
|
180
184
|
return await rpcCall("chain", params, 12e4);
|
|
181
185
|
} catch (e) {
|
|
182
|
-
return { success: false, steps: [], totalDuration: 0, stoppedReason: e
|
|
186
|
+
return { success: false, steps: [], totalDuration: 0, stoppedReason: errMsg(e) };
|
|
183
187
|
}
|
|
184
188
|
}
|
|
185
189
|
async function forwardAgentObserve(session = "default", options) {
|
|
@@ -1290,7 +1290,7 @@ var CDPInterceptorProxy = class {
|
|
|
1290
1290
|
const ctx = {
|
|
1291
1291
|
method: request.method,
|
|
1292
1292
|
params: request.params ?? {},
|
|
1293
|
-
sessionId: makeCompoundId(browserWs._cdpSession, request.sessionId),
|
|
1293
|
+
sessionId: makeCompoundId("_cdpSession" in browserWs ? browserWs._cdpSession : void 0, request.sessionId),
|
|
1294
1294
|
direction: "client\u2192browser"
|
|
1295
1295
|
};
|
|
1296
1296
|
const decision = this.engine.evaluate(ctx);
|
|
@@ -4,6 +4,13 @@ import {
|
|
|
4
4
|
|
|
5
5
|
// src/cdp-driver/launcher.ts
|
|
6
6
|
import { spawn } from "child_process";
|
|
7
|
+
|
|
8
|
+
// src/utils/error.ts
|
|
9
|
+
function errMsg(e) {
|
|
10
|
+
return e instanceof Error ? e.message : String(e);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// src/cdp-driver/launcher.ts
|
|
7
14
|
import { existsSync as fsExistsSync } from "fs";
|
|
8
15
|
var DEFAULT_CHROME_PATHS = {
|
|
9
16
|
darwin: [
|
|
@@ -146,7 +153,7 @@ async function launchChrome(options = {}) {
|
|
|
146
153
|
} catch (err) {
|
|
147
154
|
const stderr = stderrLines.slice(-20).join("\n");
|
|
148
155
|
const exitInfo = child.exitCode !== null ? ` (exit code: ${child.exitCode})` : " (still running)";
|
|
149
|
-
throw new Error(`${err
|
|
156
|
+
throw new Error(`${errMsg(err)}${exitInfo}
|
|
150
157
|
Chrome stderr:
|
|
151
158
|
${stderr || "(empty)"}`);
|
|
152
159
|
}
|
|
@@ -250,6 +257,7 @@ function sleep(ms) {
|
|
|
250
257
|
}
|
|
251
258
|
|
|
252
259
|
export {
|
|
260
|
+
errMsg,
|
|
253
261
|
DEFAULT_ARGS,
|
|
254
262
|
ANTI_DETECT_ARGS,
|
|
255
263
|
findChrome,
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
connectToCDP,
|
|
3
3
|
launchChrome
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-TNEN6VQ2.js";
|
|
5
|
+
import {
|
|
6
|
+
errMsg
|
|
7
|
+
} from "./chunk-GDKLH7ZY.js";
|
|
5
8
|
import {
|
|
6
9
|
__require
|
|
7
10
|
} from "./chunk-KFQGP6VL.js";
|
|
@@ -1203,7 +1206,7 @@ var XBPageImpl = class _XBPageImpl {
|
|
|
1203
1206
|
);
|
|
1204
1207
|
if (result) return result;
|
|
1205
1208
|
} catch (err) {
|
|
1206
|
-
lastError = err;
|
|
1209
|
+
lastError = err instanceof Error ? err : new Error(errMsg(err));
|
|
1207
1210
|
}
|
|
1208
1211
|
const pollMs = typeof polling === "number" ? polling : 16;
|
|
1209
1212
|
await this.waitForTimeout(pollMs);
|
|
@@ -1613,6 +1616,19 @@ Last error: ${lastError.message}` : "";
|
|
|
1613
1616
|
async _cdpSend(method, params) {
|
|
1614
1617
|
return this.conn.send(method, params, this.sessionId);
|
|
1615
1618
|
}
|
|
1619
|
+
/**
|
|
1620
|
+
* 开启/关闭原生文件选择框拦截(CDP stateful 开关)。
|
|
1621
|
+
*
|
|
1622
|
+
* - enabled=true(执行期默认):点击上传按钮时不弹系统文件框,改发 Page.fileChooserOpened 事件,
|
|
1623
|
+
* page 的 'filechooser' 监听器拿到 chooser 后用 setFiles/setInputFiles 注入文件。
|
|
1624
|
+
* - enabled=false(录制期默认):真实文件选择框正常弹出,用户手动选文件;
|
|
1625
|
+
* 前端 input[type=file] 的 change 事件由 action signal 脚本捕获记录。
|
|
1626
|
+
*
|
|
1627
|
+
* 可多次调用切换状态(CDP 协议是 stateful 的)。
|
|
1628
|
+
*/
|
|
1629
|
+
async setFileDialogInterception(enabled) {
|
|
1630
|
+
await this.conn.send("Page.setInterceptFileChooserDialog", { enabled }, this.sessionId).catch((e) => console.error("[XBPage] setInterceptFileChooserDialog failed:", errMsg(e)));
|
|
1631
|
+
}
|
|
1616
1632
|
/** Subscribe to a CDP event on this page's session. Returns unsubscribe function. */
|
|
1617
1633
|
_subscribe(event, handler) {
|
|
1618
1634
|
return this.conn.subscribe(event, this.sessionId, handler);
|
|
@@ -2313,7 +2329,7 @@ var XBBrowserImpl = class {
|
|
|
2313
2329
|
this._exitHandler = null;
|
|
2314
2330
|
}
|
|
2315
2331
|
if (this.childProcess) {
|
|
2316
|
-
const { killChrome: killChrome2 } = await import("./launcher-
|
|
2332
|
+
const { killChrome: killChrome2 } = await import("./launcher-L2JNDB2H.js");
|
|
2317
2333
|
await killChrome2(this.childProcess, this.tmpDir);
|
|
2318
2334
|
}
|
|
2319
2335
|
await this.conn.close();
|
|
@@ -2448,7 +2464,7 @@ var XBBrowserImpl = class {
|
|
|
2448
2464
|
if (pageTargets.length === 0 && httpFallbackUrl) {
|
|
2449
2465
|
console.log(`[discoverContexts] Target.getTargets returned ${targetInfos.length} targets (0 page type). Falling back to HTTP /json/list at ${httpFallbackUrl}`);
|
|
2450
2466
|
try {
|
|
2451
|
-
const { getCDPTargets: getCDPTargets3 } = await import("./launcher-
|
|
2467
|
+
const { getCDPTargets: getCDPTargets3 } = await import("./launcher-L2JNDB2H.js");
|
|
2452
2468
|
const httpPages = await getCDPTargets3(httpFallbackUrl);
|
|
2453
2469
|
console.log(`[discoverContexts] HTTP /json/list returned ${httpPages.length} pages`);
|
|
2454
2470
|
for (const p of httpPages) {
|
|
@@ -2463,7 +2479,7 @@ var XBBrowserImpl = class {
|
|
|
2463
2479
|
}
|
|
2464
2480
|
console.log(`[discoverContexts] After HTTP fallback: ${targetInfos.length} total targets, ${targetInfos.filter((t) => t.type === "page").length} pages`);
|
|
2465
2481
|
} catch (err) {
|
|
2466
|
-
console.log(`[discoverContexts] HTTP fallback failed: ${err
|
|
2482
|
+
console.log(`[discoverContexts] HTTP fallback failed: ${errMsg(err)}`);
|
|
2467
2483
|
}
|
|
2468
2484
|
}
|
|
2469
2485
|
const pagesByContext = /* @__PURE__ */ new Map();
|
|
@@ -4015,7 +4031,7 @@ var CDPInterceptorProxy = class {
|
|
|
4015
4031
|
const ctx = {
|
|
4016
4032
|
method: request.method,
|
|
4017
4033
|
params: request.params ?? {},
|
|
4018
|
-
sessionId: makeCompoundId(browserWs._cdpSession, request.sessionId),
|
|
4034
|
+
sessionId: makeCompoundId("_cdpSession" in browserWs ? browserWs._cdpSession : void 0, request.sessionId),
|
|
4019
4035
|
direction: "client\u2192browser"
|
|
4020
4036
|
};
|
|
4021
4037
|
const decision = this.engine.evaluate(ctx);
|
|
@@ -4283,7 +4299,7 @@ async function createBrowser(options) {
|
|
|
4283
4299
|
}
|
|
4284
4300
|
const { browser: browser2 } = await launch({ cdpEndpoint: realEndpoint });
|
|
4285
4301
|
await browser2.discoverContexts().catch((err) => {
|
|
4286
|
-
console.error(`[browser] discoverContexts failed: ${err
|
|
4302
|
+
console.error(`[browser] discoverContexts failed: ${errMsg(err)}`);
|
|
4287
4303
|
});
|
|
4288
4304
|
return browser2;
|
|
4289
4305
|
}
|
|
@@ -4434,7 +4450,7 @@ async function findOrRestoreSession(name, cdpEndpoint) {
|
|
|
4434
4450
|
await installNetworkCapture(page, name);
|
|
4435
4451
|
return session;
|
|
4436
4452
|
} catch (e) {
|
|
4437
|
-
console.error(`[Session Restore] Failed for "${name}":`, e
|
|
4453
|
+
console.error(`[Session Restore] Failed for "${name}":`, errMsg(e));
|
|
4438
4454
|
deleteSessionDiskMeta(name);
|
|
4439
4455
|
return void 0;
|
|
4440
4456
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
launch
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-N2JFPWMI.js";
|
|
4
|
+
import {
|
|
5
|
+
errMsg
|
|
6
|
+
} from "./chunk-GDKLH7ZY.js";
|
|
4
7
|
|
|
5
8
|
// src/browser.ts
|
|
6
9
|
import { randomUUID } from "crypto";
|
|
@@ -1300,7 +1303,7 @@ var CDPInterceptorProxy = class {
|
|
|
1300
1303
|
const ctx = {
|
|
1301
1304
|
method: request.method,
|
|
1302
1305
|
params: request.params ?? {},
|
|
1303
|
-
sessionId: makeCompoundId(browserWs._cdpSession, request.sessionId),
|
|
1306
|
+
sessionId: makeCompoundId("_cdpSession" in browserWs ? browserWs._cdpSession : void 0, request.sessionId),
|
|
1304
1307
|
direction: "client\u2192browser"
|
|
1305
1308
|
};
|
|
1306
1309
|
const decision = this.engine.evaluate(ctx);
|
|
@@ -1568,7 +1571,7 @@ async function createBrowser(options) {
|
|
|
1568
1571
|
}
|
|
1569
1572
|
const { browser: browser2 } = await launch({ cdpEndpoint: realEndpoint });
|
|
1570
1573
|
await browser2.discoverContexts().catch((err) => {
|
|
1571
|
-
console.error(`[browser] discoverContexts failed: ${err
|
|
1574
|
+
console.error(`[browser] discoverContexts failed: ${errMsg(err)}`);
|
|
1572
1575
|
});
|
|
1573
1576
|
return browser2;
|
|
1574
1577
|
}
|
|
@@ -1719,7 +1722,7 @@ async function findOrRestoreSession(name, cdpEndpoint) {
|
|
|
1719
1722
|
await installNetworkCapture(page, name);
|
|
1720
1723
|
return session;
|
|
1721
1724
|
} catch (e) {
|
|
1722
|
-
console.error(`[Session Restore] Failed for "${name}":`, e
|
|
1725
|
+
console.error(`[Session Restore] Failed for "${name}":`, errMsg(e));
|
|
1723
1726
|
deleteSessionDiskMeta(name);
|
|
1724
1727
|
return void 0;
|
|
1725
1728
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
connectToCDP,
|
|
3
3
|
launchChrome
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-TNEN6VQ2.js";
|
|
5
|
+
import {
|
|
6
|
+
errMsg
|
|
7
|
+
} from "./chunk-GDKLH7ZY.js";
|
|
5
8
|
import {
|
|
6
9
|
__require
|
|
7
10
|
} from "./chunk-KFQGP6VL.js";
|
|
@@ -1197,7 +1200,7 @@ var XBPageImpl = class _XBPageImpl {
|
|
|
1197
1200
|
);
|
|
1198
1201
|
if (result) return result;
|
|
1199
1202
|
} catch (err) {
|
|
1200
|
-
lastError = err;
|
|
1203
|
+
lastError = err instanceof Error ? err : new Error(errMsg(err));
|
|
1201
1204
|
}
|
|
1202
1205
|
const pollMs = typeof polling === "number" ? polling : 16;
|
|
1203
1206
|
await this.waitForTimeout(pollMs);
|
|
@@ -1607,6 +1610,19 @@ Last error: ${lastError.message}` : "";
|
|
|
1607
1610
|
async _cdpSend(method, params) {
|
|
1608
1611
|
return this.conn.send(method, params, this.sessionId);
|
|
1609
1612
|
}
|
|
1613
|
+
/**
|
|
1614
|
+
* 开启/关闭原生文件选择框拦截(CDP stateful 开关)。
|
|
1615
|
+
*
|
|
1616
|
+
* - enabled=true(执行期默认):点击上传按钮时不弹系统文件框,改发 Page.fileChooserOpened 事件,
|
|
1617
|
+
* page 的 'filechooser' 监听器拿到 chooser 后用 setFiles/setInputFiles 注入文件。
|
|
1618
|
+
* - enabled=false(录制期默认):真实文件选择框正常弹出,用户手动选文件;
|
|
1619
|
+
* 前端 input[type=file] 的 change 事件由 action signal 脚本捕获记录。
|
|
1620
|
+
*
|
|
1621
|
+
* 可多次调用切换状态(CDP 协议是 stateful 的)。
|
|
1622
|
+
*/
|
|
1623
|
+
async setFileDialogInterception(enabled) {
|
|
1624
|
+
await this.conn.send("Page.setInterceptFileChooserDialog", { enabled }, this.sessionId).catch((e) => console.error("[XBPage] setInterceptFileChooserDialog failed:", errMsg(e)));
|
|
1625
|
+
}
|
|
1610
1626
|
/** Subscribe to a CDP event on this page's session. Returns unsubscribe function. */
|
|
1611
1627
|
_subscribe(event, handler) {
|
|
1612
1628
|
return this.conn.subscribe(event, this.sessionId, handler);
|
|
@@ -2307,7 +2323,7 @@ var XBBrowserImpl = class {
|
|
|
2307
2323
|
this._exitHandler = null;
|
|
2308
2324
|
}
|
|
2309
2325
|
if (this.childProcess) {
|
|
2310
|
-
const { killChrome: killChrome2 } = await import("./launcher-
|
|
2326
|
+
const { killChrome: killChrome2 } = await import("./launcher-L2JNDB2H.js");
|
|
2311
2327
|
await killChrome2(this.childProcess, this.tmpDir);
|
|
2312
2328
|
}
|
|
2313
2329
|
await this.conn.close();
|
|
@@ -2442,7 +2458,7 @@ var XBBrowserImpl = class {
|
|
|
2442
2458
|
if (pageTargets.length === 0 && httpFallbackUrl) {
|
|
2443
2459
|
console.log(`[discoverContexts] Target.getTargets returned ${targetInfos.length} targets (0 page type). Falling back to HTTP /json/list at ${httpFallbackUrl}`);
|
|
2444
2460
|
try {
|
|
2445
|
-
const { getCDPTargets: getCDPTargets2 } = await import("./launcher-
|
|
2461
|
+
const { getCDPTargets: getCDPTargets2 } = await import("./launcher-L2JNDB2H.js");
|
|
2446
2462
|
const httpPages = await getCDPTargets2(httpFallbackUrl);
|
|
2447
2463
|
console.log(`[discoverContexts] HTTP /json/list returned ${httpPages.length} pages`);
|
|
2448
2464
|
for (const p of httpPages) {
|
|
@@ -2457,7 +2473,7 @@ var XBBrowserImpl = class {
|
|
|
2457
2473
|
}
|
|
2458
2474
|
console.log(`[discoverContexts] After HTTP fallback: ${targetInfos.length} total targets, ${targetInfos.filter((t) => t.type === "page").length} pages`);
|
|
2459
2475
|
} catch (err) {
|
|
2460
|
-
console.log(`[discoverContexts] HTTP fallback failed: ${err
|
|
2476
|
+
console.log(`[discoverContexts] HTTP fallback failed: ${errMsg(err)}`);
|
|
2461
2477
|
}
|
|
2462
2478
|
}
|
|
2463
2479
|
const pagesByContext = /* @__PURE__ */ new Map();
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
errMsg
|
|
3
|
+
} from "./chunk-GDKLH7ZY.js";
|
|
1
4
|
import {
|
|
2
5
|
__require
|
|
3
6
|
} from "./chunk-KFQGP6VL.js";
|
|
@@ -146,7 +149,7 @@ async function launchChrome(options = {}) {
|
|
|
146
149
|
} catch (err) {
|
|
147
150
|
const stderr = stderrLines.slice(-20).join("\n");
|
|
148
151
|
const exitInfo = child.exitCode !== null ? ` (exit code: ${child.exitCode})` : " (still running)";
|
|
149
|
-
throw new Error(`${err
|
|
152
|
+
throw new Error(`${errMsg(err)}${exitInfo}
|
|
150
153
|
Chrome stderr:
|
|
151
154
|
${stderr || "(empty)"}`);
|
|
152
155
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
launch
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-N2JFPWMI.js";
|
|
4
|
+
import {
|
|
5
|
+
errMsg
|
|
6
|
+
} from "./chunk-GDKLH7ZY.js";
|
|
4
7
|
import {
|
|
5
8
|
CDPInterceptorProxy
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ABXMBNQ6.js";
|
|
7
10
|
|
|
8
11
|
// src/browser.ts
|
|
9
12
|
import { randomUUID } from "crypto";
|
|
@@ -203,7 +206,7 @@ async function createBrowser(options) {
|
|
|
203
206
|
}
|
|
204
207
|
const { browser: browser2 } = await launch({ cdpEndpoint: realEndpoint });
|
|
205
208
|
await browser2.discoverContexts().catch((err) => {
|
|
206
|
-
console.error(`[browser] discoverContexts failed: ${err
|
|
209
|
+
console.error(`[browser] discoverContexts failed: ${errMsg(err)}`);
|
|
207
210
|
});
|
|
208
211
|
return browser2;
|
|
209
212
|
}
|
|
@@ -354,7 +357,7 @@ async function findOrRestoreSession(name, cdpEndpoint) {
|
|
|
354
357
|
await installNetworkCapture(page, name);
|
|
355
358
|
return session;
|
|
356
359
|
} catch (e) {
|
|
357
|
-
console.error(`[Session Restore] Failed for "${name}":`, e
|
|
360
|
+
console.error(`[Session Restore] Failed for "${name}":`, errMsg(e));
|
|
358
361
|
deleteSessionDiskMeta(name);
|
|
359
362
|
return void 0;
|
|
360
363
|
}
|