fix: stop forcing an extra blank tab on browser launch

This commit is contained in:
Roger Deng
2026-03-23 03:11:37 +08:00
committed by Peter Steinberger
parent 58c3f8673a
commit 72d775e069
2 changed files with 90 additions and 35 deletions

View File

@@ -0,0 +1,47 @@
import { describe, expect, it } from "vitest";
import { buildOpenClawChromeLaunchArgs } from "./chrome.js";
describe("browser chrome launch args", () => {
it("does not force an about:blank tab at startup", () => {
const args = buildOpenClawChromeLaunchArgs({
resolved: {
enabled: true,
controlPort: 18791,
cdpProtocol: "http",
cdpHost: "127.0.0.1",
cdpIsLoopback: true,
cdpPortRangeStart: 18800,
cdpPortRangeEnd: 18810,
evaluateEnabled: false,
remoteCdpTimeoutMs: 1500,
remoteCdpHandshakeTimeoutMs: 3000,
extraArgs: [],
color: "#FF4500",
headless: false,
noSandbox: false,
attachOnly: false,
ssrfPolicy: { allowPrivateNetwork: true },
defaultProfile: "openclaw",
profiles: {
openclaw: { cdpPort: 18800, color: "#FF4500" },
},
},
profile: {
name: "openclaw",
cdpUrl: "http://127.0.0.1:18800",
cdpPort: 18800,
cdpHost: "127.0.0.1",
cdpProtocol: "http",
cdpPath: "",
cdpIsLoopback: true,
color: "#FF4500",
auth: undefined,
},
userDataDir: "/tmp/openclaw-test-user-data",
});
expect(args).not.toContain("about:blank");
expect(args).toContain("--remote-debugging-port=18800");
expect(args).toContain("--user-data-dir=/tmp/openclaw-test-user-data");
});
});

View File

@@ -85,6 +85,44 @@ function cdpUrlForPort(cdpPort: number) {
return `http://127.0.0.1:${cdpPort}`;
}
export function buildOpenClawChromeLaunchArgs(params: {
resolved: ResolvedBrowserConfig;
profile: ResolvedBrowserProfile;
userDataDir: string;
}): string[] {
const { resolved, profile, userDataDir } = params;
const args: string[] = [
`--remote-debugging-port=${profile.cdpPort}`,
`--user-data-dir=${userDataDir}`,
"--no-first-run",
"--no-default-browser-check",
"--disable-sync",
"--disable-background-networking",
"--disable-component-update",
"--disable-features=Translate,MediaRouter",
"--disable-session-crashed-bubble",
"--hide-crash-restore-bubble",
"--password-store=basic",
];
if (resolved.headless) {
args.push("--headless=new");
args.push("--disable-gpu");
}
if (resolved.noSandbox) {
args.push("--no-sandbox");
args.push("--disable-setuid-sandbox");
}
if (process.platform === "linux") {
args.push("--disable-dev-shm-usage");
}
if (resolved.extraArgs.length > 0) {
args.push(...resolved.extraArgs);
}
return args;
}
async function canOpenWebSocket(url: string, timeoutMs: number): Promise<boolean> {
return new Promise<boolean>((resolve) => {
const ws = openCdpWebSocket(url, { handshakeTimeoutMs: timeoutMs });
@@ -280,41 +318,11 @@ export async function launchOpenClawChrome(
// First launch to create preference files if missing, then decorate and relaunch.
const spawnOnce = () => {
const args: string[] = [
`--remote-debugging-port=${profile.cdpPort}`,
`--user-data-dir=${userDataDir}`,
"--no-first-run",
"--no-default-browser-check",
"--disable-sync",
"--disable-background-networking",
"--disable-component-update",
"--disable-features=Translate,MediaRouter",
"--disable-session-crashed-bubble",
"--hide-crash-restore-bubble",
"--password-store=basic",
];
if (resolved.headless) {
// Best-effort; older Chromes may ignore.
args.push("--headless=new");
args.push("--disable-gpu");
}
if (resolved.noSandbox) {
args.push("--no-sandbox");
args.push("--disable-setuid-sandbox");
}
if (process.platform === "linux") {
args.push("--disable-dev-shm-usage");
}
// Append user-configured extra arguments (e.g., stealth flags, window size)
if (resolved.extraArgs.length > 0) {
args.push(...resolved.extraArgs);
}
// Always open a blank tab to ensure a target exists.
args.push("about:blank");
const args = buildOpenClawChromeLaunchArgs({
resolved,
profile,
userDataDir,
});
return spawn(exe.path, args, {
stdio: "pipe",
env: {