Merge PR #7604: fix(browser): honor explicit Chromium executable override (@roboomp)
This commit is contained in:
@@ -21,6 +21,9 @@
|
||||
### Fixed
|
||||
|
||||
- Fixed legacy Pi extension validation rejecting plugins such as `remote-pi` that import the package-root `convertToPng` image helper. ([#7610](https://github.com/can1357/oh-my-pi/issues/7610))
|
||||
### Fixed
|
||||
|
||||
- Fixed `PUPPETEER_EXECUTABLE_PATH` being ignored when a system Chrome installation was detected, preventing Windows users from selecting a compatible headless browser for the shared browser daemon ([#7601](https://github.com/can1357/oh-my-pi/issues/7601)).
|
||||
|
||||
## [17.2.7] - 2026-08-03
|
||||
|
||||
|
||||
@@ -121,9 +121,9 @@ async function loadBrowsers(): Promise<typeof BrowsersNs> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the Chromium executable puppeteer will launch, lazily downloading it
|
||||
* on first use via @puppeteer/browsers. Skipped when a system Chromium (NixOS)
|
||||
* or PUPPETEER_EXECUTABLE_PATH is set. The browser is cached under
|
||||
* Resolve the Chromium executable puppeteer will launch, honoring
|
||||
* PUPPETEER_EXECUTABLE_PATH before system browser detection and lazily
|
||||
* downloading Chromium otherwise. The browser is cached under
|
||||
* ~/.omp/puppeteer (getPuppeteerDir). Returns undefined when platform
|
||||
* detection fails (puppeteer default resolution takes over). Exported so
|
||||
* real-browser tests can probe launchability and skip on hosts missing
|
||||
@@ -131,10 +131,10 @@ async function loadBrowsers(): Promise<typeof BrowsersNs> {
|
||||
*/
|
||||
let chromiumExecutablePromise: Promise<string | undefined> | undefined;
|
||||
export async function ensureChromiumExecutable(): Promise<string | undefined> {
|
||||
const sysChrome = resolveSystemChromium();
|
||||
if (sysChrome) return sysChrome;
|
||||
const envPath = process.env.PUPPETEER_EXECUTABLE_PATH;
|
||||
if (envPath) return envPath;
|
||||
const sysChrome = resolveSystemChromium();
|
||||
if (sysChrome) return sysChrome;
|
||||
if (chromiumExecutablePromise) return chromiumExecutablePromise;
|
||||
|
||||
chromiumExecutablePromise = (async () => {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { ensureChromiumExecutable } from "@oh-my-pi/pi-coding-agent/tools/browser/launch";
|
||||
|
||||
const platform = process.env.OMP_BROWSER_PROBE_PLATFORM;
|
||||
if (platform) Object.defineProperty(process, "platform", { value: platform });
|
||||
|
||||
const executable = await ensureChromiumExecutable();
|
||||
process.stdout.write(executable ?? "");
|
||||
@@ -1,5 +1,9 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import * as path from "node:path";
|
||||
import { stealthIgnoreDefaultArgsForTest } from "@oh-my-pi/pi-coding-agent/tools/browser/launch";
|
||||
import { TempDir } from "@oh-my-pi/pi-utils";
|
||||
|
||||
const EXECUTABLE_PROBE = path.resolve(import.meta.dir, "../fixtures/browser-executable-probe.ts");
|
||||
|
||||
const AUTOMATION_FLAG = "--enable-automation";
|
||||
|
||||
@@ -33,3 +37,34 @@ describe("browser launch stealth defaults", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("browser executable selection", () => {
|
||||
it("honors PUPPETEER_EXECUTABLE_PATH before a detected Windows system Chrome", async () => {
|
||||
const tempDir = TempDir.createSync("@browser-executable-");
|
||||
try {
|
||||
const override = path.join(tempDir.path(), "chrome-headless-shell.exe");
|
||||
const systemChrome = path.join(tempDir.path(), "Google\\Chrome\\Application\\chrome.exe");
|
||||
await Bun.write(override, "override");
|
||||
await Bun.write(systemChrome, "system");
|
||||
|
||||
const result = Bun.spawnSync([process.execPath, EXECUTABLE_PROBE], {
|
||||
env: {
|
||||
...process.env,
|
||||
OMP_BROWSER_PROBE_PLATFORM: "win32",
|
||||
ProgramFiles: tempDir.path(),
|
||||
"ProgramFiles(x86)": path.join(tempDir.path(), "missing-x86"),
|
||||
LOCALAPPDATA: path.join(tempDir.path(), "missing-local"),
|
||||
PUPPETEER_EXECUTABLE_PATH: override,
|
||||
},
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
const stderr = new TextDecoder().decode(result.stderr);
|
||||
|
||||
expect(result.exitCode, stderr).toBe(0);
|
||||
expect(new TextDecoder().decode(result.stdout)).toBe(override);
|
||||
} finally {
|
||||
await tempDir.remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user