Skip to content

Commit a739be5

Browse files
committed
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.
1 parent 31acf7f commit a739be5

1 file changed

Lines changed: 14 additions & 12 deletions

File tree

packages/cli/src/commands/render.test.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,19 @@ vi.mock("../telemetry/events.js", () => ({
2626

2727
describe("renderLocal browser GPU config", () => {
2828
const savedEnv = new Map<string, string | undefined>();
29+
// Pre-resolve once. The first dynamic `import("./render.js")` in this file
30+
// takes >5 s on Windows runners (cold module load) — long enough to blow
31+
// vitest's default 5 s timeout in whichever test happens to be first. When
32+
// that test times out, its leaked late `createRenderJob` call lands AFTER
33+
// the next test's `beforeEach` clears `producerState.createdJobs`, shifting
34+
// index 0 and corrupting unrelated assertions. Importing once in
35+
// `beforeAll` keeps every test fast and isolated.
36+
let renderLocal: typeof import("./render.js").renderLocal;
37+
let resolveBrowserGpuForCli: typeof import("./render.js").resolveBrowserGpuForCli;
38+
39+
beforeAll(async () => {
40+
({ renderLocal, resolveBrowserGpuForCli } = await import("./render.js"));
41+
});
2942

3043
function setEnv(key: string, value: string) {
3144
savedEnv.set(key, process.env[key]);
@@ -54,7 +67,6 @@ describe("renderLocal browser GPU config", () => {
5467
it("passes an explicit software override for --no-browser-gpu even when env requests hardware", async () => {
5568
setEnv("PRODUCER_BROWSER_GPU_MODE", "hardware");
5669

57-
const { renderLocal } = await import("./render.js");
5870
await renderLocal("/tmp/project", "/tmp/out.mp4", {
5971
fps: 30,
6072
quality: "standard",
@@ -73,7 +85,6 @@ describe("renderLocal browser GPU config", () => {
7385
});
7486

7587
it("forwards browserGpuMode='auto' into producer config (probe-then-choose)", async () => {
76-
const { renderLocal } = await import("./render.js");
7788
await renderLocal("/tmp/project", "/tmp/out.mp4", {
7889
fps: 30,
7990
quality: "standard",
@@ -92,7 +103,6 @@ describe("renderLocal browser GPU config", () => {
92103
});
93104

94105
it("passes an explicit hardware override for default local browser GPU", async () => {
95-
const { renderLocal } = await import("./render.js");
96106
await renderLocal("/tmp/project", "/tmp/out.mp4", {
97107
fps: 30,
98108
quality: "standard",
@@ -110,9 +120,7 @@ describe("renderLocal browser GPU config", () => {
110120
});
111121
});
112122

113-
it("resolves browser GPU from CLI flags, Docker mode, and env fallback", async () => {
114-
const { resolveBrowserGpuForCli } = await import("./render.js");
115-
123+
it("resolves browser GPU from CLI flags, Docker mode, and env fallback", () => {
116124
// Default (no flag, no env): auto — engine probes and chooses.
117125
expect(resolveBrowserGpuForCli(false, undefined, undefined)).toBe("auto");
118126
// Env override
@@ -128,7 +136,6 @@ describe("renderLocal browser GPU config", () => {
128136
});
129137

130138
it("forwards parsed --variables payload to createRenderJob", async () => {
131-
const { renderLocal } = await import("./render.js");
132139
await renderLocal("/tmp/project", "/tmp/out.mp4", {
133140
fps: 30,
134141
quality: "standard",
@@ -144,7 +151,6 @@ describe("renderLocal browser GPU config", () => {
144151
});
145152

146153
it("forwards format: png-sequence through to createRenderJob", async () => {
147-
const { renderLocal } = await import("./render.js");
148154
await renderLocal("/tmp/project", "/tmp/frames", {
149155
fps: 30,
150156
quality: "standard",
@@ -159,7 +165,6 @@ describe("renderLocal browser GPU config", () => {
159165
});
160166

161167
it("omits variables from createRenderJob when not provided", async () => {
162-
const { renderLocal } = await import("./render.js");
163168
await renderLocal("/tmp/project", "/tmp/out.mp4", {
164169
fps: 30,
165170
quality: "standard",
@@ -174,7 +179,6 @@ describe("renderLocal browser GPU config", () => {
174179
});
175180

176181
it("forwards entryFile to createRenderJob when --composition is set", async () => {
177-
const { renderLocal } = await import("./render.js");
178182
await renderLocal("/tmp/project", "/tmp/out.mp4", {
179183
fps: 30,
180184
quality: "standard",
@@ -190,7 +194,6 @@ describe("renderLocal browser GPU config", () => {
190194
});
191195

192196
it("omits entryFile from createRenderJob when --composition is not set", async () => {
193-
const { renderLocal } = await import("./render.js");
194197
await renderLocal("/tmp/project", "/tmp/out.mp4", {
195198
fps: 30,
196199
quality: "standard",
@@ -211,7 +214,6 @@ describe("renderLocal browser GPU config", () => {
211214
.mockImplementation((code?: string | number | null): never => {
212215
throw new Error(`process.exit:${code ?? ""}`);
213216
});
214-
const { renderLocal } = await import("./render.js");
215217

216218
await renderLocal("/tmp/project", "/tmp/out.mp4", {
217219
fps: 30,

0 commit comments

Comments
 (0)