Skip to content

Commit 8124505

Browse files
committed
fix(diffs): ignore blank Windows browser roots
1 parent aaacee8 commit 8124505

2 files changed

Lines changed: 65 additions & 10 deletions

File tree

extensions/diffs/src/browser.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,53 @@ describe("PlaywrightDiffScreenshotter", () => {
6161
afterEach(async () => {
6262
await vi.runAllTimersAsync();
6363
vi.useRealTimers();
64+
vi.unstubAllEnvs();
65+
vi.restoreAllMocks();
6466
await cleanupRootDir();
6567
});
6668

69+
it("uses standard Windows install roots when ProgramFiles overrides are blank", async () => {
70+
const originalPlatform = Object.getOwnPropertyDescriptor(process, "platform");
71+
Object.defineProperty(process, "platform", { value: "win32", configurable: true });
72+
vi.stubEnv("LOCALAPPDATA", " ");
73+
vi.stubEnv("ProgramFiles", " ");
74+
vi.stubEnv("ProgramFiles(x86)", "");
75+
const chromePath = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe";
76+
vi.spyOn(fs, "access").mockImplementation(async (candidate) => {
77+
if (String(candidate) !== chromePath) {
78+
throw new Error("ENOENT");
79+
}
80+
});
81+
launchMock.mockResolvedValue(createMockBrowser([]));
82+
83+
try {
84+
const screenshotter = new PlaywrightDiffScreenshotter({ config: {}, browserIdleMs: 1_000 });
85+
await screenshotter.screenshotHtml({
86+
html: '<html><head></head><body><main class="oc-frame"></main></body></html>',
87+
outputPath,
88+
theme: "dark",
89+
image: {
90+
format: "png",
91+
qualityPreset: "standard",
92+
scale: 1,
93+
maxWidth: 960,
94+
maxPixels: 8_000_000,
95+
},
96+
});
97+
expect(launchMock).toHaveBeenCalledWith(
98+
expect.objectContaining({ executablePath: chromePath }),
99+
);
100+
expect(fs.access).not.toHaveBeenCalledWith(
101+
path.win32.join("Google", "Chrome", "Application", "chrome.exe"),
102+
expect.anything(),
103+
);
104+
} finally {
105+
if (originalPlatform) {
106+
Object.defineProperty(process, "platform", originalPlatform);
107+
}
108+
}
109+
});
110+
67111
it("reuses the same browser across renders and closes it after the idle window", async () => {
68112
const { pages, browser, screenshotter } = await createScreenshotterHarness();
69113

extensions/diffs/src/browser.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import fs from "node:fs/promises";
44
import path from "node:path";
55
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
66
import { writeExternalFileWithinRoot } from "openclaw/plugin-sdk/security-runtime";
7+
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
78
import { chromium } from "playwright-core";
89
import type { OpenClawConfig } from "../api.js";
910
import type { DiffRenderOptions, DiffTheme } from "./types.js";
@@ -520,17 +521,27 @@ function commonExecutablePathsForPlatform(): string[] {
520521
}
521522

522523
if (process.platform === "win32") {
523-
const localAppData = process.env.LOCALAPPDATA ?? "";
524-
const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
525-
const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
524+
const joinWindowsPath = path.win32.join;
525+
const localAppData = normalizeOptionalString(process.env.LOCALAPPDATA) ?? "";
526+
const programFiles = normalizeOptionalString(process.env.ProgramFiles) ?? "C:\\Program Files";
527+
const programFilesX86 =
528+
normalizeOptionalString(process.env["ProgramFiles(x86)"]) ?? "C:\\Program Files (x86)";
526529
return [
527-
path.join(localAppData, "Google", "Chrome", "Application", "chrome.exe"),
528-
path.join(programFiles, "Google", "Chrome", "Application", "chrome.exe"),
529-
path.join(programFilesX86, "Google", "Chrome", "Application", "chrome.exe"),
530-
path.join(programFiles, "Microsoft", "Edge", "Application", "msedge.exe"),
531-
path.join(programFilesX86, "Microsoft", "Edge", "Application", "msedge.exe"),
532-
path.join(programFiles, "BraveSoftware", "Brave-Browser", "Application", "brave.exe"),
533-
path.join(programFilesX86, "BraveSoftware", "Brave-Browser", "Application", "brave.exe"),
530+
...(localAppData
531+
? [joinWindowsPath(localAppData, "Google", "Chrome", "Application", "chrome.exe")]
532+
: []),
533+
joinWindowsPath(programFiles, "Google", "Chrome", "Application", "chrome.exe"),
534+
joinWindowsPath(programFilesX86, "Google", "Chrome", "Application", "chrome.exe"),
535+
joinWindowsPath(programFiles, "Microsoft", "Edge", "Application", "msedge.exe"),
536+
joinWindowsPath(programFilesX86, "Microsoft", "Edge", "Application", "msedge.exe"),
537+
joinWindowsPath(programFiles, "BraveSoftware", "Brave-Browser", "Application", "brave.exe"),
538+
joinWindowsPath(
539+
programFilesX86,
540+
"BraveSoftware",
541+
"Brave-Browser",
542+
"Application",
543+
"brave.exe",
544+
),
534545
];
535546
}
536547

0 commit comments

Comments
 (0)