mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
Merge pull request #3802 from heygen-com/fix/prinfra-344-browser-executability
fix(cli): verify Chrome can execute during preflight
This commit is contained in:
@@ -125,6 +125,41 @@ describe("runEnvironmentChecks", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ failure: { status: 133, signal: "SIGTRAP" }, detail: "SIGTRAP" },
|
||||
{ failure: { code: "EACCES" }, detail: "EACCES" },
|
||||
{ failure: { code: "ETIMEDOUT", signal: "SIGKILL" }, detail: "ETIMEDOUT" },
|
||||
])("rejects an existing browser that fails --version: $detail", async ({ failure, detail }) => {
|
||||
execFileSync.mockImplementation((_path, args) => {
|
||||
if (args[0] === "--version") throw Object.assign(new Error("cannot execute"), failure);
|
||||
return "ffmpeg version 7.1.1\n";
|
||||
});
|
||||
const findBrowser = vi.spyOn(manager, "findBrowser").mockResolvedValue({
|
||||
executablePath: process.execPath,
|
||||
source: "cache",
|
||||
});
|
||||
try {
|
||||
for (const browserPath of [undefined, process.execPath]) {
|
||||
const result = await runEnvironmentChecks({ includeBrowser: true, browserPath });
|
||||
const chrome = result.outcomes.find((outcome) => outcome.name === "Chrome");
|
||||
expect(chrome).toMatchObject({ ok: false, level: "error", title: "Chrome cannot start" });
|
||||
expect(chrome?.detail).toContain(detail);
|
||||
expect(result.browser).toBeUndefined();
|
||||
}
|
||||
expect(execFileSync).toHaveBeenCalledWith(
|
||||
process.execPath,
|
||||
["--version"],
|
||||
expect.objectContaining({
|
||||
timeout: 5000,
|
||||
killSignal: "SIGKILL",
|
||||
windowsHide: true,
|
||||
}),
|
||||
);
|
||||
} finally {
|
||||
findBrowser.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
it("reports an explicit missing browser path before render starts", async () => {
|
||||
const result = await runEnvironmentChecks({
|
||||
includeBrowser: true,
|
||||
|
||||
@@ -180,10 +180,56 @@ function chromeSharedLibOutcome(
|
||||
};
|
||||
}
|
||||
|
||||
function chromeLaunchFailureDetails(error: unknown): string {
|
||||
if (typeof error !== "object" || error === null) return "";
|
||||
const status = "status" in error ? error.status : undefined;
|
||||
const signal = "signal" in error ? error.signal : undefined;
|
||||
const code = "code" in error ? error.code : undefined;
|
||||
return [
|
||||
typeof status === "number" ? `exit code ${status}` : "",
|
||||
typeof signal === "string" ? `signal ${signal}` : "",
|
||||
typeof code === "string" ? code : "",
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(", ");
|
||||
}
|
||||
|
||||
function chromeLaunchOutcome(
|
||||
executablePath: string,
|
||||
found: EnvironmentCheckOutcome,
|
||||
): EnvironmentCheckOutcome {
|
||||
const libraries = chromeSharedLibOutcome(executablePath, found);
|
||||
if (!libraries.ok) return libraries;
|
||||
try {
|
||||
execFileSync(executablePath, ["--version"], {
|
||||
encoding: "utf-8",
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
timeout: 5000,
|
||||
killSignal: "SIGKILL",
|
||||
maxBuffer: 64 * 1024,
|
||||
windowsHide: true,
|
||||
});
|
||||
return found;
|
||||
} catch (error) {
|
||||
const details = chromeLaunchFailureDetails(error);
|
||||
return {
|
||||
name: "Chrome",
|
||||
ok: false,
|
||||
level: "error",
|
||||
title: "Chrome cannot start",
|
||||
detail: `Failed to run "${executablePath}" --version${details ? ` (${details})` : ""}.`,
|
||||
hint:
|
||||
"Select a working Chrome/Chromium binary for this OS and architecture with " +
|
||||
"HYPERFRAMES_BROWSER_PATH, or reinstall with: npx hyperframes browser ensure --force",
|
||||
path: executablePath,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async function checkChrome(browserPath?: string): Promise<EnvironmentCheckOutcome> {
|
||||
if (browserPath) {
|
||||
if (existsSync(browserPath)) {
|
||||
return chromeSharedLibOutcome(browserPath, {
|
||||
return chromeLaunchOutcome(browserPath, {
|
||||
name: "Chrome",
|
||||
ok: true,
|
||||
level: "ok",
|
||||
@@ -213,7 +259,7 @@ async function checkChrome(browserPath?: string): Promise<EnvironmentCheckOutcom
|
||||
info = undefined;
|
||||
}
|
||||
if (info) {
|
||||
return chromeSharedLibOutcome(info.executablePath, {
|
||||
return chromeLaunchOutcome(info.executablePath, {
|
||||
name: "Chrome",
|
||||
ok: true,
|
||||
level: "ok",
|
||||
|
||||
Reference in New Issue
Block a user