mirror of https://github.com/openclaw/openclaw.git
161 lines
4.7 KiB
TypeScript
161 lines
4.7 KiB
TypeScript
import { fetch as realFetch } from "undici";
|
|
import { describe, expect, it } from "vitest";
|
|
import { DEFAULT_AI_SNAPSHOT_MAX_CHARS } from "./constants.js";
|
|
import {
|
|
installAgentContractHooks,
|
|
postJson,
|
|
startServerAndBase,
|
|
} from "./server.agent-contract.test-harness.js";
|
|
import {
|
|
getBrowserControlServerTestState,
|
|
getCdpMocks,
|
|
getPwMocks,
|
|
} from "./server.control-server.test-harness.js";
|
|
|
|
const state = getBrowserControlServerTestState();
|
|
const cdpMocks = getCdpMocks();
|
|
const pwMocks = getPwMocks();
|
|
|
|
describe("browser control server", () => {
|
|
installAgentContractHooks();
|
|
|
|
it("agent contract: snapshot endpoints", async () => {
|
|
const base = await startServerAndBase();
|
|
|
|
const snapAria = (await realFetch(`${base}/snapshot?format=aria&limit=1`).then((r) =>
|
|
r.json(),
|
|
)) as { ok: boolean; format?: string };
|
|
expect(snapAria.ok).toBe(true);
|
|
expect(snapAria.format).toBe("aria");
|
|
expect(cdpMocks.snapshotAria).toHaveBeenCalledWith({
|
|
wsUrl: "ws://127.0.0.1/devtools/page/abcd1234",
|
|
limit: 1,
|
|
});
|
|
|
|
const snapAi = (await realFetch(`${base}/snapshot?format=ai`).then((r) => r.json())) as {
|
|
ok: boolean;
|
|
format?: string;
|
|
};
|
|
expect(snapAi.ok).toBe(true);
|
|
expect(snapAi.format).toBe("ai");
|
|
expect(pwMocks.snapshotAiViaPlaywright).toHaveBeenCalledWith({
|
|
cdpUrl: state.cdpBaseUrl,
|
|
targetId: "abcd1234",
|
|
maxChars: DEFAULT_AI_SNAPSHOT_MAX_CHARS,
|
|
});
|
|
|
|
const snapAiZero = (await realFetch(`${base}/snapshot?format=ai&maxChars=0`).then((r) =>
|
|
r.json(),
|
|
)) as { ok: boolean; format?: string };
|
|
expect(snapAiZero.ok).toBe(true);
|
|
expect(snapAiZero.format).toBe("ai");
|
|
const [lastCall] = pwMocks.snapshotAiViaPlaywright.mock.calls.at(-1) ?? [];
|
|
expect(lastCall).toEqual({
|
|
cdpUrl: state.cdpBaseUrl,
|
|
targetId: "abcd1234",
|
|
});
|
|
});
|
|
|
|
it("agent contract: navigation + common act commands", async () => {
|
|
const base = await startServerAndBase();
|
|
|
|
const nav = await postJson<{ ok: boolean; targetId?: string }>(`${base}/navigate`, {
|
|
url: "https://example.com",
|
|
});
|
|
expect(nav.ok).toBe(true);
|
|
expect(typeof nav.targetId).toBe("string");
|
|
expect(pwMocks.navigateViaPlaywright).toHaveBeenCalledWith({
|
|
cdpUrl: state.cdpBaseUrl,
|
|
targetId: "abcd1234",
|
|
url: "https://example.com",
|
|
});
|
|
|
|
const click = await postJson<{ ok: boolean }>(`${base}/act`, {
|
|
kind: "click",
|
|
ref: "1",
|
|
button: "left",
|
|
modifiers: ["Shift"],
|
|
});
|
|
expect(click.ok).toBe(true);
|
|
expect(pwMocks.clickViaPlaywright).toHaveBeenNthCalledWith(1, {
|
|
cdpUrl: state.cdpBaseUrl,
|
|
targetId: "abcd1234",
|
|
ref: "1",
|
|
doubleClick: false,
|
|
button: "left",
|
|
modifiers: ["Shift"],
|
|
});
|
|
|
|
const clickSelector = await realFetch(`${base}/act`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ kind: "click", selector: "button.save" }),
|
|
});
|
|
expect(clickSelector.status).toBe(400);
|
|
expect(((await clickSelector.json()) as { error?: string }).error).toMatch(
|
|
/'selector' is not supported/i,
|
|
);
|
|
|
|
const type = await postJson<{ ok: boolean }>(`${base}/act`, {
|
|
kind: "type",
|
|
ref: "1",
|
|
text: "",
|
|
});
|
|
expect(type.ok).toBe(true);
|
|
expect(pwMocks.typeViaPlaywright).toHaveBeenNthCalledWith(1, {
|
|
cdpUrl: state.cdpBaseUrl,
|
|
targetId: "abcd1234",
|
|
ref: "1",
|
|
text: "",
|
|
submit: false,
|
|
slowly: false,
|
|
});
|
|
|
|
const press = await postJson<{ ok: boolean }>(`${base}/act`, {
|
|
kind: "press",
|
|
key: "Enter",
|
|
});
|
|
expect(press.ok).toBe(true);
|
|
expect(pwMocks.pressKeyViaPlaywright).toHaveBeenCalledWith({
|
|
cdpUrl: state.cdpBaseUrl,
|
|
targetId: "abcd1234",
|
|
key: "Enter",
|
|
});
|
|
|
|
const hover = await postJson<{ ok: boolean }>(`${base}/act`, {
|
|
kind: "hover",
|
|
ref: "2",
|
|
});
|
|
expect(hover.ok).toBe(true);
|
|
expect(pwMocks.hoverViaPlaywright).toHaveBeenCalledWith({
|
|
cdpUrl: state.cdpBaseUrl,
|
|
targetId: "abcd1234",
|
|
ref: "2",
|
|
});
|
|
|
|
const scroll = await postJson<{ ok: boolean }>(`${base}/act`, {
|
|
kind: "scrollIntoView",
|
|
ref: "2",
|
|
});
|
|
expect(scroll.ok).toBe(true);
|
|
expect(pwMocks.scrollIntoViewViaPlaywright).toHaveBeenCalledWith({
|
|
cdpUrl: state.cdpBaseUrl,
|
|
targetId: "abcd1234",
|
|
ref: "2",
|
|
});
|
|
|
|
const drag = await postJson<{ ok: boolean }>(`${base}/act`, {
|
|
kind: "drag",
|
|
startRef: "3",
|
|
endRef: "4",
|
|
});
|
|
expect(drag.ok).toBe(true);
|
|
expect(pwMocks.dragViaPlaywright).toHaveBeenCalledWith({
|
|
cdpUrl: state.cdpBaseUrl,
|
|
targetId: "abcd1234",
|
|
startRef: "3",
|
|
endRef: "4",
|
|
});
|
|
});
|
|
});
|