@xbrowser/cli 1.8.4 → 1.8.6
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-4PIVOYCW.js → browser-LW2MDJE4.js} +1 -1
- package/dist/{browser-RJIRI2H5.js → browser-TLIDFFEG.js} +1 -1
- package/dist/{browser-KVTJQKBA.js → browser-XPKM344Y.js} +1 -1
- package/dist/{chunk-IGWWPMEQ.js → chunk-CJJ564VK.js} +1 -1
- package/dist/{chunk-2SVQTI2O.js → chunk-FL6DOSWV.js} +48 -20
- package/dist/{chunk-6QGZN5U7.js → chunk-HXLMMSU3.js} +1 -1
- package/dist/{chunk-ACFE6PKF.js → chunk-RMYEHTLS.js} +48 -20
- package/dist/{chunk-35DOHDTA.js → chunk-SJLRCE6N.js} +1 -1
- package/dist/cli.js +177 -75
- package/dist/daemon-main.js +29 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +176 -74
- package/dist/{session-recorder-RTDGURIJ.js → session-recorder-33UKWCIR.js} +1 -1
- package/dist/{session-recorder-YI7YYM36.js → session-recorder-BMIJ3ZJM.js} +1 -1
- package/package.json +2 -2
|
@@ -656,7 +656,7 @@ async function closeSessionByName(name) {
|
|
|
656
656
|
} catch {
|
|
657
657
|
}
|
|
658
658
|
try {
|
|
659
|
-
const { SessionRecorder } = await import("./session-recorder-
|
|
659
|
+
const { SessionRecorder } = await import("./session-recorder-33UKWCIR.js");
|
|
660
660
|
SessionRecorder.cleanup(session.name);
|
|
661
661
|
} catch {
|
|
662
662
|
}
|
|
@@ -1725,6 +1725,16 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1725
1725
|
await this.page.addInitScript(getSelectorGeneratorScript());
|
|
1726
1726
|
await this.page.addInitScript(ACTION_SIGNAL_SCRIPT);
|
|
1727
1727
|
await this.page.addInitScript(CHECKPOINT_OVERLAY_SCRIPT);
|
|
1728
|
+
this.context.on("request", this.handleRequest);
|
|
1729
|
+
this.context.on("response", this.handleResponse);
|
|
1730
|
+
this.context.on("page", this.handleNewPage);
|
|
1731
|
+
for (const p of this.context.pages()) {
|
|
1732
|
+
p.on("request", this.handleRequest);
|
|
1733
|
+
p.on("response", this.handleResponse);
|
|
1734
|
+
}
|
|
1735
|
+
this.page.on("framenavigated", this.handleFrameNavigated);
|
|
1736
|
+
this.page.on("dialog", this.handleDialog);
|
|
1737
|
+
this.page.on("filechooser", this.handleFileChooser);
|
|
1728
1738
|
if (url) {
|
|
1729
1739
|
await this.page.goto(url, { waitUntil: "domcontentloaded", timeout: 3e4 });
|
|
1730
1740
|
this.startUrl = url;
|
|
@@ -1740,17 +1750,7 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1740
1750
|
};
|
|
1741
1751
|
writeFileSync2(this.controlFilePath, JSON.stringify(control, null, 2), "utf-8");
|
|
1742
1752
|
await this.injectActionScript(this.page);
|
|
1743
|
-
this.context.on("request", this.handleRequest);
|
|
1744
|
-
this.context.on("response", this.handleResponse);
|
|
1745
|
-
this.context.on("page", this.handleNewPage);
|
|
1746
|
-
for (const p of this.context.pages()) {
|
|
1747
|
-
p.on("request", this.handleRequest);
|
|
1748
|
-
p.on("response", this.handleResponse);
|
|
1749
|
-
}
|
|
1750
1753
|
this.context.on("page", this.handleNewPage);
|
|
1751
|
-
this.page.on("framenavigated", this.handleFrameNavigated);
|
|
1752
|
-
this.page.on("dialog", this.handleDialog);
|
|
1753
|
-
this.page.on("filechooser", this.handleFileChooser);
|
|
1754
1754
|
this.pollTimer = setInterval(() => void this.pollActions(), 200);
|
|
1755
1755
|
this.flushTimer = setInterval(() => this.flushToDisk(), 5e3);
|
|
1756
1756
|
}
|
|
@@ -1891,15 +1891,37 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1891
1891
|
}
|
|
1892
1892
|
// ==================== Private ====================
|
|
1893
1893
|
async injectActionScript(page) {
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1894
|
+
let success = false;
|
|
1895
|
+
const maxAttempts = 3;
|
|
1896
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1897
|
+
try {
|
|
1898
|
+
await page.evaluate(getSelectorGeneratorScript());
|
|
1899
|
+
await page.evaluate(ACTION_SIGNAL_SCRIPT);
|
|
1900
|
+
await page.evaluate(`window.__xb_action_script_src = ${JSON.stringify(ACTION_SIGNAL_SCRIPT)};`);
|
|
1901
|
+
const injected = await page.evaluate(`(function() {
|
|
1902
|
+
try { return !!window.__xb_action_signal; } catch(e) { return false; }
|
|
1903
|
+
})()`).catch(() => false);
|
|
1904
|
+
if (injected) {
|
|
1905
|
+
success = true;
|
|
1906
|
+
break;
|
|
1907
|
+
}
|
|
1908
|
+
console.error(`[recorder] Action signal injection verification failed (attempt ${attempt}/${maxAttempts})`);
|
|
1909
|
+
} catch (e) {
|
|
1910
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
1911
|
+
console.error(`[recorder] Action signal injection error (attempt ${attempt}/${maxAttempts}): ${msg}`);
|
|
1912
|
+
}
|
|
1913
|
+
if (attempt < maxAttempts) {
|
|
1914
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
if (!success) {
|
|
1918
|
+
console.error(`[recorder] WARNING: Action signal injection FAILED after ${maxAttempts} attempts. User actions will NOT be recorded. Check that the page supports Runtime.evaluate.`);
|
|
1899
1919
|
}
|
|
1900
1920
|
try {
|
|
1901
1921
|
await page.evaluate(CHECKPOINT_OVERLAY_SCRIPT);
|
|
1902
|
-
} catch {
|
|
1922
|
+
} catch (e) {
|
|
1923
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
1924
|
+
console.error(`[recorder] Checkpoint overlay injection failed (non-fatal): ${msg}`);
|
|
1903
1925
|
}
|
|
1904
1926
|
try {
|
|
1905
1927
|
await page.evaluate(`
|
|
@@ -2051,7 +2073,11 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
2051
2073
|
await this.injectActionScript(page);
|
|
2052
2074
|
return;
|
|
2053
2075
|
}
|
|
2054
|
-
} catch {
|
|
2076
|
+
} catch (e) {
|
|
2077
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
2078
|
+
if (attempt < 4) {
|
|
2079
|
+
console.error(`[recorder] injectActionScript retry ${attempt + 1}/5 failed: ${msg}`);
|
|
2080
|
+
}
|
|
2055
2081
|
}
|
|
2056
2082
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
2057
2083
|
}
|
|
@@ -2066,18 +2092,20 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
2066
2092
|
this.activePages.delete(page);
|
|
2067
2093
|
});
|
|
2068
2094
|
page.on("framenavigated", async (frame) => {
|
|
2069
|
-
if (frame
|
|
2095
|
+
if (frame.isDetached()) return;
|
|
2070
2096
|
const url = frame.url();
|
|
2071
2097
|
if (url && url !== "about:blank" && !url.startsWith("chrome")) {
|
|
2072
2098
|
try {
|
|
2073
2099
|
await this.injectActionScript(page);
|
|
2074
|
-
} catch {
|
|
2100
|
+
} catch (e) {
|
|
2101
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
2102
|
+
console.error(`[recorder] injectActionScript after navigation failed: ${msg}`);
|
|
2075
2103
|
}
|
|
2076
2104
|
}
|
|
2077
2105
|
});
|
|
2078
2106
|
};
|
|
2079
2107
|
handleFrameNavigated = (frame) => {
|
|
2080
|
-
if (frame
|
|
2108
|
+
if (frame.isDetached()) return;
|
|
2081
2109
|
const newUrl = frame.url();
|
|
2082
2110
|
this.contextCounter++;
|
|
2083
2111
|
this.contextChanges.push({
|
|
@@ -2021,7 +2021,7 @@ async function closeSessionByName(name) {
|
|
|
2021
2021
|
} catch {
|
|
2022
2022
|
}
|
|
2023
2023
|
try {
|
|
2024
|
-
const { SessionRecorder } = await import("./session-recorder-
|
|
2024
|
+
const { SessionRecorder } = await import("./session-recorder-BMIJ3ZJM.js");
|
|
2025
2025
|
SessionRecorder.cleanup(session.name);
|
|
2026
2026
|
} catch {
|
|
2027
2027
|
}
|
|
@@ -1328,6 +1328,16 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1328
1328
|
await this.page.addInitScript(getSelectorGeneratorScript());
|
|
1329
1329
|
await this.page.addInitScript(ACTION_SIGNAL_SCRIPT);
|
|
1330
1330
|
await this.page.addInitScript(CHECKPOINT_OVERLAY_SCRIPT);
|
|
1331
|
+
this.context.on("request", this.handleRequest);
|
|
1332
|
+
this.context.on("response", this.handleResponse);
|
|
1333
|
+
this.context.on("page", this.handleNewPage);
|
|
1334
|
+
for (const p of this.context.pages()) {
|
|
1335
|
+
p.on("request", this.handleRequest);
|
|
1336
|
+
p.on("response", this.handleResponse);
|
|
1337
|
+
}
|
|
1338
|
+
this.page.on("framenavigated", this.handleFrameNavigated);
|
|
1339
|
+
this.page.on("dialog", this.handleDialog);
|
|
1340
|
+
this.page.on("filechooser", this.handleFileChooser);
|
|
1331
1341
|
if (url) {
|
|
1332
1342
|
await this.page.goto(url, { waitUntil: "domcontentloaded", timeout: 3e4 });
|
|
1333
1343
|
this.startUrl = url;
|
|
@@ -1343,17 +1353,7 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1343
1353
|
};
|
|
1344
1354
|
writeFileSync(this.controlFilePath, JSON.stringify(control, null, 2), "utf-8");
|
|
1345
1355
|
await this.injectActionScript(this.page);
|
|
1346
|
-
this.context.on("request", this.handleRequest);
|
|
1347
|
-
this.context.on("response", this.handleResponse);
|
|
1348
|
-
this.context.on("page", this.handleNewPage);
|
|
1349
|
-
for (const p of this.context.pages()) {
|
|
1350
|
-
p.on("request", this.handleRequest);
|
|
1351
|
-
p.on("response", this.handleResponse);
|
|
1352
|
-
}
|
|
1353
1356
|
this.context.on("page", this.handleNewPage);
|
|
1354
|
-
this.page.on("framenavigated", this.handleFrameNavigated);
|
|
1355
|
-
this.page.on("dialog", this.handleDialog);
|
|
1356
|
-
this.page.on("filechooser", this.handleFileChooser);
|
|
1357
1357
|
this.pollTimer = setInterval(() => void this.pollActions(), 200);
|
|
1358
1358
|
this.flushTimer = setInterval(() => this.flushToDisk(), 5e3);
|
|
1359
1359
|
}
|
|
@@ -1494,15 +1494,37 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1494
1494
|
}
|
|
1495
1495
|
// ==================== Private ====================
|
|
1496
1496
|
async injectActionScript(page) {
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1497
|
+
let success = false;
|
|
1498
|
+
const maxAttempts = 3;
|
|
1499
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1500
|
+
try {
|
|
1501
|
+
await page.evaluate(getSelectorGeneratorScript());
|
|
1502
|
+
await page.evaluate(ACTION_SIGNAL_SCRIPT);
|
|
1503
|
+
await page.evaluate(`window.__xb_action_script_src = ${JSON.stringify(ACTION_SIGNAL_SCRIPT)};`);
|
|
1504
|
+
const injected = await page.evaluate(`(function() {
|
|
1505
|
+
try { return !!window.__xb_action_signal; } catch(e) { return false; }
|
|
1506
|
+
})()`).catch(() => false);
|
|
1507
|
+
if (injected) {
|
|
1508
|
+
success = true;
|
|
1509
|
+
break;
|
|
1510
|
+
}
|
|
1511
|
+
console.error(`[recorder] Action signal injection verification failed (attempt ${attempt}/${maxAttempts})`);
|
|
1512
|
+
} catch (e) {
|
|
1513
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
1514
|
+
console.error(`[recorder] Action signal injection error (attempt ${attempt}/${maxAttempts}): ${msg}`);
|
|
1515
|
+
}
|
|
1516
|
+
if (attempt < maxAttempts) {
|
|
1517
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
if (!success) {
|
|
1521
|
+
console.error(`[recorder] WARNING: Action signal injection FAILED after ${maxAttempts} attempts. User actions will NOT be recorded. Check that the page supports Runtime.evaluate.`);
|
|
1502
1522
|
}
|
|
1503
1523
|
try {
|
|
1504
1524
|
await page.evaluate(CHECKPOINT_OVERLAY_SCRIPT);
|
|
1505
|
-
} catch {
|
|
1525
|
+
} catch (e) {
|
|
1526
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
1527
|
+
console.error(`[recorder] Checkpoint overlay injection failed (non-fatal): ${msg}`);
|
|
1506
1528
|
}
|
|
1507
1529
|
try {
|
|
1508
1530
|
await page.evaluate(`
|
|
@@ -1654,7 +1676,11 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1654
1676
|
await this.injectActionScript(page);
|
|
1655
1677
|
return;
|
|
1656
1678
|
}
|
|
1657
|
-
} catch {
|
|
1679
|
+
} catch (e) {
|
|
1680
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
1681
|
+
if (attempt < 4) {
|
|
1682
|
+
console.error(`[recorder] injectActionScript retry ${attempt + 1}/5 failed: ${msg}`);
|
|
1683
|
+
}
|
|
1658
1684
|
}
|
|
1659
1685
|
await new Promise((r) => setTimeout(r, 1e3));
|
|
1660
1686
|
}
|
|
@@ -1669,18 +1695,20 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1669
1695
|
this.activePages.delete(page);
|
|
1670
1696
|
});
|
|
1671
1697
|
page.on("framenavigated", async (frame) => {
|
|
1672
|
-
if (frame
|
|
1698
|
+
if (frame.isDetached()) return;
|
|
1673
1699
|
const url = frame.url();
|
|
1674
1700
|
if (url && url !== "about:blank" && !url.startsWith("chrome")) {
|
|
1675
1701
|
try {
|
|
1676
1702
|
await this.injectActionScript(page);
|
|
1677
|
-
} catch {
|
|
1703
|
+
} catch (e) {
|
|
1704
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
1705
|
+
console.error(`[recorder] injectActionScript after navigation failed: ${msg}`);
|
|
1678
1706
|
}
|
|
1679
1707
|
}
|
|
1680
1708
|
});
|
|
1681
1709
|
};
|
|
1682
1710
|
handleFrameNavigated = (frame) => {
|
|
1683
|
-
if (frame
|
|
1711
|
+
if (frame.isDetached()) return;
|
|
1684
1712
|
const newUrl = frame.url();
|
|
1685
1713
|
this.contextCounter++;
|
|
1686
1714
|
this.contextChanges.push({
|
|
@@ -4965,7 +4965,7 @@ async function closeSessionByName(name) {
|
|
|
4965
4965
|
} catch {
|
|
4966
4966
|
}
|
|
4967
4967
|
try {
|
|
4968
|
-
const { SessionRecorder } = await import("./session-recorder-
|
|
4968
|
+
const { SessionRecorder } = await import("./session-recorder-33UKWCIR.js");
|
|
4969
4969
|
SessionRecorder.cleanup(session.name);
|
|
4970
4970
|
} catch {
|
|
4971
4971
|
}
|