browser: add Windows Chrome executable detection
This commit is contained in:
committed by
Peter Steinberger
parent
92a62bc300
commit
7294ba037d
@@ -8,6 +8,7 @@ import { afterEach, describe, expect, it, vi } from "vitest";
|
|||||||
import {
|
import {
|
||||||
decorateClawdProfile,
|
decorateClawdProfile,
|
||||||
findChromeExecutableMac,
|
findChromeExecutableMac,
|
||||||
|
findChromeExecutableWindows,
|
||||||
isChromeReachable,
|
isChromeReachable,
|
||||||
stopClawdChrome,
|
stopClawdChrome,
|
||||||
} from "./chrome.js";
|
} from "./chrome.js";
|
||||||
@@ -155,6 +156,34 @@ describe("browser chrome helpers", () => {
|
|||||||
exists.mockRestore();
|
exists.mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("picks the first existing Chrome candidate on Windows", () => {
|
||||||
|
const exists = vi
|
||||||
|
.spyOn(fs, "existsSync")
|
||||||
|
.mockImplementation((p) => String(p).includes("Chrome SxS"));
|
||||||
|
const exe = findChromeExecutableWindows();
|
||||||
|
expect(exe?.kind).toBe("canary");
|
||||||
|
expect(exe?.path).toMatch(/Chrome SxS/);
|
||||||
|
exists.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("finds Chrome in Program Files on Windows", () => {
|
||||||
|
// Use path.join to match how the function builds paths (cross-platform)
|
||||||
|
const marker = path.join("Program Files", "Google", "Chrome");
|
||||||
|
const exists = vi
|
||||||
|
.spyOn(fs, "existsSync")
|
||||||
|
.mockImplementation((p) => String(p).includes(marker));
|
||||||
|
const exe = findChromeExecutableWindows();
|
||||||
|
expect(exe?.kind).toBe("chrome");
|
||||||
|
expect(exe?.path).toMatch(/chrome\.exe$/);
|
||||||
|
exists.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns null when no Chrome candidate exists on Windows", () => {
|
||||||
|
const exists = vi.spyOn(fs, "existsSync").mockReturnValue(false);
|
||||||
|
expect(findChromeExecutableWindows()).toBeNull();
|
||||||
|
exists.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
it("reports reachability based on /json/version", async () => {
|
it("reports reachability based on /json/version", async () => {
|
||||||
vi.stubGlobal(
|
vi.stubGlobal(
|
||||||
"fetch",
|
"fetch",
|
||||||
|
|||||||
@@ -102,6 +102,72 @@ export function findChromeExecutableLinux(): BrowserExecutable | null {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function findChromeExecutableWindows(): BrowserExecutable | null {
|
||||||
|
const localAppData = process.env.LOCALAPPDATA ?? "";
|
||||||
|
const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
|
||||||
|
// Must use bracket notation: variable name contains parentheses
|
||||||
|
const programFilesX86 =
|
||||||
|
process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
|
||||||
|
|
||||||
|
const candidates: Array<BrowserExecutable> = [
|
||||||
|
// Chrome Canary (user install)
|
||||||
|
{
|
||||||
|
kind: "canary",
|
||||||
|
path: path.join(
|
||||||
|
localAppData,
|
||||||
|
"Google",
|
||||||
|
"Chrome SxS",
|
||||||
|
"Application",
|
||||||
|
"chrome.exe",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
// Chromium (user install)
|
||||||
|
{
|
||||||
|
kind: "chromium",
|
||||||
|
path: path.join(localAppData, "Chromium", "Application", "chrome.exe"),
|
||||||
|
},
|
||||||
|
// Chrome (user install)
|
||||||
|
{
|
||||||
|
kind: "chrome",
|
||||||
|
path: path.join(
|
||||||
|
localAppData,
|
||||||
|
"Google",
|
||||||
|
"Chrome",
|
||||||
|
"Application",
|
||||||
|
"chrome.exe",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
// Chrome (system install, 64-bit)
|
||||||
|
{
|
||||||
|
kind: "chrome",
|
||||||
|
path: path.join(
|
||||||
|
programFiles,
|
||||||
|
"Google",
|
||||||
|
"Chrome",
|
||||||
|
"Application",
|
||||||
|
"chrome.exe",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
// Chrome (system install, 32-bit on 64-bit Windows)
|
||||||
|
{
|
||||||
|
kind: "chrome",
|
||||||
|
path: path.join(
|
||||||
|
programFilesX86,
|
||||||
|
"Google",
|
||||||
|
"Chrome",
|
||||||
|
"Application",
|
||||||
|
"chrome.exe",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const candidate of candidates) {
|
||||||
|
if (exists(candidate.path)) return candidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function resolveBrowserExecutable(
|
function resolveBrowserExecutable(
|
||||||
resolved: ResolvedBrowserConfig,
|
resolved: ResolvedBrowserConfig,
|
||||||
): BrowserExecutable | null {
|
): BrowserExecutable | null {
|
||||||
@@ -116,6 +182,7 @@ function resolveBrowserExecutable(
|
|||||||
|
|
||||||
if (process.platform === "darwin") return findChromeExecutableMac();
|
if (process.platform === "darwin") return findChromeExecutableMac();
|
||||||
if (process.platform === "linux") return findChromeExecutableLinux();
|
if (process.platform === "linux") return findChromeExecutableLinux();
|
||||||
|
if (process.platform === "win32") return findChromeExecutableWindows();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,7 +512,7 @@ export async function launchClawdChrome(
|
|||||||
const exe = resolveBrowserExecutable(resolved);
|
const exe = resolveBrowserExecutable(resolved);
|
||||||
if (!exe) {
|
if (!exe) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"No supported browser found (Chrome/Chromium on macOS or Linux).",
|
"No supported browser found (Chrome/Chromium on macOS, Linux, or Windows).",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user