@flrande/browserctl 0.5.0 → 0.6.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/client.d.ts +34 -0
- package/dist/client.js +138 -0
- package/dist/commandRegistry.d.ts +16 -0
- package/dist/commandRegistry.js +21 -0
- package/dist/help.d.ts +4 -0
- package/dist/help.js +24 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +23 -0
- package/dist/runCli.d.ts +5 -0
- package/dist/runCli.js +170 -0
- package/package.json +32 -57
- package/INSTALL-CN.md +0 -92
- package/INSTALL.md +0 -92
- package/LICENSE +0 -21
- package/README-CN.md +0 -69
- package/README.md +0 -69
- package/apps/browserctl/src/commands/a11y-snapshot.ts +0 -20
- package/apps/browserctl/src/commands/act.test.ts +0 -71
- package/apps/browserctl/src/commands/act.ts +0 -64
- package/apps/browserctl/src/commands/command-wrappers.test.ts +0 -688
- package/apps/browserctl/src/commands/common.test.ts +0 -87
- package/apps/browserctl/src/commands/common.ts +0 -191
- package/apps/browserctl/src/commands/console-list.test.ts +0 -102
- package/apps/browserctl/src/commands/console-list.ts +0 -108
- package/apps/browserctl/src/commands/cookie-clear.ts +0 -18
- package/apps/browserctl/src/commands/cookie-get.ts +0 -18
- package/apps/browserctl/src/commands/cookie-set.ts +0 -22
- package/apps/browserctl/src/commands/dialog-arm.ts +0 -20
- package/apps/browserctl/src/commands/dom-query-all.ts +0 -18
- package/apps/browserctl/src/commands/dom-query.ts +0 -18
- package/apps/browserctl/src/commands/download-trigger.ts +0 -22
- package/apps/browserctl/src/commands/download-wait.test.ts +0 -67
- package/apps/browserctl/src/commands/download-wait.ts +0 -27
- package/apps/browserctl/src/commands/element-screenshot.ts +0 -20
- package/apps/browserctl/src/commands/frame-list.ts +0 -16
- package/apps/browserctl/src/commands/frame-snapshot.ts +0 -18
- package/apps/browserctl/src/commands/har-export.test.ts +0 -112
- package/apps/browserctl/src/commands/har-export.ts +0 -120
- package/apps/browserctl/src/commands/memory-delete.ts +0 -20
- package/apps/browserctl/src/commands/memory-inspect.ts +0 -20
- package/apps/browserctl/src/commands/memory-list.ts +0 -90
- package/apps/browserctl/src/commands/memory-mode-set.ts +0 -29
- package/apps/browserctl/src/commands/memory-purge.ts +0 -16
- package/apps/browserctl/src/commands/memory-resolve.ts +0 -56
- package/apps/browserctl/src/commands/memory-status.ts +0 -16
- package/apps/browserctl/src/commands/memory-ttl-set.ts +0 -28
- package/apps/browserctl/src/commands/memory-upsert.ts +0 -142
- package/apps/browserctl/src/commands/network-list.test.ts +0 -110
- package/apps/browserctl/src/commands/network-list.ts +0 -112
- package/apps/browserctl/src/commands/network-wait-for.test.ts +0 -90
- package/apps/browserctl/src/commands/network-wait-for.ts +0 -100
- package/apps/browserctl/src/commands/profile-list.ts +0 -16
- package/apps/browserctl/src/commands/profile-use.ts +0 -18
- package/apps/browserctl/src/commands/response-body.ts +0 -24
- package/apps/browserctl/src/commands/screenshot.ts +0 -16
- package/apps/browserctl/src/commands/session-drop.test.ts +0 -36
- package/apps/browserctl/src/commands/session-drop.ts +0 -16
- package/apps/browserctl/src/commands/session-list.test.ts +0 -81
- package/apps/browserctl/src/commands/session-list.ts +0 -70
- package/apps/browserctl/src/commands/snapshot.ts +0 -16
- package/apps/browserctl/src/commands/status.ts +0 -10
- package/apps/browserctl/src/commands/storage-get.ts +0 -20
- package/apps/browserctl/src/commands/storage-set.ts +0 -22
- package/apps/browserctl/src/commands/tab-close.ts +0 -20
- package/apps/browserctl/src/commands/tab-focus.ts +0 -20
- package/apps/browserctl/src/commands/tab-open.ts +0 -19
- package/apps/browserctl/src/commands/tabs.ts +0 -13
- package/apps/browserctl/src/commands/trace-get.test.ts +0 -61
- package/apps/browserctl/src/commands/trace-get.ts +0 -62
- package/apps/browserctl/src/commands/upload-arm.ts +0 -26
- package/apps/browserctl/src/commands/wait-element.test.ts +0 -80
- package/apps/browserctl/src/commands/wait-element.ts +0 -76
- package/apps/browserctl/src/commands/wait-text.test.ts +0 -110
- package/apps/browserctl/src/commands/wait-text.ts +0 -93
- package/apps/browserctl/src/commands/wait-url.test.ts +0 -80
- package/apps/browserctl/src/commands/wait-url.ts +0 -76
- package/apps/browserctl/src/daemon-client.test.ts +0 -253
- package/apps/browserctl/src/daemon-client.ts +0 -632
- package/apps/browserctl/src/e2e.test.ts +0 -103
- package/apps/browserctl/src/main.dispatch.test.ts +0 -461
- package/apps/browserctl/src/main.test.ts +0 -334
- package/apps/browserctl/src/main.ts +0 -957
- package/apps/browserctl/src/smoke.e2e.test.ts +0 -97
- package/apps/browserctl/src/test-port.ts +0 -26
- package/apps/browserd/src/bootstrap.ts +0 -432
- package/apps/browserd/src/chrome-relay-extension-bridge.test.ts +0 -250
- package/apps/browserd/src/chrome-relay-extension-bridge.ts +0 -506
- package/apps/browserd/src/container.ts +0 -3088
- package/apps/browserd/src/main.test.ts +0 -1436
- package/apps/browserd/src/main.ts +0 -7
- package/apps/browserd/src/test-port.ts +0 -26
- package/apps/browserd/src/tool-matrix.test.ts +0 -887
- package/bin/browserctl.cjs +0 -21
- package/bin/browserd.cjs +0 -21
- package/extensions/chrome-relay/README-CN.md +0 -39
- package/extensions/chrome-relay/README.md +0 -39
- package/extensions/chrome-relay/background.js +0 -1687
- package/extensions/chrome-relay/manifest.json +0 -15
- package/extensions/chrome-relay/popup.html +0 -369
- package/extensions/chrome-relay/popup.js +0 -972
- package/packages/core/src/bootstrap.test.ts +0 -10
- package/packages/core/src/driver-registry.test.ts +0 -45
- package/packages/core/src/driver-registry.ts +0 -22
- package/packages/core/src/driver.ts +0 -47
- package/packages/core/src/index.ts +0 -6
- package/packages/core/src/navigation-memory.test.ts +0 -259
- package/packages/core/src/navigation-memory.ts +0 -360
- package/packages/core/src/ref-cache.test.ts +0 -61
- package/packages/core/src/ref-cache.ts +0 -28
- package/packages/core/src/session-store.test.ts +0 -82
- package/packages/core/src/session-store.ts +0 -138
- package/packages/core/src/types.ts +0 -9
- package/packages/driver-chrome-relay/src/chrome-relay-driver.test.ts +0 -744
- package/packages/driver-chrome-relay/src/chrome-relay-driver.ts +0 -2429
- package/packages/driver-chrome-relay/src/chrome-relay-extension-runtime.test.ts +0 -264
- package/packages/driver-chrome-relay/src/chrome-relay-extension-runtime.ts +0 -521
- package/packages/driver-chrome-relay/src/index.ts +0 -26
- package/packages/driver-managed/src/index.ts +0 -22
- package/packages/driver-managed/src/managed-driver.test.ts +0 -183
- package/packages/driver-managed/src/managed-driver.ts +0 -341
- package/packages/driver-managed/src/managed-local-driver.test.ts +0 -608
- package/packages/driver-managed/src/managed-local-driver.ts +0 -2243
- package/packages/driver-remote-cdp/src/index.ts +0 -19
- package/packages/driver-remote-cdp/src/remote-cdp-driver.test.ts +0 -727
- package/packages/driver-remote-cdp/src/remote-cdp-driver.ts +0 -2264
- package/packages/protocol/src/envelope.test.ts +0 -25
- package/packages/protocol/src/envelope.ts +0 -31
- package/packages/protocol/src/errors.test.ts +0 -17
- package/packages/protocol/src/errors.ts +0 -11
- package/packages/protocol/src/index.ts +0 -3
- package/packages/protocol/src/tools.ts +0 -3
- package/packages/transport-mcp-stdio/src/index.ts +0 -3
- package/packages/transport-mcp-stdio/src/sdk-server.ts +0 -139
- package/packages/transport-mcp-stdio/src/server.test.ts +0 -281
- package/packages/transport-mcp-stdio/src/server.ts +0 -183
- package/packages/transport-mcp-stdio/src/tool-map.ts +0 -84
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
const { callDaemonToolMock } = vi.hoisted(() => ({
|
|
4
|
-
callDaemonToolMock: vi.fn()
|
|
5
|
-
}));
|
|
6
|
-
|
|
7
|
-
vi.mock("../daemon-client", () => ({
|
|
8
|
-
callDaemonTool: callDaemonToolMock
|
|
9
|
-
}));
|
|
10
|
-
|
|
11
|
-
import { runSessionListCommand } from "./session-list";
|
|
12
|
-
|
|
13
|
-
afterEach(() => {
|
|
14
|
-
callDaemonToolMock.mockReset();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
describe("runSessionListCommand", () => {
|
|
18
|
-
it("forwards tenant and limit filters", async () => {
|
|
19
|
-
callDaemonToolMock.mockResolvedValue({ ok: true });
|
|
20
|
-
|
|
21
|
-
await runSessionListCommand([
|
|
22
|
-
"--tenant",
|
|
23
|
-
"finance",
|
|
24
|
-
"--limit",
|
|
25
|
-
"20"
|
|
26
|
-
]);
|
|
27
|
-
|
|
28
|
-
expect(callDaemonToolMock).toHaveBeenCalledTimes(1);
|
|
29
|
-
expect(callDaemonToolMock).toHaveBeenCalledWith("browser.session.list", {
|
|
30
|
-
sessionId: "cli:local",
|
|
31
|
-
tenant: "finance",
|
|
32
|
-
limit: 20
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it("supports no options", async () => {
|
|
37
|
-
callDaemonToolMock.mockResolvedValue({ ok: true });
|
|
38
|
-
|
|
39
|
-
await runSessionListCommand([]);
|
|
40
|
-
|
|
41
|
-
expect(callDaemonToolMock).toHaveBeenCalledTimes(1);
|
|
42
|
-
expect(callDaemonToolMock).toHaveBeenCalledWith("browser.session.list", {
|
|
43
|
-
sessionId: "cli:local"
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("throws when --tenant is missing value", async () => {
|
|
48
|
-
await expect(runSessionListCommand(["--tenant"])).rejects.toThrow(
|
|
49
|
-
"Missing value for --tenant."
|
|
50
|
-
);
|
|
51
|
-
expect(callDaemonToolMock).not.toHaveBeenCalled();
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it("throws when --limit is missing value", async () => {
|
|
55
|
-
await expect(runSessionListCommand(["--limit"])).rejects.toThrow(
|
|
56
|
-
"Missing value for --limit."
|
|
57
|
-
);
|
|
58
|
-
expect(callDaemonToolMock).not.toHaveBeenCalled();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it("throws on invalid --limit", async () => {
|
|
62
|
-
await expect(runSessionListCommand(["--limit", "0"])).rejects.toThrow(
|
|
63
|
-
"--limit must be a positive integer."
|
|
64
|
-
);
|
|
65
|
-
expect(callDaemonToolMock).not.toHaveBeenCalled();
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it("rejects non-strict integer text for --limit", async () => {
|
|
69
|
-
await expect(runSessionListCommand(["--limit", "20abc"])).rejects.toThrow(
|
|
70
|
-
"--limit must be a positive integer."
|
|
71
|
-
);
|
|
72
|
-
expect(callDaemonToolMock).not.toHaveBeenCalled();
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it("throws on unknown option token", async () => {
|
|
76
|
-
await expect(runSessionListCommand(["--unknown"])).rejects.toThrow(
|
|
77
|
-
"Unknown session-list option: --unknown"
|
|
78
|
-
);
|
|
79
|
-
expect(callDaemonToolMock).not.toHaveBeenCalled();
|
|
80
|
-
});
|
|
81
|
-
});
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { callDaemonTool } from "../daemon-client";
|
|
2
|
-
import { buildToolArguments, parseCommandContext } from "./common";
|
|
3
|
-
|
|
4
|
-
export type SessionListCommandResult = Record<string, unknown>;
|
|
5
|
-
|
|
6
|
-
function parsePositiveInteger(value: string, optionName: string): number {
|
|
7
|
-
const normalized = value.trim();
|
|
8
|
-
if (!/^[1-9]\d*$/.test(normalized)) {
|
|
9
|
-
throw new Error(`${optionName} must be a positive integer.`);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
return Number.parseInt(normalized, 10);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function parseSessionListOptions(tokens: string[]): {
|
|
16
|
-
tenant?: string;
|
|
17
|
-
limit?: number;
|
|
18
|
-
} {
|
|
19
|
-
let tenant: string | undefined;
|
|
20
|
-
let limit: number | undefined;
|
|
21
|
-
|
|
22
|
-
for (let index = 0; index < tokens.length; index += 1) {
|
|
23
|
-
const token = tokens[index];
|
|
24
|
-
if (token === "--tenant") {
|
|
25
|
-
const value = tokens[index + 1];
|
|
26
|
-
if (value === undefined) {
|
|
27
|
-
throw new Error("Missing value for --tenant.");
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const trimmedValue = value.trim();
|
|
31
|
-
if (trimmedValue.length === 0) {
|
|
32
|
-
throw new Error("--tenant must be a non-empty string.");
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
tenant = trimmedValue;
|
|
36
|
-
index += 1;
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (token === "--limit") {
|
|
41
|
-
const value = tokens[index + 1];
|
|
42
|
-
if (value === undefined) {
|
|
43
|
-
throw new Error("Missing value for --limit.");
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
limit = parsePositiveInteger(value, "--limit");
|
|
47
|
-
index += 1;
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
throw new Error(`Unknown session-list option: ${token}`);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return {
|
|
55
|
-
...(tenant !== undefined ? { tenant } : {}),
|
|
56
|
-
...(limit !== undefined ? { limit } : {})
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export async function runSessionListCommand(args: string[]): Promise<SessionListCommandResult> {
|
|
61
|
-
const context = parseCommandContext(args);
|
|
62
|
-
const options = parseSessionListOptions(context.positional);
|
|
63
|
-
|
|
64
|
-
return await callDaemonTool<SessionListCommandResult>(
|
|
65
|
-
"browser.session.list",
|
|
66
|
-
buildToolArguments(context, {
|
|
67
|
-
...options
|
|
68
|
-
})
|
|
69
|
-
);
|
|
70
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { callDaemonTool } from "../daemon-client";
|
|
2
|
-
import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
|
|
3
|
-
|
|
4
|
-
export type SnapshotCommandResult = Record<string, unknown>;
|
|
5
|
-
|
|
6
|
-
export async function runSnapshotCommand(args: string[]): Promise<SnapshotCommandResult> {
|
|
7
|
-
const context = parseCommandContext(args);
|
|
8
|
-
const targetId = requirePositionalArg(context, 0, "targetId");
|
|
9
|
-
|
|
10
|
-
return await callDaemonTool<SnapshotCommandResult>(
|
|
11
|
-
"browser.snapshot",
|
|
12
|
-
buildToolArguments(context, {
|
|
13
|
-
targetId
|
|
14
|
-
})
|
|
15
|
-
);
|
|
16
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { callDaemonTool } from "../daemon-client";
|
|
2
|
-
import { buildToolArguments, parseCommandContext } from "./common";
|
|
3
|
-
|
|
4
|
-
export type StatusCommandResult = Record<string, unknown>;
|
|
5
|
-
|
|
6
|
-
export async function runStatusCommand(args: string[] = []): Promise<StatusCommandResult> {
|
|
7
|
-
const context = parseCommandContext(args);
|
|
8
|
-
|
|
9
|
-
return await callDaemonTool<StatusCommandResult>("browser.status", buildToolArguments(context));
|
|
10
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { callDaemonTool } from "../daemon-client";
|
|
2
|
-
import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
|
|
3
|
-
|
|
4
|
-
export type StorageGetCommandResult = Record<string, unknown>;
|
|
5
|
-
|
|
6
|
-
export async function runStorageGetCommand(args: string[]): Promise<StorageGetCommandResult> {
|
|
7
|
-
const context = parseCommandContext(args);
|
|
8
|
-
const targetId = requirePositionalArg(context, 0, "targetId");
|
|
9
|
-
const scope = requirePositionalArg(context, 1, "scope");
|
|
10
|
-
const key = requirePositionalArg(context, 2, "key");
|
|
11
|
-
|
|
12
|
-
return await callDaemonTool<StorageGetCommandResult>(
|
|
13
|
-
"browser.storage.get",
|
|
14
|
-
buildToolArguments(context, {
|
|
15
|
-
targetId,
|
|
16
|
-
scope,
|
|
17
|
-
key
|
|
18
|
-
})
|
|
19
|
-
);
|
|
20
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { callDaemonTool } from "../daemon-client";
|
|
2
|
-
import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
|
|
3
|
-
|
|
4
|
-
export type StorageSetCommandResult = Record<string, unknown>;
|
|
5
|
-
|
|
6
|
-
export async function runStorageSetCommand(args: string[]): Promise<StorageSetCommandResult> {
|
|
7
|
-
const context = parseCommandContext(args);
|
|
8
|
-
const targetId = requirePositionalArg(context, 0, "targetId");
|
|
9
|
-
const scope = requirePositionalArg(context, 1, "scope");
|
|
10
|
-
const key = requirePositionalArg(context, 2, "key");
|
|
11
|
-
const value = requirePositionalArg(context, 3, "value");
|
|
12
|
-
|
|
13
|
-
return await callDaemonTool<StorageSetCommandResult>(
|
|
14
|
-
"browser.storage.set",
|
|
15
|
-
buildToolArguments(context, {
|
|
16
|
-
targetId,
|
|
17
|
-
scope,
|
|
18
|
-
key,
|
|
19
|
-
value
|
|
20
|
-
})
|
|
21
|
-
);
|
|
22
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { callDaemonTool } from "../daemon-client";
|
|
2
|
-
import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
|
|
3
|
-
|
|
4
|
-
export type TabCloseCommandResult = {
|
|
5
|
-
driver: string;
|
|
6
|
-
targetId: string;
|
|
7
|
-
closed: boolean;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export async function runTabCloseCommand(args: string[]): Promise<TabCloseCommandResult> {
|
|
11
|
-
const context = parseCommandContext(args);
|
|
12
|
-
const targetId = requirePositionalArg(context, 0, "targetId");
|
|
13
|
-
|
|
14
|
-
return await callDaemonTool<TabCloseCommandResult>(
|
|
15
|
-
"browser.tab.close",
|
|
16
|
-
buildToolArguments(context, {
|
|
17
|
-
targetId
|
|
18
|
-
})
|
|
19
|
-
);
|
|
20
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { callDaemonTool } from "../daemon-client";
|
|
2
|
-
import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
|
|
3
|
-
|
|
4
|
-
export type TabFocusCommandResult = {
|
|
5
|
-
driver: string;
|
|
6
|
-
targetId: string;
|
|
7
|
-
focused: boolean;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export async function runTabFocusCommand(args: string[]): Promise<TabFocusCommandResult> {
|
|
11
|
-
const context = parseCommandContext(args);
|
|
12
|
-
const targetId = requirePositionalArg(context, 0, "targetId");
|
|
13
|
-
|
|
14
|
-
return await callDaemonTool<TabFocusCommandResult>(
|
|
15
|
-
"browser.tab.focus",
|
|
16
|
-
buildToolArguments(context, {
|
|
17
|
-
targetId
|
|
18
|
-
})
|
|
19
|
-
);
|
|
20
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { callDaemonTool } from "../daemon-client";
|
|
2
|
-
import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
|
|
3
|
-
|
|
4
|
-
export type TabOpenCommandResult = {
|
|
5
|
-
driver: string;
|
|
6
|
-
targetId: string;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export async function runTabOpenCommand(args: string[]): Promise<TabOpenCommandResult> {
|
|
10
|
-
const context = parseCommandContext(args);
|
|
11
|
-
const url = requirePositionalArg(context, 0, "url");
|
|
12
|
-
|
|
13
|
-
return await callDaemonTool<TabOpenCommandResult>(
|
|
14
|
-
"browser.tab.open",
|
|
15
|
-
buildToolArguments(context, {
|
|
16
|
-
url
|
|
17
|
-
})
|
|
18
|
-
);
|
|
19
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { callDaemonTool } from "../daemon-client";
|
|
2
|
-
import { buildToolArguments, parseCommandContext } from "./common";
|
|
3
|
-
|
|
4
|
-
export type TabsCommandResult = {
|
|
5
|
-
driver: string;
|
|
6
|
-
tabs: string[];
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export async function runTabsCommand(args: string[] = []): Promise<TabsCommandResult> {
|
|
10
|
-
const context = parseCommandContext(args);
|
|
11
|
-
|
|
12
|
-
return await callDaemonTool<TabsCommandResult>("browser.tab.list", buildToolArguments(context));
|
|
13
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
const { callDaemonToolMock } = vi.hoisted(() => ({
|
|
4
|
-
callDaemonToolMock: vi.fn()
|
|
5
|
-
}));
|
|
6
|
-
|
|
7
|
-
vi.mock("../daemon-client", () => ({
|
|
8
|
-
callDaemonTool: callDaemonToolMock
|
|
9
|
-
}));
|
|
10
|
-
|
|
11
|
-
import { runTraceGetCommand } from "./trace-get";
|
|
12
|
-
|
|
13
|
-
afterEach(() => {
|
|
14
|
-
callDaemonToolMock.mockReset();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
describe("runTraceGetCommand", () => {
|
|
18
|
-
it("forwards limit option", async () => {
|
|
19
|
-
callDaemonToolMock.mockResolvedValue({ ok: true });
|
|
20
|
-
|
|
21
|
-
await runTraceGetCommand(["--limit", "50"]);
|
|
22
|
-
|
|
23
|
-
expect(callDaemonToolMock).toHaveBeenCalledTimes(1);
|
|
24
|
-
expect(callDaemonToolMock).toHaveBeenCalledWith("browser.trace.get", {
|
|
25
|
-
sessionId: "cli:local",
|
|
26
|
-
limit: 50
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it("supports empty options", async () => {
|
|
31
|
-
callDaemonToolMock.mockResolvedValue({ ok: true });
|
|
32
|
-
|
|
33
|
-
await runTraceGetCommand([]);
|
|
34
|
-
|
|
35
|
-
expect(callDaemonToolMock).toHaveBeenCalledTimes(1);
|
|
36
|
-
expect(callDaemonToolMock).toHaveBeenCalledWith("browser.trace.get", {
|
|
37
|
-
sessionId: "cli:local"
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("throws when --limit is missing a value", async () => {
|
|
42
|
-
await expect(runTraceGetCommand(["--limit"]))
|
|
43
|
-
.rejects.toThrow("Missing value for --limit.");
|
|
44
|
-
|
|
45
|
-
expect(callDaemonToolMock).not.toHaveBeenCalled();
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("throws when --limit is invalid", async () => {
|
|
49
|
-
await expect(runTraceGetCommand(["--limit", "0"]))
|
|
50
|
-
.rejects.toThrow("--limit must be a positive integer.");
|
|
51
|
-
|
|
52
|
-
expect(callDaemonToolMock).not.toHaveBeenCalled();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("throws on unknown option token", async () => {
|
|
56
|
-
await expect(runTraceGetCommand(["--unknown"]))
|
|
57
|
-
.rejects.toThrow("Unknown trace-get option: --unknown");
|
|
58
|
-
|
|
59
|
-
expect(callDaemonToolMock).not.toHaveBeenCalled();
|
|
60
|
-
});
|
|
61
|
-
});
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { callDaemonTool } from "../daemon-client";
|
|
2
|
-
import { buildToolArguments, parseCommandContext } from "./common";
|
|
3
|
-
|
|
4
|
-
type TraceGetKeyResponse = {
|
|
5
|
-
stepIndex?: number;
|
|
6
|
-
kind?: string;
|
|
7
|
-
timestamp?: string;
|
|
8
|
-
data?: {
|
|
9
|
-
memoryHit?: boolean;
|
|
10
|
-
} & Record<string, unknown>;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export type TraceGetCommandResult = {
|
|
14
|
-
sessionId?: string;
|
|
15
|
-
steps?: Array<Record<string, unknown>>;
|
|
16
|
-
keyResponses?: TraceGetKeyResponse[];
|
|
17
|
-
screenshots?: Array<Record<string, unknown>>;
|
|
18
|
-
} & Record<string, unknown>;
|
|
19
|
-
|
|
20
|
-
function parsePositiveInteger(value: string, optionName: string): number {
|
|
21
|
-
const parsed = Number.parseInt(value, 10);
|
|
22
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
23
|
-
throw new Error(`${optionName} must be a positive integer.`);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return parsed;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function parseTraceGetOptions(tokens: string[]): {
|
|
30
|
-
limit?: number;
|
|
31
|
-
} {
|
|
32
|
-
let limit: number | undefined;
|
|
33
|
-
|
|
34
|
-
for (let index = 0; index < tokens.length; index += 1) {
|
|
35
|
-
const token = tokens[index];
|
|
36
|
-
if (token === "--limit") {
|
|
37
|
-
const value = tokens[index + 1];
|
|
38
|
-
if (value === undefined) {
|
|
39
|
-
throw new Error("Missing value for --limit.");
|
|
40
|
-
}
|
|
41
|
-
limit = parsePositiveInteger(value, "--limit");
|
|
42
|
-
index += 1;
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
throw new Error(`Unknown trace-get option: ${token}`);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return limit === undefined ? {} : { limit };
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export async function runTraceGetCommand(args: string[]): Promise<TraceGetCommandResult> {
|
|
53
|
-
const context = parseCommandContext(args);
|
|
54
|
-
const options = parseTraceGetOptions(context.positional);
|
|
55
|
-
|
|
56
|
-
return await callDaemonTool<TraceGetCommandResult>(
|
|
57
|
-
"browser.trace.get",
|
|
58
|
-
buildToolArguments(context, {
|
|
59
|
-
...options
|
|
60
|
-
})
|
|
61
|
-
);
|
|
62
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { callDaemonTool } from "../daemon-client";
|
|
2
|
-
import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
|
|
3
|
-
|
|
4
|
-
export type UploadArmCommandResult = {
|
|
5
|
-
driver: string;
|
|
6
|
-
targetId: string;
|
|
7
|
-
armed: boolean;
|
|
8
|
-
files: string[];
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export async function runUploadArmCommand(args: string[]): Promise<UploadArmCommandResult> {
|
|
12
|
-
const context = parseCommandContext(args);
|
|
13
|
-
const targetId = requirePositionalArg(context, 0, "targetId");
|
|
14
|
-
const files = context.positional.slice(1);
|
|
15
|
-
if (files.length === 0) {
|
|
16
|
-
throw new Error("Missing required argument: files.");
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return await callDaemonTool<UploadArmCommandResult>(
|
|
20
|
-
"browser.upload.arm",
|
|
21
|
-
buildToolArguments(context, {
|
|
22
|
-
targetId,
|
|
23
|
-
files
|
|
24
|
-
})
|
|
25
|
-
);
|
|
26
|
-
}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
const { callDaemonToolMock } = vi.hoisted(() => ({
|
|
4
|
-
callDaemonToolMock: vi.fn()
|
|
5
|
-
}));
|
|
6
|
-
|
|
7
|
-
vi.mock("../daemon-client", () => ({
|
|
8
|
-
callDaemonTool: callDaemonToolMock
|
|
9
|
-
}));
|
|
10
|
-
|
|
11
|
-
import { runWaitElementCommand } from "./wait-element";
|
|
12
|
-
|
|
13
|
-
afterEach(() => {
|
|
14
|
-
callDaemonToolMock.mockReset();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
describe("runWaitElementCommand", () => {
|
|
18
|
-
it("supports positional timeout shorthand", async () => {
|
|
19
|
-
callDaemonToolMock.mockResolvedValue({ ok: true });
|
|
20
|
-
|
|
21
|
-
await runWaitElementCommand(["target:1", "#root", "2500"]);
|
|
22
|
-
|
|
23
|
-
expect(callDaemonToolMock).toHaveBeenCalledTimes(1);
|
|
24
|
-
expect(callDaemonToolMock).toHaveBeenCalledWith("browser.wait.element", {
|
|
25
|
-
sessionId: "cli:local",
|
|
26
|
-
targetId: "target:1",
|
|
27
|
-
selector: "#root",
|
|
28
|
-
timeoutMs: 2500
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it.each([
|
|
33
|
-
{
|
|
34
|
-
label: "--timeout-ms",
|
|
35
|
-
args: ["target:1", "#root", "--timeout-ms"],
|
|
36
|
-
message: "Missing value for --timeout-ms."
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
label: "--poll-ms",
|
|
40
|
-
args: ["target:1", "#root", "--poll-ms"],
|
|
41
|
-
message: "Missing value for --poll-ms."
|
|
42
|
-
}
|
|
43
|
-
])("throws when $label is missing a value", async ({ args, message }) => {
|
|
44
|
-
await expect(runWaitElementCommand(args)).rejects.toThrow(message);
|
|
45
|
-
expect(callDaemonToolMock).not.toHaveBeenCalled();
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it.each([
|
|
49
|
-
{
|
|
50
|
-
label: "timeout <= 0",
|
|
51
|
-
args: ["target:1", "#root", "--timeout-ms", "0"],
|
|
52
|
-
message: "--timeout-ms must be a positive integer."
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
label: "poll <= 0",
|
|
56
|
-
args: ["target:1", "#root", "--poll-ms", "-1"],
|
|
57
|
-
message: "--poll-ms must be a positive integer."
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
label: "positional timeout <= 0",
|
|
61
|
-
args: ["target:1", "#root", "0"],
|
|
62
|
-
message: "timeoutMs must be a positive integer."
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
label: "non-strict timeout text",
|
|
66
|
-
args: ["target:1", "#root", "--timeout-ms", "1200abc"],
|
|
67
|
-
message: "--timeout-ms must be a positive integer."
|
|
68
|
-
}
|
|
69
|
-
])("throws on non-positive numeric option: $label", async ({ args, message }) => {
|
|
70
|
-
await expect(runWaitElementCommand(args)).rejects.toThrow(message);
|
|
71
|
-
expect(callDaemonToolMock).not.toHaveBeenCalled();
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("throws on unknown option token", async () => {
|
|
75
|
-
await expect(runWaitElementCommand(["target:1", "#root", "1200", "--unknown"]))
|
|
76
|
-
.rejects.toThrow("Unknown wait-element option: --unknown");
|
|
77
|
-
|
|
78
|
-
expect(callDaemonToolMock).not.toHaveBeenCalled();
|
|
79
|
-
});
|
|
80
|
-
});
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { callDaemonTool } from "../daemon-client";
|
|
2
|
-
import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
|
|
3
|
-
|
|
4
|
-
export type WaitElementCommandResult = Record<string, unknown>;
|
|
5
|
-
|
|
6
|
-
function parsePositiveInteger(value: string, optionName: string): number {
|
|
7
|
-
const normalized = value.trim();
|
|
8
|
-
if (!/^[1-9]\d*$/.test(normalized)) {
|
|
9
|
-
throw new Error(`${optionName} must be a positive integer.`);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
return Number.parseInt(normalized, 10);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function parseWaitOptions(tokens: string[]): {
|
|
16
|
-
timeoutMs?: number;
|
|
17
|
-
pollMs?: number;
|
|
18
|
-
} {
|
|
19
|
-
let timeoutMs: number | undefined;
|
|
20
|
-
let pollMs: number | undefined;
|
|
21
|
-
|
|
22
|
-
for (let index = 0; index < tokens.length; index += 1) {
|
|
23
|
-
const token = tokens[index];
|
|
24
|
-
if (token === "--timeout-ms") {
|
|
25
|
-
const value = tokens[index + 1];
|
|
26
|
-
if (value === undefined) {
|
|
27
|
-
throw new Error("Missing value for --timeout-ms.");
|
|
28
|
-
}
|
|
29
|
-
timeoutMs = parsePositiveInteger(value, "--timeout-ms");
|
|
30
|
-
index += 1;
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (token === "--poll-ms") {
|
|
35
|
-
const value = tokens[index + 1];
|
|
36
|
-
if (value === undefined) {
|
|
37
|
-
throw new Error("Missing value for --poll-ms.");
|
|
38
|
-
}
|
|
39
|
-
pollMs = parsePositiveInteger(value, "--poll-ms");
|
|
40
|
-
index += 1;
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (token.startsWith("--")) {
|
|
45
|
-
throw new Error(`Unknown wait-element option: ${token}`);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (timeoutMs === undefined) {
|
|
49
|
-
timeoutMs = parsePositiveInteger(token, "timeoutMs");
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
throw new Error(`Unknown wait-element option: ${token}`);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return {
|
|
57
|
-
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
58
|
-
...(pollMs !== undefined ? { pollMs } : {})
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export async function runWaitElementCommand(args: string[]): Promise<WaitElementCommandResult> {
|
|
63
|
-
const context = parseCommandContext(args);
|
|
64
|
-
const targetId = requirePositionalArg(context, 0, "targetId");
|
|
65
|
-
const selector = requirePositionalArg(context, 1, "selector");
|
|
66
|
-
const options = parseWaitOptions(context.positional.slice(2));
|
|
67
|
-
|
|
68
|
-
return await callDaemonTool<WaitElementCommandResult>(
|
|
69
|
-
"browser.wait.element",
|
|
70
|
-
buildToolArguments(context, {
|
|
71
|
-
targetId,
|
|
72
|
-
selector,
|
|
73
|
-
...options
|
|
74
|
-
})
|
|
75
|
-
);
|
|
76
|
-
}
|