refactor: route browser control via gateway/node

This commit is contained in:
Peter Steinberger
2026-01-27 03:23:42 +00:00
parent b151b8d196
commit e7fdccce39
91 changed files with 1909 additions and 1608 deletions

View File

@@ -2,13 +2,14 @@ import { describe, expect, it } from "vitest";
import { resolveBrowserConfig, resolveProfile, shouldStartLocalBrowserServer } from "./config.js";
describe("browser config", () => {
it("defaults to enabled with loopback control url and lobster-orange color", () => {
it("defaults to enabled with loopback defaults and lobster-orange color", () => {
const resolved = resolveBrowserConfig(undefined);
expect(resolved.enabled).toBe(true);
expect(resolved.controlPort).toBe(18791);
expect(resolved.controlHost).toBe("127.0.0.1");
expect(resolved.color).toBe("#FF4500");
expect(shouldStartLocalBrowserServer(resolved)).toBe(true);
expect(resolved.cdpHost).toBe("127.0.0.1");
expect(resolved.cdpProtocol).toBe("http");
const profile = resolveProfile(resolved, resolved.defaultProfile);
expect(profile?.name).toBe("chrome");
expect(profile?.driver).toBe("extension");
@@ -46,9 +47,31 @@ describe("browser config", () => {
}
});
it("derives default ports from gateway.port when env is unset", () => {
const prev = process.env.CLAWDBOT_GATEWAY_PORT;
delete process.env.CLAWDBOT_GATEWAY_PORT;
try {
const resolved = resolveBrowserConfig(undefined, { gateway: { port: 19011 } });
expect(resolved.controlPort).toBe(19013);
const chrome = resolveProfile(resolved, "chrome");
expect(chrome?.driver).toBe("extension");
expect(chrome?.cdpPort).toBe(19014);
expect(chrome?.cdpUrl).toBe("http://127.0.0.1:19014");
const clawd = resolveProfile(resolved, "clawd");
expect(clawd?.cdpPort).toBe(19022);
expect(clawd?.cdpUrl).toBe("http://127.0.0.1:19022");
} finally {
if (prev === undefined) {
delete process.env.CLAWDBOT_GATEWAY_PORT;
} else {
process.env.CLAWDBOT_GATEWAY_PORT = prev;
}
}
});
it("normalizes hex colors", () => {
const resolved = resolveBrowserConfig({
controlUrl: "http://localhost:18791",
color: "ff4500",
});
expect(resolved.color).toBe("#FF4500");
@@ -56,7 +79,6 @@ describe("browser config", () => {
it("supports custom remote CDP timeouts", () => {
const resolved = resolveBrowserConfig({
controlUrl: "http://127.0.0.1:18791",
remoteCdpTimeoutMs: 2200,
remoteCdpHandshakeTimeoutMs: 5000,
});
@@ -66,31 +88,21 @@ describe("browser config", () => {
it("falls back to default color for invalid hex", () => {
const resolved = resolveBrowserConfig({
controlUrl: "http://localhost:18791",
color: "#GGGGGG",
});
expect(resolved.color).toBe("#FF4500");
});
it("treats non-loopback control urls as remote", () => {
it("treats non-loopback cdpUrl as remote", () => {
const resolved = resolveBrowserConfig({
controlUrl: "http://example.com:18791",
cdpUrl: "http://example.com:9222",
});
expect(shouldStartLocalBrowserServer(resolved)).toBe(false);
});
it("derives CDP host/protocol from control url when cdpUrl is unset", () => {
const resolved = resolveBrowserConfig({
controlUrl: "http://127.0.0.1:19000",
});
expect(resolved.controlPort).toBe(19000);
expect(resolved.cdpHost).toBe("127.0.0.1");
expect(resolved.cdpProtocol).toBe("http");
const profile = resolveProfile(resolved, "clawd");
expect(profile?.cdpIsLoopback).toBe(false);
});
it("supports explicit CDP URLs for the default profile", () => {
const resolved = resolveBrowserConfig({
controlUrl: "http://127.0.0.1:18791",
cdpUrl: "http://example.com:9222",
});
const profile = resolveProfile(resolved, "clawd");
@@ -101,7 +113,6 @@ describe("browser config", () => {
it("uses profile cdpUrl when provided", () => {
const resolved = resolveBrowserConfig({
controlUrl: "http://127.0.0.1:18791",
profiles: {
remote: { cdpUrl: "http://10.0.0.42:9222", color: "#0066CC" },
},
@@ -115,7 +126,6 @@ describe("browser config", () => {
it("uses base protocol for profiles with only cdpPort", () => {
const resolved = resolveBrowserConfig({
controlUrl: "http://127.0.0.1:18791",
cdpUrl: "https://example.com:9443",
profiles: {
work: { cdpPort: 18801, color: "#0066CC" },
@@ -127,14 +137,11 @@ describe("browser config", () => {
});
it("rejects unsupported protocols", () => {
expect(() => resolveBrowserConfig({ controlUrl: "ws://127.0.0.1:18791" })).toThrow(
/must be http/i,
);
expect(() => resolveBrowserConfig({ cdpUrl: "ws://127.0.0.1:18791" })).toThrow(/must be http/i);
});
it("does not add the built-in chrome extension profile if the derived relay port is already used", () => {
const resolved = resolveBrowserConfig({
controlUrl: "http://127.0.0.1:18791",
profiles: {
clawd: { cdpPort: 18792, color: "#FF4500" },
},