import test from "node:test"; import assert from "node:assert/strict"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { buildBrowserControlTaskExecution, canHandleBrowserControlTask, executeBrowserControlTask, getBrowserControlTaskRunnerConfig, parseBrowserControlTaskResult, } from "../local-agent/browser-control-task-runner.mjs"; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); test("browser control runner handles browser_control tasks", async () => { assert.equal( canHandleBrowserControlTask({ taskType: "browser_control", requestText: "打开后台首页", }), true, ); }); test("browser control runner derives config from explicit values", () => { const config = getBrowserControlTaskRunnerConfig({}, { browserControlEnabled: true, browserControlCommand: "node", browserControlArgs: ["tests/fixtures/browser-control-runtime.mjs"], browserControlWorkdir: repoRoot, browserControlTimeoutMs: 12000, }); assert.equal(config.enabled, true); assert.equal(config.command, "node"); assert.deepEqual(config.args, ["tests/fixtures/browser-control-runtime.mjs"]); assert.equal(config.cwd, repoRoot); assert.equal(config.timeoutMs, 12000); }); test("browser control runner builds normalized stdin payload", () => { const execution = buildBrowserControlTaskExecution( { enabled: true, command: "node", args: ["tests/fixtures/browser-control-runtime.mjs"], cwd: repoRoot, timeoutMs: 3000, }, { taskId: "browser-task-1", taskType: "browser_control", requestText: "打开后台首页", projectId: "boss-console", threadId: "thread-1", requestedByAccount: "17600001111", confirmationScopeKey: "thread:1", riskLevel: "medium", }, ); assert.equal(execution.command, "node"); assert.equal(execution.cwd, repoRoot); assert.equal(execution.timeoutMs, 3000); assert.equal(execution.stdinPayload.requestKind, "browser_control"); assert.equal(execution.stdinPayload.requestId, "browser-task-1"); assert.equal(execution.stdinPayload.objective, "打开后台首页"); assert.equal(execution.stdinPayload.context.projectId, "boss-console"); assert.equal(execution.stdinPayload.context.threadId, "thread-1"); assert.equal(execution.stdinPayload.context.confirmationScopeKey, "thread:1"); assert.equal(execution.stdinPayload.context.riskLevel, "medium"); }); test("browser control runner parses completed runtime payload", () => { const result = parseBrowserControlTaskResult( '{"status":"completed","replyBody":"已打开后台首页","executionSummary":"browser ok"}', ); assert.equal(result.status, "completed"); assert.equal(result.replyBody, "已打开后台首页"); assert.equal(result.executionSummary, "browser ok"); }); test("browser control runner parses failed runtime payload", () => { const result = parseBrowserControlTaskResult('{"status":"failed","error":"BROWSER_DENIED"}'); assert.equal(result.status, "failed"); assert.equal(result.errorMessage, "BROWSER_DENIED"); }); test("browser control runner executes configured runtime command", async () => { const result = await executeBrowserControlTask( { taskId: "browser-task-exec", taskType: "browser_control", requestText: "打开用户后台", projectId: "boss-console", threadId: "thread-browser", requestedByAccount: "17600002222", }, { browserControlEnabled: true, browserControlCommand: process.execPath, browserControlArgs: ["tests/fixtures/browser-control-runtime.mjs"], browserControlWorkdir: repoRoot, browserControlTimeoutMs: 4000, }, ); assert.equal(result.status, "completed"); assert.match(result.replyBody ?? "", /浏览器运行时已执行/); assert.match(result.replyBody ?? "", /打开用户后台/); }); test("browser control runner reports disabled runtime instead of pretending browser work completed", async () => { const result = await executeBrowserControlTask({ taskId: "task-browser-control", requestText: "打开后台首页", }, {}); assert.equal(result.status, "failed"); assert.equal(result.errorMessage, "BROWSER_CONTROL_RUNTIME_DISABLED"); });