mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 12:54:29 +00:00
fix(cli): preload render.js once in renderLocal test suite to fix Windows CI
The first dynamic `await import("./render.js")` cold-load takes >5 s on
Windows runners — long enough to blow vitest's default 5 s timeout in
whichever test ran it first. Subsequent imports are <10 ms because the
module is now cached, so only test #1 ever times out.
The downstream failure is more subtle: when test #1 times out, vitest
moves on, but its leaked async function eventually hits the synchronous
`producer.createRenderJob(...)` line and pushes a stale config to
`producerState.createdJobs`. That push lands AFTER test #2's `beforeEach`
clears the array, so test #2's `createdJobs[0]` is the leaked test #1
entry instead of its own. That's why test #2 saw `browserGpuMode: 'software'`
when it expected `'auto'`.
Hoist the import into `beforeAll` (matching the pattern the existing
`parseVariablesArg` and `validateVariablesAgainstProject` describe blocks
in this file already use). Cold-load happens once outside any test's
timeout window, every test stays fast, no leaked promise can corrupt
state.
Failing run: https://github.com/heygen-com/hyperframes/actions/runs/25470257972/job/74732502915
Started failing on main with the merge of #642 (auto-detect-browser-gpu),
which added the "forwards browserGpuMode='auto'" test as test #2.
This commit is contained in:
@@ -26,6 +26,19 @@ vi.mock("../telemetry/events.js", () => ({
|
||||
|
||||
describe("renderLocal browser GPU config", () => {
|
||||
const savedEnv = new Map<string, string | undefined>();
|
||||
// Pre-resolve once. The first dynamic `import("./render.js")` in this file
|
||||
// takes >5 s on Windows runners (cold module load) — long enough to blow
|
||||
// vitest's default 5 s timeout in whichever test happens to be first. When
|
||||
// that test times out, its leaked late `createRenderJob` call lands AFTER
|
||||
// the next test's `beforeEach` clears `producerState.createdJobs`, shifting
|
||||
// index 0 and corrupting unrelated assertions. Importing once in
|
||||
// `beforeAll` keeps every test fast and isolated.
|
||||
let renderLocal: typeof import("./render.js").renderLocal;
|
||||
let resolveBrowserGpuForCli: typeof import("./render.js").resolveBrowserGpuForCli;
|
||||
|
||||
beforeAll(async () => {
|
||||
({ renderLocal, resolveBrowserGpuForCli } = await import("./render.js"));
|
||||
});
|
||||
|
||||
function setEnv(key: string, value: string) {
|
||||
savedEnv.set(key, process.env[key]);
|
||||
@@ -54,7 +67,6 @@ describe("renderLocal browser GPU config", () => {
|
||||
it("passes an explicit software override for --no-browser-gpu even when env requests hardware", async () => {
|
||||
setEnv("PRODUCER_BROWSER_GPU_MODE", "hardware");
|
||||
|
||||
const { renderLocal } = await import("./render.js");
|
||||
await renderLocal("/tmp/project", "/tmp/out.mp4", {
|
||||
fps: 30,
|
||||
quality: "standard",
|
||||
@@ -73,7 +85,6 @@ describe("renderLocal browser GPU config", () => {
|
||||
});
|
||||
|
||||
it("forwards browserGpuMode='auto' into producer config (probe-then-choose)", async () => {
|
||||
const { renderLocal } = await import("./render.js");
|
||||
await renderLocal("/tmp/project", "/tmp/out.mp4", {
|
||||
fps: 30,
|
||||
quality: "standard",
|
||||
@@ -92,7 +103,6 @@ describe("renderLocal browser GPU config", () => {
|
||||
});
|
||||
|
||||
it("passes an explicit hardware override for default local browser GPU", async () => {
|
||||
const { renderLocal } = await import("./render.js");
|
||||
await renderLocal("/tmp/project", "/tmp/out.mp4", {
|
||||
fps: 30,
|
||||
quality: "standard",
|
||||
@@ -110,9 +120,7 @@ describe("renderLocal browser GPU config", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("resolves browser GPU from CLI flags, Docker mode, and env fallback", async () => {
|
||||
const { resolveBrowserGpuForCli } = await import("./render.js");
|
||||
|
||||
it("resolves browser GPU from CLI flags, Docker mode, and env fallback", () => {
|
||||
// Default (no flag, no env): auto — engine probes and chooses.
|
||||
expect(resolveBrowserGpuForCli(false, undefined, undefined)).toBe("auto");
|
||||
// Env override
|
||||
@@ -128,7 +136,6 @@ describe("renderLocal browser GPU config", () => {
|
||||
});
|
||||
|
||||
it("forwards parsed --variables payload to createRenderJob", async () => {
|
||||
const { renderLocal } = await import("./render.js");
|
||||
await renderLocal("/tmp/project", "/tmp/out.mp4", {
|
||||
fps: 30,
|
||||
quality: "standard",
|
||||
@@ -144,7 +151,6 @@ describe("renderLocal browser GPU config", () => {
|
||||
});
|
||||
|
||||
it("forwards format: png-sequence through to createRenderJob", async () => {
|
||||
const { renderLocal } = await import("./render.js");
|
||||
await renderLocal("/tmp/project", "/tmp/frames", {
|
||||
fps: 30,
|
||||
quality: "standard",
|
||||
@@ -159,7 +165,6 @@ describe("renderLocal browser GPU config", () => {
|
||||
});
|
||||
|
||||
it("omits variables from createRenderJob when not provided", async () => {
|
||||
const { renderLocal } = await import("./render.js");
|
||||
await renderLocal("/tmp/project", "/tmp/out.mp4", {
|
||||
fps: 30,
|
||||
quality: "standard",
|
||||
@@ -174,7 +179,6 @@ describe("renderLocal browser GPU config", () => {
|
||||
});
|
||||
|
||||
it("forwards entryFile to createRenderJob when --composition is set", async () => {
|
||||
const { renderLocal } = await import("./render.js");
|
||||
await renderLocal("/tmp/project", "/tmp/out.mp4", {
|
||||
fps: 30,
|
||||
quality: "standard",
|
||||
@@ -190,7 +194,6 @@ describe("renderLocal browser GPU config", () => {
|
||||
});
|
||||
|
||||
it("omits entryFile from createRenderJob when --composition is not set", async () => {
|
||||
const { renderLocal } = await import("./render.js");
|
||||
await renderLocal("/tmp/project", "/tmp/out.mp4", {
|
||||
fps: 30,
|
||||
quality: "standard",
|
||||
@@ -211,7 +214,6 @@ describe("renderLocal browser GPU config", () => {
|
||||
.mockImplementation((code?: string | number | null): never => {
|
||||
throw new Error(`process.exit:${code ?? ""}`);
|
||||
});
|
||||
const { renderLocal } = await import("./render.js");
|
||||
|
||||
await renderLocal("/tmp/project", "/tmp/out.mp4", {
|
||||
fps: 30,
|
||||
|
||||
Reference in New Issue
Block a user