mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 19:10:58 +00:00
perf(test): trim browser smoke and speed canvas test reload
This commit is contained in:
@@ -275,7 +275,7 @@ describe("browser control server", () => {
|
|||||||
await stopBrowserControlServer();
|
await stopBrowserControlServer();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("covers primary control routes, validation, and attach-only compatibility", async () => {
|
it("covers primary control routes, validation, and profile compatibility", async () => {
|
||||||
const { startBrowserControlServerFromConfig } = await import("./server.js");
|
const { startBrowserControlServerFromConfig } = await import("./server.js");
|
||||||
const started = await startBrowserControlServerFromConfig();
|
const started = await startBrowserControlServerFromConfig();
|
||||||
expect(started?.port).toBe(testPort);
|
expect(started?.port).toBe(testPort);
|
||||||
@@ -356,78 +356,32 @@ describe("browser control server", () => {
|
|||||||
});
|
});
|
||||||
expect(focusMissing.status).toBe(404);
|
expect(focusMissing.status).toBe(404);
|
||||||
|
|
||||||
const [
|
const [navMissing, clickMissingRef, scrollSelectorUnsupported, dialogMissingAccept] =
|
||||||
navMissing,
|
await Promise.all([
|
||||||
actMissing,
|
realFetch(`${base}/navigate`, {
|
||||||
clickMissingRef,
|
method: "POST",
|
||||||
scrollMissingRef,
|
headers: { "Content-Type": "application/json" },
|
||||||
scrollSelectorUnsupported,
|
body: JSON.stringify({}),
|
||||||
clickBadButton,
|
}),
|
||||||
clickBadModifiers,
|
realFetch(`${base}/act`, {
|
||||||
typeBadText,
|
method: "POST",
|
||||||
uploadMissingPaths,
|
headers: { "Content-Type": "application/json" },
|
||||||
dialogMissingAccept,
|
body: JSON.stringify({ kind: "click" }),
|
||||||
] = await Promise.all([
|
}),
|
||||||
realFetch(`${base}/navigate`, {
|
realFetch(`${base}/act`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({}),
|
body: JSON.stringify({ kind: "scrollIntoView", selector: "button.save" }),
|
||||||
}),
|
}),
|
||||||
realFetch(`${base}/act`, {
|
realFetch(`${base}/hooks/dialog`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({}),
|
body: JSON.stringify({}),
|
||||||
}),
|
}),
|
||||||
realFetch(`${base}/act`, {
|
]);
|
||||||
method: "POST",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({ kind: "click" }),
|
|
||||||
}),
|
|
||||||
realFetch(`${base}/act`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({ kind: "scrollIntoView" }),
|
|
||||||
}),
|
|
||||||
realFetch(`${base}/act`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({ kind: "scrollIntoView", selector: "button.save" }),
|
|
||||||
}),
|
|
||||||
realFetch(`${base}/act`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({ kind: "click", ref: "1", button: "nope" }),
|
|
||||||
}),
|
|
||||||
realFetch(`${base}/act`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({ kind: "click", ref: "1", modifiers: ["Nope"] }),
|
|
||||||
}),
|
|
||||||
realFetch(`${base}/act`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({ kind: "type", ref: "1", text: 123 }),
|
|
||||||
}),
|
|
||||||
realFetch(`${base}/hooks/file-chooser`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({}),
|
|
||||||
}),
|
|
||||||
realFetch(`${base}/hooks/dialog`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({}),
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
expect(navMissing.status).toBe(400);
|
expect(navMissing.status).toBe(400);
|
||||||
expect(actMissing.status).toBe(400);
|
|
||||||
expect(clickMissingRef.status).toBe(400);
|
expect(clickMissingRef.status).toBe(400);
|
||||||
expect(scrollMissingRef.status).toBe(400);
|
|
||||||
expect(scrollSelectorUnsupported.status).toBe(400);
|
expect(scrollSelectorUnsupported.status).toBe(400);
|
||||||
expect(clickBadButton.status).toBe(400);
|
|
||||||
expect(clickBadModifiers.status).toBe(400);
|
|
||||||
expect(typeBadText.status).toBe(400);
|
|
||||||
expect(uploadMissingPaths.status).toBe(400);
|
|
||||||
expect(dialogMissingAccept.status).toBe(400);
|
expect(dialogMissingAccept.status).toBe(400);
|
||||||
|
|
||||||
const snapDefault = (await realFetch(`${base}/snapshot?format=wat`).then((r) => r.json())) as {
|
const snapDefault = (await realFetch(`${base}/snapshot?format=wat`).then((r) => r.json())) as {
|
||||||
@@ -499,50 +453,5 @@ describe("browser control server", () => {
|
|||||||
body: JSON.stringify({}),
|
body: JSON.stringify({}),
|
||||||
});
|
});
|
||||||
expect(missing.status).toBe(400);
|
expect(missing.status).toBe(400);
|
||||||
|
|
||||||
reachable = false;
|
|
||||||
cfgAttachOnly = true;
|
|
||||||
const attachStarted = (await realFetch(`${base}/start`, {
|
|
||||||
method: "POST",
|
|
||||||
}).then((r) => r.json())) as { error?: string };
|
|
||||||
expect(attachStarted.error ?? "").toMatch(/attachOnly/i);
|
|
||||||
|
|
||||||
const { startBrowserBridgeServer } = await import("./bridge-server.js");
|
|
||||||
|
|
||||||
const ensured = vi.fn(async () => {
|
|
||||||
reachable = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
const bridge = await startBrowserBridgeServer({
|
|
||||||
resolved: {
|
|
||||||
enabled: true,
|
|
||||||
controlPort: 0,
|
|
||||||
cdpProtocol: "http",
|
|
||||||
cdpHost: "127.0.0.1",
|
|
||||||
cdpIsLoopback: true,
|
|
||||||
color: "#FF4500",
|
|
||||||
headless: true,
|
|
||||||
noSandbox: false,
|
|
||||||
attachOnly: true,
|
|
||||||
defaultProfile: "openclaw",
|
|
||||||
profiles: {
|
|
||||||
openclaw: { cdpPort: testPort + 1, color: "#FF4500" },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
onEnsureAttachTarget: ensured,
|
|
||||||
});
|
|
||||||
|
|
||||||
const bridgeStarted = (await realFetch(`${bridge.baseUrl}/start`, {
|
|
||||||
method: "POST",
|
|
||||||
}).then((r) => r.json())) as { ok?: boolean; error?: string };
|
|
||||||
expect(bridgeStarted.error).toBeUndefined();
|
|
||||||
expect(bridgeStarted.ok).toBe(true);
|
|
||||||
const status = (await realFetch(`${bridge.baseUrl}/`).then((r) => r.json())) as {
|
|
||||||
running?: boolean;
|
|
||||||
};
|
|
||||||
expect(status.running).toBe(true);
|
|
||||||
expect(ensured).toHaveBeenCalledTimes(1);
|
|
||||||
|
|
||||||
await new Promise<void>((resolve) => bridge.server.close(() => resolve()));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -264,6 +264,10 @@ export async function createCanvasHostHandler(
|
|||||||
const rootReal = await prepareCanvasRoot(rootDir);
|
const rootReal = await prepareCanvasRoot(rootDir);
|
||||||
|
|
||||||
const liveReload = opts.liveReload !== false;
|
const liveReload = opts.liveReload !== false;
|
||||||
|
const testMode = opts.allowInTests === true;
|
||||||
|
const reloadDebounceMs = testMode ? 12 : 75;
|
||||||
|
const writeStabilityThresholdMs = testMode ? 12 : 75;
|
||||||
|
const writePollIntervalMs = testMode ? 5 : 10;
|
||||||
const wss = liveReload ? new WebSocketServer({ noServer: true }) : null;
|
const wss = liveReload ? new WebSocketServer({ noServer: true }) : null;
|
||||||
const sockets = new Set<WebSocket>();
|
const sockets = new Set<WebSocket>();
|
||||||
if (wss) {
|
if (wss) {
|
||||||
@@ -293,7 +297,7 @@ export async function createCanvasHostHandler(
|
|||||||
debounce = setTimeout(() => {
|
debounce = setTimeout(() => {
|
||||||
debounce = null;
|
debounce = null;
|
||||||
broadcastReload();
|
broadcastReload();
|
||||||
}, 75);
|
}, reloadDebounceMs);
|
||||||
debounce.unref?.();
|
debounce.unref?.();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -301,8 +305,11 @@ export async function createCanvasHostHandler(
|
|||||||
const watcher = liveReload
|
const watcher = liveReload
|
||||||
? chokidar.watch(rootReal, {
|
? chokidar.watch(rootReal, {
|
||||||
ignoreInitial: true,
|
ignoreInitial: true,
|
||||||
awaitWriteFinish: { stabilityThreshold: 75, pollInterval: 10 },
|
awaitWriteFinish: {
|
||||||
usePolling: opts.allowInTests === true,
|
stabilityThreshold: writeStabilityThresholdMs,
|
||||||
|
pollInterval: writePollIntervalMs,
|
||||||
|
},
|
||||||
|
usePolling: testMode,
|
||||||
ignored: [
|
ignored: [
|
||||||
/(^|[\\/])\../, // dotfiles
|
/(^|[\\/])\../, // dotfiles
|
||||||
/(^|[\\/])node_modules([\\/]|$)/,
|
/(^|[\\/])node_modules([\\/]|$)/,
|
||||||
|
|||||||
Reference in New Issue
Block a user