@xbrowser/cli 1.4.2 → 1.4.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-VKZVOOVV.js → browser-B5W577GO.js} +1 -1
- package/dist/{browser-WMQRPYXX.js → browser-MPMDAGZY.js} +2 -2
- package/dist/{browser-ALV2PLW4.js → browser-VWKGCFA5.js} +2 -2
- package/dist/{cdp-driver-72HOBP4C.js → cdp-driver-RCRYKHVQ.js} +1 -1
- package/dist/{cdp-driver-JZPU5YXY.js → cdp-driver-TMMK2YYE.js} +8 -8
- package/dist/{chunk-7OGKQWXE.js → chunk-J3VNBG25.js} +1 -1
- package/dist/{chunk-UZQYMXR5.js → chunk-JLSKMNMN.js} +1 -1
- package/dist/{chunk-TLOHV3FP.js → chunk-O4HCWMU2.js} +8 -8
- package/dist/{chunk-N4PIGZDG.js → chunk-WI3XE4W3.js} +8 -8
- package/dist/cli.js +24 -7
- package/dist/daemon-main.js +24 -7
- package/dist/index.d.ts +6 -20
- package/dist/index.js +25 -8
- package/dist/{session-replayer-JIVFXVUL.js → session-replayer-X3S47AA3.js} +1 -1
- package/package.json +2 -2
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
saveSessionDiskMeta,
|
|
21
21
|
setActivePage,
|
|
22
22
|
touchSession
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-JLSKMNMN.js";
|
|
24
|
+
import "./chunk-WI3XE4W3.js";
|
|
25
25
|
import "./chunk-TNEN6VQ2.js";
|
|
26
26
|
import "./chunk-GDKLH7ZY.js";
|
|
27
27
|
import "./chunk-ABXMBNQ6.js";
|
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
saveSessionDiskMeta,
|
|
21
21
|
setActivePage,
|
|
22
22
|
touchSession
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-J3VNBG25.js";
|
|
24
|
+
import "./chunk-WI3XE4W3.js";
|
|
25
25
|
import "./chunk-TNEN6VQ2.js";
|
|
26
26
|
import "./chunk-GDKLH7ZY.js";
|
|
27
27
|
import "./chunk-KFQGP6VL.js";
|
|
@@ -1629,16 +1629,16 @@ Last error: ${lastError.message}` : "";
|
|
|
1629
1629
|
const result = await this.conn.send("Page.getFrameTree", void 0, this.sessionId);
|
|
1630
1630
|
const frames = [];
|
|
1631
1631
|
const collect = (node) => {
|
|
1632
|
-
|
|
1632
|
+
const frame = {
|
|
1633
1633
|
name: () => node.frame.name || "",
|
|
1634
1634
|
url: () => node.frame.url,
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1635
|
+
isDetached: () => false,
|
|
1636
|
+
page: () => this,
|
|
1637
|
+
evaluate: (fn, ...args) => this.evaluate(fn, ...args),
|
|
1638
|
+
$: (sel) => this.$(sel),
|
|
1639
|
+
$$: (sel) => this.$$(sel)
|
|
1640
|
+
};
|
|
1641
|
+
frames.push(frame);
|
|
1642
1642
|
for (const child of node.childFrames || []) {
|
|
1643
1643
|
collect({ frame: child.frame, childFrames: [] });
|
|
1644
1644
|
}
|
|
@@ -1634,16 +1634,16 @@ Last error: ${lastError.message}` : "";
|
|
|
1634
1634
|
const result = await this.conn.send("Page.getFrameTree", void 0, this.sessionId);
|
|
1635
1635
|
const frames = [];
|
|
1636
1636
|
const collect = (node) => {
|
|
1637
|
-
|
|
1637
|
+
const frame = {
|
|
1638
1638
|
name: () => node.frame.name || "",
|
|
1639
1639
|
url: () => node.frame.url,
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1640
|
+
isDetached: () => false,
|
|
1641
|
+
page: () => this,
|
|
1642
|
+
evaluate: (fn, ...args) => this.evaluate(fn, ...args),
|
|
1643
|
+
$: (sel) => this.$(sel),
|
|
1644
|
+
$$: (sel) => this.$$(sel)
|
|
1645
|
+
};
|
|
1646
|
+
frames.push(frame);
|
|
1647
1647
|
for (const child of node.childFrames || []) {
|
|
1648
1648
|
collect({ frame: child.frame, childFrames: [] });
|
|
1649
1649
|
}
|
|
@@ -1628,16 +1628,16 @@ Last error: ${lastError.message}` : "";
|
|
|
1628
1628
|
const result = await this.conn.send("Page.getFrameTree", void 0, this.sessionId);
|
|
1629
1629
|
const frames = [];
|
|
1630
1630
|
const collect = (node) => {
|
|
1631
|
-
|
|
1631
|
+
const frame = {
|
|
1632
1632
|
name: () => node.frame.name || "",
|
|
1633
1633
|
url: () => node.frame.url,
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1634
|
+
isDetached: () => false,
|
|
1635
|
+
page: () => this,
|
|
1636
|
+
evaluate: (fn, ...args) => this.evaluate(fn, ...args),
|
|
1637
|
+
$: (sel) => this.$(sel),
|
|
1638
|
+
$$: (sel) => this.$$(sel)
|
|
1639
|
+
};
|
|
1640
|
+
frames.push(frame);
|
|
1641
1641
|
for (const child of node.childFrames || []) {
|
|
1642
1642
|
collect({ frame: child.frame, childFrames: [] });
|
|
1643
1643
|
}
|
package/dist/cli.js
CHANGED
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
resolveLaunchOpts,
|
|
26
26
|
saveSessionDiskMeta,
|
|
27
27
|
setActivePage
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-O4HCWMU2.js";
|
|
29
29
|
import "./chunk-TNEN6VQ2.js";
|
|
30
30
|
import {
|
|
31
31
|
forwardCommandLog,
|
|
@@ -2678,7 +2678,7 @@ async function discoverUrls(page, baseUrl, options) {
|
|
|
2678
2678
|
`);
|
|
2679
2679
|
const basePath = new URL(baseUrl).pathname;
|
|
2680
2680
|
let filtered = Array.from(allUrls).filter(
|
|
2681
|
-
(u) => isSameDomain(u, baseHostname, options.includeSubdomains ?? false) && isWithinPathScope(u, basePath)
|
|
2681
|
+
(u) => options.allowExternalLinks || isSameDomain(u, baseHostname, options.includeSubdomains ?? false) && isWithinPathScope(u, basePath)
|
|
2682
2682
|
);
|
|
2683
2683
|
filtered = deduplicateUrls(filtered);
|
|
2684
2684
|
if (options.search) {
|
|
@@ -2699,6 +2699,7 @@ var mapCommand = registerCommand({
|
|
|
2699
2699
|
search: z16.string().optional(),
|
|
2700
2700
|
sitemap: z16.enum(["include", "only"]).optional(),
|
|
2701
2701
|
includeSubdomains: z16.boolean().optional(),
|
|
2702
|
+
allowExternalLinks: z16.boolean().optional().describe("Include links to external domains"),
|
|
2702
2703
|
limit: z16.number().optional(),
|
|
2703
2704
|
verbose: z16.boolean().default(false).describe("Show progress feedback")
|
|
2704
2705
|
}),
|
|
@@ -2708,6 +2709,7 @@ var mapCommand = registerCommand({
|
|
|
2708
2709
|
const links = await discoverUrls(page, p.url, {
|
|
2709
2710
|
sitemap: p.sitemap,
|
|
2710
2711
|
includeSubdomains: p.includeSubdomains,
|
|
2712
|
+
allowExternalLinks: p.allowExternalLinks,
|
|
2711
2713
|
limit: p.limit,
|
|
2712
2714
|
search: p.search,
|
|
2713
2715
|
verbose: p.verbose
|
|
@@ -4892,8 +4894,23 @@ async function waitForPage(page, input) {
|
|
|
4892
4894
|
return { success: true, matched: "selector", timeout, elapsed: Date.now() - startedAt };
|
|
4893
4895
|
}
|
|
4894
4896
|
if (input.text) {
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
+
const textToFind = input.text;
|
|
4898
|
+
const matched = await pollUntil(timeout, pollInterval, async () => {
|
|
4899
|
+
return page.evaluate((text) => {
|
|
4900
|
+
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
|
|
4901
|
+
while (walker.nextNode()) {
|
|
4902
|
+
if (walker.currentNode.textContent?.includes(text)) return true;
|
|
4903
|
+
}
|
|
4904
|
+
return false;
|
|
4905
|
+
}, textToFind);
|
|
4906
|
+
});
|
|
4907
|
+
return {
|
|
4908
|
+
success: matched,
|
|
4909
|
+
matched: "text",
|
|
4910
|
+
timeout,
|
|
4911
|
+
elapsed: Date.now() - startedAt,
|
|
4912
|
+
...matched ? {} : { message: `Timed out waiting for text: ${input.text}` }
|
|
4913
|
+
};
|
|
4897
4914
|
}
|
|
4898
4915
|
if (input.url) {
|
|
4899
4916
|
const matched = await pollUntil(timeout, pollInterval, async () => matchUrlPattern(page.url(), input.url));
|
|
@@ -7058,7 +7075,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7058
7075
|
}
|
|
7059
7076
|
let targetPageOverride = null;
|
|
7060
7077
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7061
|
-
const { findTargetPage } = await import("./browser-
|
|
7078
|
+
const { findTargetPage } = await import("./browser-B5W577GO.js");
|
|
7062
7079
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7063
7080
|
if (!targetPageOverride) {
|
|
7064
7081
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -12408,7 +12425,7 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
12408
12425
|
const possibleCmd = argv[0].substring(0, spaceIdx);
|
|
12409
12426
|
if (/^[a-zA-Z][\w-]*$/.test(possibleCmd)) {
|
|
12410
12427
|
const remainder = argv[0].substring(spaceIdx + 1);
|
|
12411
|
-
if (remainder.
|
|
12428
|
+
if (remainder.includes("--")) {
|
|
12412
12429
|
const remainderParts = remainder.split(/\s+/).filter(Boolean);
|
|
12413
12430
|
argv = [possibleCmd, ...remainderParts, ...argv.slice(1)];
|
|
12414
12431
|
} else {
|
|
@@ -13024,7 +13041,7 @@ async function main() {
|
|
|
13024
13041
|
const command = process.argv[2];
|
|
13025
13042
|
const isLongRunning = command === "preview" || command === "serve";
|
|
13026
13043
|
if (!isLongRunning) {
|
|
13027
|
-
const { ensureProcessCanExit } = await import("./browser-
|
|
13044
|
+
const { ensureProcessCanExit } = await import("./browser-B5W577GO.js");
|
|
13028
13045
|
await ensureProcessCanExit().catch(() => {
|
|
13029
13046
|
});
|
|
13030
13047
|
process.exit(exitCode);
|
package/dist/daemon-main.js
CHANGED
|
@@ -21,8 +21,8 @@ import {
|
|
|
21
21
|
resolveLaunchOpts,
|
|
22
22
|
saveSessionDiskMeta,
|
|
23
23
|
setActivePage
|
|
24
|
-
} from "./chunk-
|
|
25
|
-
import "./chunk-
|
|
24
|
+
} from "./chunk-J3VNBG25.js";
|
|
25
|
+
import "./chunk-WI3XE4W3.js";
|
|
26
26
|
import "./chunk-TNEN6VQ2.js";
|
|
27
27
|
import {
|
|
28
28
|
getPluginLoader
|
|
@@ -2639,7 +2639,7 @@ async function discoverUrls(page, baseUrl, options) {
|
|
|
2639
2639
|
`);
|
|
2640
2640
|
const basePath = new URL(baseUrl).pathname;
|
|
2641
2641
|
let filtered = Array.from(allUrls).filter(
|
|
2642
|
-
(u) => isSameDomain(u, baseHostname, options.includeSubdomains ?? false) && isWithinPathScope(u, basePath)
|
|
2642
|
+
(u) => options.allowExternalLinks || isSameDomain(u, baseHostname, options.includeSubdomains ?? false) && isWithinPathScope(u, basePath)
|
|
2643
2643
|
);
|
|
2644
2644
|
filtered = deduplicateUrls(filtered);
|
|
2645
2645
|
if (options.search) {
|
|
@@ -2660,6 +2660,7 @@ var mapCommand = registerCommand({
|
|
|
2660
2660
|
search: z16.string().optional(),
|
|
2661
2661
|
sitemap: z16.enum(["include", "only"]).optional(),
|
|
2662
2662
|
includeSubdomains: z16.boolean().optional(),
|
|
2663
|
+
allowExternalLinks: z16.boolean().optional().describe("Include links to external domains"),
|
|
2663
2664
|
limit: z16.number().optional(),
|
|
2664
2665
|
verbose: z16.boolean().default(false).describe("Show progress feedback")
|
|
2665
2666
|
}),
|
|
@@ -2669,6 +2670,7 @@ var mapCommand = registerCommand({
|
|
|
2669
2670
|
const links = await discoverUrls(page, p.url, {
|
|
2670
2671
|
sitemap: p.sitemap,
|
|
2671
2672
|
includeSubdomains: p.includeSubdomains,
|
|
2673
|
+
allowExternalLinks: p.allowExternalLinks,
|
|
2672
2674
|
limit: p.limit,
|
|
2673
2675
|
search: p.search,
|
|
2674
2676
|
verbose: p.verbose
|
|
@@ -4853,8 +4855,23 @@ async function waitForPage(page, input) {
|
|
|
4853
4855
|
return { success: true, matched: "selector", timeout, elapsed: Date.now() - startedAt };
|
|
4854
4856
|
}
|
|
4855
4857
|
if (input.text) {
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
+
const textToFind = input.text;
|
|
4859
|
+
const matched = await pollUntil(timeout, pollInterval, async () => {
|
|
4860
|
+
return page.evaluate((text) => {
|
|
4861
|
+
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
|
|
4862
|
+
while (walker.nextNode()) {
|
|
4863
|
+
if (walker.currentNode.textContent?.includes(text)) return true;
|
|
4864
|
+
}
|
|
4865
|
+
return false;
|
|
4866
|
+
}, textToFind);
|
|
4867
|
+
});
|
|
4868
|
+
return {
|
|
4869
|
+
success: matched,
|
|
4870
|
+
matched: "text",
|
|
4871
|
+
timeout,
|
|
4872
|
+
elapsed: Date.now() - startedAt,
|
|
4873
|
+
...matched ? {} : { message: `Timed out waiting for text: ${input.text}` }
|
|
4874
|
+
};
|
|
4858
4875
|
}
|
|
4859
4876
|
if (input.url) {
|
|
4860
4877
|
const matched = await pollUntil(timeout, pollInterval, async () => matchUrlPattern(page.url(), input.url));
|
|
@@ -6589,7 +6606,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
6589
6606
|
}
|
|
6590
6607
|
let targetPageOverride = null;
|
|
6591
6608
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
6592
|
-
const { findTargetPage } = await import("./browser-
|
|
6609
|
+
const { findTargetPage } = await import("./browser-VWKGCFA5.js");
|
|
6593
6610
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
6594
6611
|
if (!targetPageOverride) {
|
|
6595
6612
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -8305,7 +8322,7 @@ function createRPCHandler() {
|
|
|
8305
8322
|
const isNewFormat = Array.isArray(parsed.actions);
|
|
8306
8323
|
if (isNewFormat) {
|
|
8307
8324
|
try {
|
|
8308
|
-
const { SessionReplayer } = await import("./session-replayer-
|
|
8325
|
+
const { SessionReplayer } = await import("./session-replayer-X3S47AA3.js");
|
|
8309
8326
|
const replayer = new SessionReplayer({
|
|
8310
8327
|
page: session.page,
|
|
8311
8328
|
stepDelay: slowMo * 500,
|
package/dist/index.d.ts
CHANGED
|
@@ -172,6 +172,7 @@ interface XBPage {
|
|
|
172
172
|
height: number;
|
|
173
173
|
}): Promise<void>;
|
|
174
174
|
addInitScript(script: string): Promise<void>;
|
|
175
|
+
discoverFrames(): Promise<XBFrame[]>;
|
|
175
176
|
bringToFront(): Promise<void>;
|
|
176
177
|
setExtraHTTPHeaders(headers: Record<string, string>): Promise<void>;
|
|
177
178
|
setOfflineMode(offline: boolean): Promise<void>;
|
|
@@ -1606,6 +1607,10 @@ declare class RecorderController {
|
|
|
1606
1607
|
private getDefaultOutputPath;
|
|
1607
1608
|
}
|
|
1608
1609
|
|
|
1610
|
+
/**
|
|
1611
|
+
* Recording-related type definitions.
|
|
1612
|
+
* Extracted from session-recorder.ts to keep the main file focused on logic.
|
|
1613
|
+
*/
|
|
1609
1614
|
interface ClickContextItem {
|
|
1610
1615
|
text: string;
|
|
1611
1616
|
tag?: string;
|
|
@@ -1650,17 +1655,13 @@ interface UserAction {
|
|
|
1650
1655
|
tag: string;
|
|
1651
1656
|
selector?: string;
|
|
1652
1657
|
text: string;
|
|
1653
|
-
/** Which strategy from generateUniqueSelector produced this selector */
|
|
1654
1658
|
strategy?: string;
|
|
1655
|
-
/** Reliability rating from generateUniqueSelector: high / medium / low */
|
|
1656
1659
|
confidence?: 'high' | 'medium' | 'low';
|
|
1657
|
-
/** Text-based fallback for low-confidence selectors (e.g. menu items) */
|
|
1658
1660
|
textFallback?: {
|
|
1659
1661
|
type: 'text';
|
|
1660
1662
|
value: string;
|
|
1661
1663
|
selector: string;
|
|
1662
1664
|
};
|
|
1663
|
-
/** Popup/menu context when element is inside a dropdown */
|
|
1664
1665
|
popup?: {
|
|
1665
1666
|
containerSelector: string;
|
|
1666
1667
|
containerText: string;
|
|
@@ -1677,9 +1678,7 @@ interface UserAction {
|
|
|
1677
1678
|
y?: number;
|
|
1678
1679
|
scrollX?: number;
|
|
1679
1680
|
scrollY?: number;
|
|
1680
|
-
/** Click context: popover/dropdown/menu items captured 200ms after click */
|
|
1681
1681
|
clickContext?: ClickContext;
|
|
1682
|
-
/** File upload info (type=filechooser only) */
|
|
1683
1682
|
files?: {
|
|
1684
1683
|
names: string[];
|
|
1685
1684
|
count: number;
|
|
@@ -1691,36 +1690,30 @@ interface UserAction {
|
|
|
1691
1690
|
dataUrl: string | null;
|
|
1692
1691
|
}>;
|
|
1693
1692
|
};
|
|
1694
|
-
/** Drag & drop info (type=drag only) */
|
|
1695
1693
|
drag?: {
|
|
1696
1694
|
fromX: number;
|
|
1697
1695
|
fromY: number;
|
|
1698
1696
|
toX: number;
|
|
1699
1697
|
toY: number;
|
|
1700
|
-
/** Source element description */
|
|
1701
1698
|
source?: {
|
|
1702
1699
|
tag: string;
|
|
1703
1700
|
selector?: string;
|
|
1704
1701
|
text: string;
|
|
1705
1702
|
};
|
|
1706
|
-
/** Target (drop zone) element description */
|
|
1707
1703
|
target?: {
|
|
1708
1704
|
tag: string;
|
|
1709
1705
|
selector?: string;
|
|
1710
1706
|
text: string;
|
|
1711
1707
|
};
|
|
1712
1708
|
};
|
|
1713
|
-
/** Resize info (type=resize only) */
|
|
1714
1709
|
resize?: {
|
|
1715
1710
|
width: number;
|
|
1716
1711
|
height: number;
|
|
1717
1712
|
};
|
|
1718
|
-
/** Clipboard info (type=clipboard only) */
|
|
1719
1713
|
clipboard?: {
|
|
1720
1714
|
operation: 'copy' | 'paste' | 'cut';
|
|
1721
1715
|
textPreview?: string;
|
|
1722
1716
|
};
|
|
1723
|
-
/** Touch info (type=touch only) */
|
|
1724
1717
|
touch?: {
|
|
1725
1718
|
touchType: 'start' | 'move' | 'end';
|
|
1726
1719
|
touches: Array<{
|
|
@@ -1728,26 +1721,19 @@ interface UserAction {
|
|
|
1728
1721
|
y: number;
|
|
1729
1722
|
}>;
|
|
1730
1723
|
};
|
|
1731
|
-
/** Focus info (type=focus only) */
|
|
1732
1724
|
focus?: {
|
|
1733
1725
|
focusType: 'focus' | 'blur';
|
|
1734
1726
|
};
|
|
1735
|
-
/** Visibility info (type=visibility only) */
|
|
1736
1727
|
visibility?: {
|
|
1737
1728
|
state: 'visible' | 'hidden';
|
|
1738
1729
|
};
|
|
1739
|
-
/** Mouse trajectory from previous action's position to this action's position.
|
|
1740
|
-
* Captured as simplified waypoints with relative timestamps for realistic replay. */
|
|
1741
1730
|
trajectory?: {
|
|
1742
|
-
/** Waypoints: [x, y, deltaMs from previous point] */
|
|
1743
1731
|
points: Array<{
|
|
1744
1732
|
x: number;
|
|
1745
1733
|
y: number;
|
|
1746
1734
|
dt: number;
|
|
1747
1735
|
}>;
|
|
1748
|
-
/** Total distance in pixels (approximate) */
|
|
1749
1736
|
distance: number;
|
|
1750
|
-
/** Total duration in ms */
|
|
1751
1737
|
duration: number;
|
|
1752
1738
|
};
|
|
1753
1739
|
}
|
|
@@ -1825,13 +1811,13 @@ interface RecordingData {
|
|
|
1825
1811
|
contextChanges: ContextChange[];
|
|
1826
1812
|
checkpoints: CheckpointEntry[];
|
|
1827
1813
|
}
|
|
1828
|
-
/** Written to disk so `record stop` (separate process) can signal the recorder. */
|
|
1829
1814
|
interface RecordingControlFile {
|
|
1830
1815
|
pid: number;
|
|
1831
1816
|
startedAt: string;
|
|
1832
1817
|
startUrl: string;
|
|
1833
1818
|
sessionName: string;
|
|
1834
1819
|
}
|
|
1820
|
+
|
|
1835
1821
|
declare class SessionRecorder {
|
|
1836
1822
|
private context;
|
|
1837
1823
|
private page;
|
package/dist/index.js
CHANGED
|
@@ -81,8 +81,8 @@ import {
|
|
|
81
81
|
resolveLaunchOpts,
|
|
82
82
|
saveSessionDiskMeta,
|
|
83
83
|
setActivePage
|
|
84
|
-
} from "./chunk-
|
|
85
|
-
import "./chunk-
|
|
84
|
+
} from "./chunk-JLSKMNMN.js";
|
|
85
|
+
import "./chunk-WI3XE4W3.js";
|
|
86
86
|
import "./chunk-TNEN6VQ2.js";
|
|
87
87
|
import {
|
|
88
88
|
errMsg
|
|
@@ -2718,7 +2718,7 @@ async function discoverUrls(page, baseUrl, options) {
|
|
|
2718
2718
|
`);
|
|
2719
2719
|
const basePath = new URL(baseUrl).pathname;
|
|
2720
2720
|
let filtered = Array.from(allUrls).filter(
|
|
2721
|
-
(u) => isSameDomain(u, baseHostname, options.includeSubdomains ?? false) && isWithinPathScope(u, basePath)
|
|
2721
|
+
(u) => options.allowExternalLinks || isSameDomain(u, baseHostname, options.includeSubdomains ?? false) && isWithinPathScope(u, basePath)
|
|
2722
2722
|
);
|
|
2723
2723
|
filtered = deduplicateUrls(filtered);
|
|
2724
2724
|
if (options.search) {
|
|
@@ -2739,6 +2739,7 @@ var mapCommand = registerCommand({
|
|
|
2739
2739
|
search: z16.string().optional(),
|
|
2740
2740
|
sitemap: z16.enum(["include", "only"]).optional(),
|
|
2741
2741
|
includeSubdomains: z16.boolean().optional(),
|
|
2742
|
+
allowExternalLinks: z16.boolean().optional().describe("Include links to external domains"),
|
|
2742
2743
|
limit: z16.number().optional(),
|
|
2743
2744
|
verbose: z16.boolean().default(false).describe("Show progress feedback")
|
|
2744
2745
|
}),
|
|
@@ -2748,6 +2749,7 @@ var mapCommand = registerCommand({
|
|
|
2748
2749
|
const links = await discoverUrls(page, p.url, {
|
|
2749
2750
|
sitemap: p.sitemap,
|
|
2750
2751
|
includeSubdomains: p.includeSubdomains,
|
|
2752
|
+
allowExternalLinks: p.allowExternalLinks,
|
|
2751
2753
|
limit: p.limit,
|
|
2752
2754
|
search: p.search,
|
|
2753
2755
|
verbose: p.verbose
|
|
@@ -5209,8 +5211,23 @@ async function waitForPage(page, input) {
|
|
|
5209
5211
|
return { success: true, matched: "selector", timeout, elapsed: Date.now() - startedAt };
|
|
5210
5212
|
}
|
|
5211
5213
|
if (input.text) {
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
+
const textToFind = input.text;
|
|
5215
|
+
const matched = await pollUntil(timeout, pollInterval, async () => {
|
|
5216
|
+
return page.evaluate((text) => {
|
|
5217
|
+
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
|
|
5218
|
+
while (walker.nextNode()) {
|
|
5219
|
+
if (walker.currentNode.textContent?.includes(text)) return true;
|
|
5220
|
+
}
|
|
5221
|
+
return false;
|
|
5222
|
+
}, textToFind);
|
|
5223
|
+
});
|
|
5224
|
+
return {
|
|
5225
|
+
success: matched,
|
|
5226
|
+
matched: "text",
|
|
5227
|
+
timeout,
|
|
5228
|
+
elapsed: Date.now() - startedAt,
|
|
5229
|
+
...matched ? {} : { message: `Timed out waiting for text: ${input.text}` }
|
|
5230
|
+
};
|
|
5214
5231
|
}
|
|
5215
5232
|
if (input.url) {
|
|
5216
5233
|
const matched = await pollUntil(timeout, pollInterval, async () => matchUrlPattern(page.url(), input.url));
|
|
@@ -7378,7 +7395,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7378
7395
|
}
|
|
7379
7396
|
let targetPageOverride = null;
|
|
7380
7397
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7381
|
-
const { findTargetPage } = await import("./browser-
|
|
7398
|
+
const { findTargetPage } = await import("./browser-MPMDAGZY.js");
|
|
7382
7399
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7383
7400
|
if (!targetPageOverride) {
|
|
7384
7401
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -12748,7 +12765,7 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
12748
12765
|
const possibleCmd = argv[0].substring(0, spaceIdx);
|
|
12749
12766
|
if (/^[a-zA-Z][\w-]*$/.test(possibleCmd)) {
|
|
12750
12767
|
const remainder = argv[0].substring(spaceIdx + 1);
|
|
12751
|
-
if (remainder.
|
|
12768
|
+
if (remainder.includes("--")) {
|
|
12752
12769
|
const remainderParts = remainder.split(/\s+/).filter(Boolean);
|
|
12753
12770
|
argv = [possibleCmd, ...remainderParts, ...argv.slice(1)];
|
|
12754
12771
|
} else {
|
|
@@ -16151,7 +16168,7 @@ var DataCollector = class {
|
|
|
16151
16168
|
return results;
|
|
16152
16169
|
}
|
|
16153
16170
|
async createBrowserContext() {
|
|
16154
|
-
const { launch } = await import("./cdp-driver-
|
|
16171
|
+
const { launch } = await import("./cdp-driver-RCRYKHVQ.js");
|
|
16155
16172
|
const { browser } = await launch({
|
|
16156
16173
|
headless: true,
|
|
16157
16174
|
args: ["--no-sandbox", "--disable-setuid-sandbox"]
|
|
@@ -31,7 +31,7 @@ var SessionReplayer = class {
|
|
|
31
31
|
if (this.opts.page) {
|
|
32
32
|
this.page = this.opts.page;
|
|
33
33
|
} else if (this.opts.cdpUrl) {
|
|
34
|
-
const { launch } = await import("./cdp-driver-
|
|
34
|
+
const { launch } = await import("./cdp-driver-RCRYKHVQ.js");
|
|
35
35
|
const { browser } = await launch({ cdpEndpoint: this.opts.cdpUrl });
|
|
36
36
|
let contexts = browser.contexts();
|
|
37
37
|
for (let i = 0; i < 10 && contexts.length === 0; i++) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xbrowser/cli",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
4
4
|
"description": "Browser automation CLI for web scraping, headless browsing, SEO analysis, and AI agent workflows. A command-line alternative to Playwright, Puppeteer, and Selenium.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -122,6 +122,6 @@
|
|
|
122
122
|
]
|
|
123
123
|
},
|
|
124
124
|
"optionalDependencies": {
|
|
125
|
-
"undici": "^7.
|
|
125
|
+
"undici": "^7.28.0"
|
|
126
126
|
}
|
|
127
127
|
}
|