@xbrowser/cli 1.4.7 → 1.5.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/dist/{browser-SOML2EWR.js → browser-2FJ4OO4H.js} +1 -1
- package/dist/{browser-2OK26HBS.js → browser-IS6DTR5Y.js} +2 -2
- package/dist/{browser-ZTTS2SVT.js → browser-ZFW2XADE.js} +2 -2
- package/dist/{cdp-driver-67B5EI4C.js → cdp-driver-MR6OG3YF.js} +62 -8
- package/dist/{cdp-driver-UGO45HXR.js → cdp-driver-QHTXQRQ2.js} +1 -1
- package/dist/{chunk-2RHJEYWU.js → chunk-74QM55TC.js} +62 -8
- package/dist/{chunk-RGS6ECTH.js → chunk-H7R352A2.js} +62 -8
- package/dist/{chunk-LYVU6SD3.js → chunk-MKEAO3XJ.js} +1 -1
- package/dist/{chunk-NQSFETTQ.js → chunk-WCM4FNUB.js} +1 -1
- package/dist/cli.js +62 -21
- package/dist/daemon-main.js +7 -7
- package/dist/index.js +63 -22
- package/dist/{session-replayer-YIGRIIDD.js → session-replayer-SD2MWGP5.js} +1 -1
- package/package.json +1 -1
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
saveSessionDiskMeta,
|
|
21
21
|
setActivePage,
|
|
22
22
|
touchSession
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-WCM4FNUB.js";
|
|
24
|
+
import "./chunk-74QM55TC.js";
|
|
25
25
|
import "./chunk-TNEN6VQ2.js";
|
|
26
26
|
import "./chunk-GDKLH7ZY.js";
|
|
27
27
|
import "./chunk-KFQGP6VL.js";
|
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
saveSessionDiskMeta,
|
|
21
21
|
setActivePage,
|
|
22
22
|
touchSession
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-MKEAO3XJ.js";
|
|
24
|
+
import "./chunk-74QM55TC.js";
|
|
25
25
|
import "./chunk-TNEN6VQ2.js";
|
|
26
26
|
import "./chunk-GDKLH7ZY.js";
|
|
27
27
|
import "./chunk-ABXMBNQ6.js";
|
|
@@ -303,6 +303,18 @@ function queryAllJS(selector) {
|
|
|
303
303
|
async function waitForActionable(page, selector, opts = {}) {
|
|
304
304
|
const timeout = opts.timeout ?? 3e4;
|
|
305
305
|
if (opts.force) {
|
|
306
|
+
if (selector.startsWith("xpath=")) {
|
|
307
|
+
const rect2 = await page.evaluate(`
|
|
308
|
+
(function() {
|
|
309
|
+
const el = ${queryJS(selector)};
|
|
310
|
+
if (!el) return null;
|
|
311
|
+
const r = el.getBoundingClientRect();
|
|
312
|
+
return { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
313
|
+
})()
|
|
314
|
+
`);
|
|
315
|
+
if (!rect2) throw new Error(`Element not found: ${selector}`);
|
|
316
|
+
return { nodeId: 0, rect: rect2 };
|
|
317
|
+
}
|
|
306
318
|
const nodeId = await page.querySelector(selector);
|
|
307
319
|
if (!nodeId) throw new Error(`Element not found: ${selector}`);
|
|
308
320
|
const rect = await page.getBoxModel(nodeId);
|
|
@@ -1165,17 +1177,43 @@ var XBPageImpl = class _XBPageImpl {
|
|
|
1165
1177
|
headers: () => headers
|
|
1166
1178
|
};
|
|
1167
1179
|
}
|
|
1168
|
-
async goBack(
|
|
1169
|
-
|
|
1180
|
+
async goBack(opts = {}) {
|
|
1181
|
+
try {
|
|
1182
|
+
const navHistory = await this.conn.send("Page.getNavigationHistory", void 0, this.sessionId);
|
|
1183
|
+
if (navHistory.currentIndex > 0) {
|
|
1184
|
+
const prevUrl = navHistory.entries[navHistory.currentIndex - 1]?.url;
|
|
1185
|
+
if (prevUrl && prevUrl !== "about:blank") {
|
|
1186
|
+
await this.conn.send("Page.navigate", { url: prevUrl }, this.sessionId);
|
|
1187
|
+
await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 1e4).catch(() => {
|
|
1188
|
+
});
|
|
1189
|
+
this._url = prevUrl;
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
} catch {
|
|
1194
|
+
}
|
|
1170
1195
|
await this.evaluate("() => history.back()");
|
|
1171
|
-
await this.waitForTimeout(
|
|
1172
|
-
this._url = await this.evaluate("location.href").catch(() =>
|
|
1196
|
+
await this.waitForTimeout(3e3);
|
|
1197
|
+
this._url = await this.evaluate("location.href").catch(() => this._url);
|
|
1173
1198
|
}
|
|
1174
|
-
async goForward(
|
|
1175
|
-
|
|
1199
|
+
async goForward(opts = {}) {
|
|
1200
|
+
try {
|
|
1201
|
+
const navHistory = await this.conn.send("Page.getNavigationHistory", void 0, this.sessionId);
|
|
1202
|
+
if (navHistory.currentIndex < navHistory.entries.length - 1) {
|
|
1203
|
+
const nextUrl = navHistory.entries[navHistory.currentIndex + 1]?.url;
|
|
1204
|
+
if (nextUrl && nextUrl !== "about:blank") {
|
|
1205
|
+
await this.conn.send("Page.navigate", { url: nextUrl }, this.sessionId);
|
|
1206
|
+
await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 1e4).catch(() => {
|
|
1207
|
+
});
|
|
1208
|
+
this._url = nextUrl;
|
|
1209
|
+
return;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
} catch {
|
|
1213
|
+
}
|
|
1176
1214
|
await this.evaluate("() => history.forward()");
|
|
1177
|
-
await this.waitForTimeout(
|
|
1178
|
-
this._url = await this.evaluate("location.href").catch(() =>
|
|
1215
|
+
await this.waitForTimeout(3e3);
|
|
1216
|
+
this._url = await this.evaluate("location.href").catch(() => this._url);
|
|
1179
1217
|
}
|
|
1180
1218
|
async reload(opts = {}) {
|
|
1181
1219
|
this._loadState = { loadFired: false, domContentFired: false, networkIdle: false };
|
|
@@ -1656,6 +1694,22 @@ Last error: ${lastError.message}` : "";
|
|
|
1656
1694
|
// ── CDP helpers exposed for locator/element ─────────────────
|
|
1657
1695
|
/** Query a single element, returns CDP nodeId or 0 if not found */
|
|
1658
1696
|
async querySelector(selector) {
|
|
1697
|
+
if (selector.startsWith("xpath=")) {
|
|
1698
|
+
const found = await this.evaluate(`
|
|
1699
|
+
(() => { const el = ${queryJS(selector)}; return !!el; })()
|
|
1700
|
+
`).catch(() => false);
|
|
1701
|
+
if (!found) return 0;
|
|
1702
|
+
try {
|
|
1703
|
+
const search = await this.conn.send(
|
|
1704
|
+
"DOM.performSearch",
|
|
1705
|
+
{ query: selector.slice(6) },
|
|
1706
|
+
this.sessionId
|
|
1707
|
+
);
|
|
1708
|
+
if (search.nodeId) return search.nodeId;
|
|
1709
|
+
} catch {
|
|
1710
|
+
}
|
|
1711
|
+
return 1;
|
|
1712
|
+
}
|
|
1659
1713
|
const doc = await this.conn.send(
|
|
1660
1714
|
"DOM.getDocument",
|
|
1661
1715
|
{ depth: 0 },
|
|
@@ -302,6 +302,18 @@ function queryAllJS(selector) {
|
|
|
302
302
|
async function waitForActionable(page, selector, opts = {}) {
|
|
303
303
|
const timeout = opts.timeout ?? 3e4;
|
|
304
304
|
if (opts.force) {
|
|
305
|
+
if (selector.startsWith("xpath=")) {
|
|
306
|
+
const rect2 = await page.evaluate(`
|
|
307
|
+
(function() {
|
|
308
|
+
const el = ${queryJS(selector)};
|
|
309
|
+
if (!el) return null;
|
|
310
|
+
const r = el.getBoundingClientRect();
|
|
311
|
+
return { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
312
|
+
})()
|
|
313
|
+
`);
|
|
314
|
+
if (!rect2) throw new Error(`Element not found: ${selector}`);
|
|
315
|
+
return { nodeId: 0, rect: rect2 };
|
|
316
|
+
}
|
|
305
317
|
const nodeId = await page.querySelector(selector);
|
|
306
318
|
if (!nodeId) throw new Error(`Element not found: ${selector}`);
|
|
307
319
|
const rect = await page.getBoxModel(nodeId);
|
|
@@ -1164,17 +1176,43 @@ var XBPageImpl = class _XBPageImpl {
|
|
|
1164
1176
|
headers: () => headers
|
|
1165
1177
|
};
|
|
1166
1178
|
}
|
|
1167
|
-
async goBack(
|
|
1168
|
-
|
|
1179
|
+
async goBack(opts = {}) {
|
|
1180
|
+
try {
|
|
1181
|
+
const navHistory = await this.conn.send("Page.getNavigationHistory", void 0, this.sessionId);
|
|
1182
|
+
if (navHistory.currentIndex > 0) {
|
|
1183
|
+
const prevUrl = navHistory.entries[navHistory.currentIndex - 1]?.url;
|
|
1184
|
+
if (prevUrl && prevUrl !== "about:blank") {
|
|
1185
|
+
await this.conn.send("Page.navigate", { url: prevUrl }, this.sessionId);
|
|
1186
|
+
await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 1e4).catch(() => {
|
|
1187
|
+
});
|
|
1188
|
+
this._url = prevUrl;
|
|
1189
|
+
return;
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
} catch {
|
|
1193
|
+
}
|
|
1169
1194
|
await this.evaluate("() => history.back()");
|
|
1170
|
-
await this.waitForTimeout(
|
|
1171
|
-
this._url = await this.evaluate("location.href").catch(() =>
|
|
1195
|
+
await this.waitForTimeout(3e3);
|
|
1196
|
+
this._url = await this.evaluate("location.href").catch(() => this._url);
|
|
1172
1197
|
}
|
|
1173
|
-
async goForward(
|
|
1174
|
-
|
|
1198
|
+
async goForward(opts = {}) {
|
|
1199
|
+
try {
|
|
1200
|
+
const navHistory = await this.conn.send("Page.getNavigationHistory", void 0, this.sessionId);
|
|
1201
|
+
if (navHistory.currentIndex < navHistory.entries.length - 1) {
|
|
1202
|
+
const nextUrl = navHistory.entries[navHistory.currentIndex + 1]?.url;
|
|
1203
|
+
if (nextUrl && nextUrl !== "about:blank") {
|
|
1204
|
+
await this.conn.send("Page.navigate", { url: nextUrl }, this.sessionId);
|
|
1205
|
+
await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 1e4).catch(() => {
|
|
1206
|
+
});
|
|
1207
|
+
this._url = nextUrl;
|
|
1208
|
+
return;
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
} catch {
|
|
1212
|
+
}
|
|
1175
1213
|
await this.evaluate("() => history.forward()");
|
|
1176
|
-
await this.waitForTimeout(
|
|
1177
|
-
this._url = await this.evaluate("location.href").catch(() =>
|
|
1214
|
+
await this.waitForTimeout(3e3);
|
|
1215
|
+
this._url = await this.evaluate("location.href").catch(() => this._url);
|
|
1178
1216
|
}
|
|
1179
1217
|
async reload(opts = {}) {
|
|
1180
1218
|
this._loadState = { loadFired: false, domContentFired: false, networkIdle: false };
|
|
@@ -1655,6 +1693,22 @@ Last error: ${lastError.message}` : "";
|
|
|
1655
1693
|
// ── CDP helpers exposed for locator/element ─────────────────
|
|
1656
1694
|
/** Query a single element, returns CDP nodeId or 0 if not found */
|
|
1657
1695
|
async querySelector(selector) {
|
|
1696
|
+
if (selector.startsWith("xpath=")) {
|
|
1697
|
+
const found = await this.evaluate(`
|
|
1698
|
+
(() => { const el = ${queryJS(selector)}; return !!el; })()
|
|
1699
|
+
`).catch(() => false);
|
|
1700
|
+
if (!found) return 0;
|
|
1701
|
+
try {
|
|
1702
|
+
const search = await this.conn.send(
|
|
1703
|
+
"DOM.performSearch",
|
|
1704
|
+
{ query: selector.slice(6) },
|
|
1705
|
+
this.sessionId
|
|
1706
|
+
);
|
|
1707
|
+
if (search.nodeId) return search.nodeId;
|
|
1708
|
+
} catch {
|
|
1709
|
+
}
|
|
1710
|
+
return 1;
|
|
1711
|
+
}
|
|
1658
1712
|
const doc = await this.conn.send(
|
|
1659
1713
|
"DOM.getDocument",
|
|
1660
1714
|
{ depth: 0 },
|
|
@@ -308,6 +308,18 @@ function queryAllJS(selector) {
|
|
|
308
308
|
async function waitForActionable(page, selector, opts = {}) {
|
|
309
309
|
const timeout = opts.timeout ?? 3e4;
|
|
310
310
|
if (opts.force) {
|
|
311
|
+
if (selector.startsWith("xpath=")) {
|
|
312
|
+
const rect2 = await page.evaluate(`
|
|
313
|
+
(function() {
|
|
314
|
+
const el = ${queryJS(selector)};
|
|
315
|
+
if (!el) return null;
|
|
316
|
+
const r = el.getBoundingClientRect();
|
|
317
|
+
return { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
318
|
+
})()
|
|
319
|
+
`);
|
|
320
|
+
if (!rect2) throw new Error(`Element not found: ${selector}`);
|
|
321
|
+
return { nodeId: 0, rect: rect2 };
|
|
322
|
+
}
|
|
311
323
|
const nodeId = await page.querySelector(selector);
|
|
312
324
|
if (!nodeId) throw new Error(`Element not found: ${selector}`);
|
|
313
325
|
const rect = await page.getBoxModel(nodeId);
|
|
@@ -1170,17 +1182,43 @@ var XBPageImpl = class _XBPageImpl {
|
|
|
1170
1182
|
headers: () => headers
|
|
1171
1183
|
};
|
|
1172
1184
|
}
|
|
1173
|
-
async goBack(
|
|
1174
|
-
|
|
1185
|
+
async goBack(opts = {}) {
|
|
1186
|
+
try {
|
|
1187
|
+
const navHistory = await this.conn.send("Page.getNavigationHistory", void 0, this.sessionId);
|
|
1188
|
+
if (navHistory.currentIndex > 0) {
|
|
1189
|
+
const prevUrl = navHistory.entries[navHistory.currentIndex - 1]?.url;
|
|
1190
|
+
if (prevUrl && prevUrl !== "about:blank") {
|
|
1191
|
+
await this.conn.send("Page.navigate", { url: prevUrl }, this.sessionId);
|
|
1192
|
+
await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 1e4).catch(() => {
|
|
1193
|
+
});
|
|
1194
|
+
this._url = prevUrl;
|
|
1195
|
+
return;
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
} catch {
|
|
1199
|
+
}
|
|
1175
1200
|
await this.evaluate("() => history.back()");
|
|
1176
|
-
await this.waitForTimeout(
|
|
1177
|
-
this._url = await this.evaluate("location.href").catch(() =>
|
|
1201
|
+
await this.waitForTimeout(3e3);
|
|
1202
|
+
this._url = await this.evaluate("location.href").catch(() => this._url);
|
|
1178
1203
|
}
|
|
1179
|
-
async goForward(
|
|
1180
|
-
|
|
1204
|
+
async goForward(opts = {}) {
|
|
1205
|
+
try {
|
|
1206
|
+
const navHistory = await this.conn.send("Page.getNavigationHistory", void 0, this.sessionId);
|
|
1207
|
+
if (navHistory.currentIndex < navHistory.entries.length - 1) {
|
|
1208
|
+
const nextUrl = navHistory.entries[navHistory.currentIndex + 1]?.url;
|
|
1209
|
+
if (nextUrl && nextUrl !== "about:blank") {
|
|
1210
|
+
await this.conn.send("Page.navigate", { url: nextUrl }, this.sessionId);
|
|
1211
|
+
await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 1e4).catch(() => {
|
|
1212
|
+
});
|
|
1213
|
+
this._url = nextUrl;
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
} catch {
|
|
1218
|
+
}
|
|
1181
1219
|
await this.evaluate("() => history.forward()");
|
|
1182
|
-
await this.waitForTimeout(
|
|
1183
|
-
this._url = await this.evaluate("location.href").catch(() =>
|
|
1220
|
+
await this.waitForTimeout(3e3);
|
|
1221
|
+
this._url = await this.evaluate("location.href").catch(() => this._url);
|
|
1184
1222
|
}
|
|
1185
1223
|
async reload(opts = {}) {
|
|
1186
1224
|
this._loadState = { loadFired: false, domContentFired: false, networkIdle: false };
|
|
@@ -1661,6 +1699,22 @@ Last error: ${lastError.message}` : "";
|
|
|
1661
1699
|
// ── CDP helpers exposed for locator/element ─────────────────
|
|
1662
1700
|
/** Query a single element, returns CDP nodeId or 0 if not found */
|
|
1663
1701
|
async querySelector(selector) {
|
|
1702
|
+
if (selector.startsWith("xpath=")) {
|
|
1703
|
+
const found = await this.evaluate(`
|
|
1704
|
+
(() => { const el = ${queryJS(selector)}; return !!el; })()
|
|
1705
|
+
`).catch(() => false);
|
|
1706
|
+
if (!found) return 0;
|
|
1707
|
+
try {
|
|
1708
|
+
const search = await this.conn.send(
|
|
1709
|
+
"DOM.performSearch",
|
|
1710
|
+
{ query: selector.slice(6) },
|
|
1711
|
+
this.sessionId
|
|
1712
|
+
);
|
|
1713
|
+
if (search.nodeId) return search.nodeId;
|
|
1714
|
+
} catch {
|
|
1715
|
+
}
|
|
1716
|
+
return 1;
|
|
1717
|
+
}
|
|
1664
1718
|
const doc = await this.conn.send(
|
|
1665
1719
|
"DOM.getDocument",
|
|
1666
1720
|
{ depth: 0 },
|
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-H7R352A2.js";
|
|
29
29
|
import "./chunk-TNEN6VQ2.js";
|
|
30
30
|
import {
|
|
31
31
|
forwardCommandLog,
|
|
@@ -1208,9 +1208,9 @@ var setViewportCommand = registerCommand({
|
|
|
1208
1208
|
description: "Set the viewport size and properties",
|
|
1209
1209
|
scope: "browser",
|
|
1210
1210
|
parameters: z11.object({
|
|
1211
|
-
width: z11.number(),
|
|
1212
|
-
height: z11.number(),
|
|
1213
|
-
deviceScaleFactor: z11.number().optional(),
|
|
1211
|
+
width: z11.coerce.number(),
|
|
1212
|
+
height: z11.coerce.number(),
|
|
1213
|
+
deviceScaleFactor: z11.coerce.number().optional(),
|
|
1214
1214
|
isMobile: z11.boolean().optional(),
|
|
1215
1215
|
hasTouch: z11.boolean().optional()
|
|
1216
1216
|
}),
|
|
@@ -7083,7 +7083,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7083
7083
|
}
|
|
7084
7084
|
let targetPageOverride = null;
|
|
7085
7085
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7086
|
-
const { findTargetPage } = await import("./browser-
|
|
7086
|
+
const { findTargetPage } = await import("./browser-2FJ4OO4H.js");
|
|
7087
7087
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7088
7088
|
if (!targetPageOverride) {
|
|
7089
7089
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -11744,8 +11744,13 @@ Commands:
|
|
|
11744
11744
|
session close [--session <name>] Close session
|
|
11745
11745
|
session list List sessions
|
|
11746
11746
|
session kill [--session <name>] Kill session
|
|
11747
|
+
|
|
11747
11748
|
goto <url> Navigate to URL
|
|
11748
11749
|
open <url> Navigate to URL (alias for goto)
|
|
11750
|
+
back Go back in history
|
|
11751
|
+
forward Go forward in history
|
|
11752
|
+
refresh Reload page
|
|
11753
|
+
|
|
11749
11754
|
click <selector> Click element (-s <sel>)
|
|
11750
11755
|
fill <selector> <value> Fill input (-s <sel> -v <val>)
|
|
11751
11756
|
type <selector> <text> Type text (-s <sel> -v <text>)
|
|
@@ -11755,21 +11760,61 @@ Commands:
|
|
|
11755
11760
|
dblclick <selector> Double click (-s <sel>)
|
|
11756
11761
|
check <selector> Check checkbox (-s <sel>)
|
|
11757
11762
|
uncheck <selector> Uncheck checkbox (-s <sel>)
|
|
11758
|
-
|
|
11763
|
+
mouse <action> <x> <y> Mouse move/click at coordinates
|
|
11764
|
+
scroll <direction> [--distance N] Scroll page
|
|
11765
|
+
|
|
11766
|
+
screenshot [--full-page] [--base64] Take screenshot
|
|
11759
11767
|
eval <expression> Evaluate JS
|
|
11760
11768
|
wait <selector> [--timeout <ms>] Wait for element (-s <sel>)
|
|
11761
|
-
|
|
11769
|
+
waitForTimeout <ms> Wait for milliseconds
|
|
11770
|
+
waitFor --text <t> Wait for text/url/selector predicate
|
|
11762
11771
|
title Get page title
|
|
11763
11772
|
url Get current URL
|
|
11764
11773
|
html [--selector <sel>] Get HTML content
|
|
11765
11774
|
text [--selector <sel>] Get text content
|
|
11775
|
+
find <strategy> <value> [--action click|fill|hover] Find element by text/role/label
|
|
11776
|
+
|
|
11777
|
+
set-viewport <width> <height> Set viewport size
|
|
11778
|
+
frames List all frames
|
|
11779
|
+
frame --index <n> Switch to frame
|
|
11780
|
+
tab list List browser tabs
|
|
11781
|
+
tab new <url> Open new tab
|
|
11782
|
+
tab close --index <n> Close tab
|
|
11783
|
+
tab switch --index <n> Switch to tab
|
|
11784
|
+
|
|
11785
|
+
get-cookies Get all cookies
|
|
11786
|
+
set-cookie <name> <value> Set cookie
|
|
11787
|
+
clear-cookies Clear cookies
|
|
11788
|
+
get-local-storage Get localStorage
|
|
11789
|
+
set-local-storage <key> <value> Set localStorage item
|
|
11790
|
+
clear-local-storage Clear localStorage
|
|
11791
|
+
|
|
11792
|
+
snapshot Get page snapshot with element refs
|
|
11793
|
+
observe AI agent: observe page state
|
|
11794
|
+
act AI agent: perform action
|
|
11795
|
+
actions <url> --action "..." Execute action sequence
|
|
11796
|
+
|
|
11797
|
+
console Get console messages
|
|
11798
|
+
net-debug Get network debug info
|
|
11799
|
+
perf Get performance metrics
|
|
11800
|
+
health Run page health check (SEO/links/errors)
|
|
11801
|
+
structure Get page DOM structure
|
|
11802
|
+
network <url> Capture network traffic
|
|
11803
|
+
addinitscript <script> Add init script
|
|
11804
|
+
|
|
11805
|
+
scrape <url> Scrape page to markdown
|
|
11806
|
+
crawl <url> Crawl website (multi-page)
|
|
11807
|
+
search "query" Search the web (--engine, --limit, --full)
|
|
11808
|
+
map <url> Discover all URLs on a website
|
|
11809
|
+
|
|
11766
11810
|
convert <rec.yaml> <out.{js,py,sh}> Convert recording to script
|
|
11767
11811
|
extract <rec.yaml> Extract LLM-ready summary
|
|
11768
11812
|
filter <in.yaml> <out.yaml> Filter recording events
|
|
11769
|
-
|
|
11770
|
-
|
|
11771
|
-
|
|
11772
|
-
|
|
11813
|
+
replay <file> Replay recording
|
|
11814
|
+
record start --url <url> Start recording
|
|
11815
|
+
record stop Stop recording
|
|
11816
|
+
record status Recording status
|
|
11817
|
+
|
|
11773
11818
|
config <get|set|list> Manage config
|
|
11774
11819
|
plugin search <query> Search for plugins
|
|
11775
11820
|
plugin install <source> Install plugin
|
|
@@ -11777,16 +11822,12 @@ Commands:
|
|
|
11777
11822
|
plugin list List plugins
|
|
11778
11823
|
plugin reload <name> Reload plugin
|
|
11779
11824
|
create <name> --template <type> Create plugin
|
|
11780
|
-
serve [--port <port>] [--token <t>] Start HTTP server
|
|
11781
|
-
remote <url> [command] [--token <t>] Execute
|
|
11782
|
-
record start --url <url> Start recording
|
|
11783
|
-
record stop Stop recording
|
|
11784
|
-
record status Recording status
|
|
11785
|
-
replay <file> Replay recording
|
|
11825
|
+
serve [--port <port>] [--token <t>] Start HTTP server
|
|
11826
|
+
remote <url> [command] [--token <t>] Execute on remote server
|
|
11786
11827
|
run <file> Execute commands from file
|
|
11787
|
-
viewer [--name <n>]
|
|
11828
|
+
viewer [--name <n>] Generate viewer URL
|
|
11788
11829
|
help Show this help
|
|
11789
|
-
--version
|
|
11830
|
+
--version Show version
|
|
11790
11831
|
Plugin Commands:
|
|
11791
11832
|
Installed plugins provide additional commands.
|
|
11792
11833
|
Use 'xbrowser plugin list' to see installed plugins and their commands.
|
|
@@ -11832,7 +11873,7 @@ Global Flags:
|
|
|
11832
11873
|
--session <name> Use specific session
|
|
11833
11874
|
--cdp <endpoint> Connect via CDP (url, port, or 'auto')
|
|
11834
11875
|
--help, -h Show help
|
|
11835
|
-
|
|
11876
|
+
`);
|
|
11836
11877
|
}
|
|
11837
11878
|
|
|
11838
11879
|
// src/cli/chain-output.ts
|
|
@@ -13059,7 +13100,7 @@ async function main() {
|
|
|
13059
13100
|
const command = process.argv[2];
|
|
13060
13101
|
const isLongRunning = command === "preview" || command === "serve";
|
|
13061
13102
|
if (!isLongRunning) {
|
|
13062
|
-
const { ensureProcessCanExit } = await import("./browser-
|
|
13103
|
+
const { ensureProcessCanExit } = await import("./browser-2FJ4OO4H.js");
|
|
13063
13104
|
await ensureProcessCanExit().catch(() => {
|
|
13064
13105
|
});
|
|
13065
13106
|
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-WCM4FNUB.js";
|
|
25
|
+
import "./chunk-74QM55TC.js";
|
|
26
26
|
import "./chunk-TNEN6VQ2.js";
|
|
27
27
|
import {
|
|
28
28
|
getPluginLoader
|
|
@@ -1169,9 +1169,9 @@ var setViewportCommand = registerCommand({
|
|
|
1169
1169
|
description: "Set the viewport size and properties",
|
|
1170
1170
|
scope: "browser",
|
|
1171
1171
|
parameters: z11.object({
|
|
1172
|
-
width: z11.number(),
|
|
1173
|
-
height: z11.number(),
|
|
1174
|
-
deviceScaleFactor: z11.number().optional(),
|
|
1172
|
+
width: z11.coerce.number(),
|
|
1173
|
+
height: z11.coerce.number(),
|
|
1174
|
+
deviceScaleFactor: z11.coerce.number().optional(),
|
|
1175
1175
|
isMobile: z11.boolean().optional(),
|
|
1176
1176
|
hasTouch: z11.boolean().optional()
|
|
1177
1177
|
}),
|
|
@@ -6614,7 +6614,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
6614
6614
|
}
|
|
6615
6615
|
let targetPageOverride = null;
|
|
6616
6616
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
6617
|
-
const { findTargetPage } = await import("./browser-
|
|
6617
|
+
const { findTargetPage } = await import("./browser-IS6DTR5Y.js");
|
|
6618
6618
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
6619
6619
|
if (!targetPageOverride) {
|
|
6620
6620
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -8330,7 +8330,7 @@ function createRPCHandler() {
|
|
|
8330
8330
|
const isNewFormat = Array.isArray(parsed.actions);
|
|
8331
8331
|
if (isNewFormat) {
|
|
8332
8332
|
try {
|
|
8333
|
-
const { SessionReplayer } = await import("./session-replayer-
|
|
8333
|
+
const { SessionReplayer } = await import("./session-replayer-SD2MWGP5.js");
|
|
8334
8334
|
const replayer = new SessionReplayer({
|
|
8335
8335
|
page: session.page,
|
|
8336
8336
|
stepDelay: slowMo * 500,
|
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-MKEAO3XJ.js";
|
|
85
|
+
import "./chunk-74QM55TC.js";
|
|
86
86
|
import "./chunk-TNEN6VQ2.js";
|
|
87
87
|
import {
|
|
88
88
|
errMsg
|
|
@@ -1248,9 +1248,9 @@ var setViewportCommand = registerCommand({
|
|
|
1248
1248
|
description: "Set the viewport size and properties",
|
|
1249
1249
|
scope: "browser",
|
|
1250
1250
|
parameters: z11.object({
|
|
1251
|
-
width: z11.number(),
|
|
1252
|
-
height: z11.number(),
|
|
1253
|
-
deviceScaleFactor: z11.number().optional(),
|
|
1251
|
+
width: z11.coerce.number(),
|
|
1252
|
+
height: z11.coerce.number(),
|
|
1253
|
+
deviceScaleFactor: z11.coerce.number().optional(),
|
|
1254
1254
|
isMobile: z11.boolean().optional(),
|
|
1255
1255
|
hasTouch: z11.boolean().optional()
|
|
1256
1256
|
}),
|
|
@@ -7403,7 +7403,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7403
7403
|
}
|
|
7404
7404
|
let targetPageOverride = null;
|
|
7405
7405
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7406
|
-
const { findTargetPage } = await import("./browser-
|
|
7406
|
+
const { findTargetPage } = await import("./browser-ZFW2XADE.js");
|
|
7407
7407
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7408
7408
|
if (!targetPageOverride) {
|
|
7409
7409
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -12084,8 +12084,13 @@ Commands:
|
|
|
12084
12084
|
session close [--session <name>] Close session
|
|
12085
12085
|
session list List sessions
|
|
12086
12086
|
session kill [--session <name>] Kill session
|
|
12087
|
+
|
|
12087
12088
|
goto <url> Navigate to URL
|
|
12088
12089
|
open <url> Navigate to URL (alias for goto)
|
|
12090
|
+
back Go back in history
|
|
12091
|
+
forward Go forward in history
|
|
12092
|
+
refresh Reload page
|
|
12093
|
+
|
|
12089
12094
|
click <selector> Click element (-s <sel>)
|
|
12090
12095
|
fill <selector> <value> Fill input (-s <sel> -v <val>)
|
|
12091
12096
|
type <selector> <text> Type text (-s <sel> -v <text>)
|
|
@@ -12095,21 +12100,61 @@ Commands:
|
|
|
12095
12100
|
dblclick <selector> Double click (-s <sel>)
|
|
12096
12101
|
check <selector> Check checkbox (-s <sel>)
|
|
12097
12102
|
uncheck <selector> Uncheck checkbox (-s <sel>)
|
|
12098
|
-
|
|
12103
|
+
mouse <action> <x> <y> Mouse move/click at coordinates
|
|
12104
|
+
scroll <direction> [--distance N] Scroll page
|
|
12105
|
+
|
|
12106
|
+
screenshot [--full-page] [--base64] Take screenshot
|
|
12099
12107
|
eval <expression> Evaluate JS
|
|
12100
12108
|
wait <selector> [--timeout <ms>] Wait for element (-s <sel>)
|
|
12101
|
-
|
|
12109
|
+
waitForTimeout <ms> Wait for milliseconds
|
|
12110
|
+
waitFor --text <t> Wait for text/url/selector predicate
|
|
12102
12111
|
title Get page title
|
|
12103
12112
|
url Get current URL
|
|
12104
12113
|
html [--selector <sel>] Get HTML content
|
|
12105
12114
|
text [--selector <sel>] Get text content
|
|
12115
|
+
find <strategy> <value> [--action click|fill|hover] Find element by text/role/label
|
|
12116
|
+
|
|
12117
|
+
set-viewport <width> <height> Set viewport size
|
|
12118
|
+
frames List all frames
|
|
12119
|
+
frame --index <n> Switch to frame
|
|
12120
|
+
tab list List browser tabs
|
|
12121
|
+
tab new <url> Open new tab
|
|
12122
|
+
tab close --index <n> Close tab
|
|
12123
|
+
tab switch --index <n> Switch to tab
|
|
12124
|
+
|
|
12125
|
+
get-cookies Get all cookies
|
|
12126
|
+
set-cookie <name> <value> Set cookie
|
|
12127
|
+
clear-cookies Clear cookies
|
|
12128
|
+
get-local-storage Get localStorage
|
|
12129
|
+
set-local-storage <key> <value> Set localStorage item
|
|
12130
|
+
clear-local-storage Clear localStorage
|
|
12131
|
+
|
|
12132
|
+
snapshot Get page snapshot with element refs
|
|
12133
|
+
observe AI agent: observe page state
|
|
12134
|
+
act AI agent: perform action
|
|
12135
|
+
actions <url> --action "..." Execute action sequence
|
|
12136
|
+
|
|
12137
|
+
console Get console messages
|
|
12138
|
+
net-debug Get network debug info
|
|
12139
|
+
perf Get performance metrics
|
|
12140
|
+
health Run page health check (SEO/links/errors)
|
|
12141
|
+
structure Get page DOM structure
|
|
12142
|
+
network <url> Capture network traffic
|
|
12143
|
+
addinitscript <script> Add init script
|
|
12144
|
+
|
|
12145
|
+
scrape <url> Scrape page to markdown
|
|
12146
|
+
crawl <url> Crawl website (multi-page)
|
|
12147
|
+
search "query" Search the web (--engine, --limit, --full)
|
|
12148
|
+
map <url> Discover all URLs on a website
|
|
12149
|
+
|
|
12106
12150
|
convert <rec.yaml> <out.{js,py,sh}> Convert recording to script
|
|
12107
12151
|
extract <rec.yaml> Extract LLM-ready summary
|
|
12108
12152
|
filter <in.yaml> <out.yaml> Filter recording events
|
|
12109
|
-
|
|
12110
|
-
|
|
12111
|
-
|
|
12112
|
-
|
|
12153
|
+
replay <file> Replay recording
|
|
12154
|
+
record start --url <url> Start recording
|
|
12155
|
+
record stop Stop recording
|
|
12156
|
+
record status Recording status
|
|
12157
|
+
|
|
12113
12158
|
config <get|set|list> Manage config
|
|
12114
12159
|
plugin search <query> Search for plugins
|
|
12115
12160
|
plugin install <source> Install plugin
|
|
@@ -12117,16 +12162,12 @@ Commands:
|
|
|
12117
12162
|
plugin list List plugins
|
|
12118
12163
|
plugin reload <name> Reload plugin
|
|
12119
12164
|
create <name> --template <type> Create plugin
|
|
12120
|
-
serve [--port <port>] [--token <t>] Start HTTP server
|
|
12121
|
-
remote <url> [command] [--token <t>] Execute
|
|
12122
|
-
record start --url <url> Start recording
|
|
12123
|
-
record stop Stop recording
|
|
12124
|
-
record status Recording status
|
|
12125
|
-
replay <file> Replay recording
|
|
12165
|
+
serve [--port <port>] [--token <t>] Start HTTP server
|
|
12166
|
+
remote <url> [command] [--token <t>] Execute on remote server
|
|
12126
12167
|
run <file> Execute commands from file
|
|
12127
|
-
viewer [--name <n>]
|
|
12168
|
+
viewer [--name <n>] Generate viewer URL
|
|
12128
12169
|
help Show this help
|
|
12129
|
-
--version
|
|
12170
|
+
--version Show version
|
|
12130
12171
|
Plugin Commands:
|
|
12131
12172
|
Installed plugins provide additional commands.
|
|
12132
12173
|
Use 'xbrowser plugin list' to see installed plugins and their commands.
|
|
@@ -12172,7 +12213,7 @@ Global Flags:
|
|
|
12172
12213
|
--session <name> Use specific session
|
|
12173
12214
|
--cdp <endpoint> Connect via CDP (url, port, or 'auto')
|
|
12174
12215
|
--help, -h Show help
|
|
12175
|
-
|
|
12216
|
+
`);
|
|
12176
12217
|
}
|
|
12177
12218
|
|
|
12178
12219
|
// src/cli/chain-output.ts
|
|
@@ -16186,7 +16227,7 @@ var DataCollector = class {
|
|
|
16186
16227
|
return results;
|
|
16187
16228
|
}
|
|
16188
16229
|
async createBrowserContext() {
|
|
16189
|
-
const { launch } = await import("./cdp-driver-
|
|
16230
|
+
const { launch } = await import("./cdp-driver-QHTXQRQ2.js");
|
|
16190
16231
|
const { browser } = await launch({
|
|
16191
16232
|
headless: true,
|
|
16192
16233
|
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-QHTXQRQ2.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.
|
|
3
|
+
"version": "1.5.0",
|
|
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": {
|