Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 56 additions & 2 deletions packages/cli/src/commands/render.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// fallow-ignore-file code-duplication
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";

const producerState = vi.hoisted(() => ({
createdJobs: [] as Array<Record<string, unknown>>,
Expand Down Expand Up @@ -59,21 +62,41 @@ vi.mock("../browser/preflight.js", () => ({
runEnvironmentChecks: vi.fn(async () => preflightState.result),
}));

vi.mock("../browser/manager.js", () => ({
ensureBrowser: vi.fn(async () => ({ executablePath: "/mock/chrome", source: "cache" })),
}));

describe("renderLocal browser GPU config", () => {
const savedEnv = new Map<string, string | undefined>();
let tempDirs: string[] = [];
// 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 renderCommand: (typeof import("./render.js"))["default"];
let renderLocal: typeof import("./render.js").renderLocal;
let resolveBrowserGpuForCli: typeof import("./render.js").resolveBrowserGpuForCli;

beforeAll(async () => {
({ renderLocal, resolveBrowserGpuForCli } = await import("./render.js"));
});
const renderModule = await import("./render.js");
renderCommand = renderModule.default;
renderLocal = renderModule.renderLocal;
resolveBrowserGpuForCli = renderModule.resolveBrowserGpuForCli;
}, 30_000);

function createRenderProject(): string {
const dir = mkdtempSync(join(tmpdir(), "hf-render-command-"));
tempDirs.push(dir);
writeFileSync(
join(dir, "index.html"),
'<!doctype html><html><body><div data-composition-id="main" data-width="1920" data-height="1080" data-no-timeline></div></body></html>',
"utf8",
);
return dir;
}

function setEnv(key: string, value: string) {
if (!savedEnv.has(key)) savedEnv.set(key, process.env[key]);
Expand Down Expand Up @@ -103,6 +126,10 @@ describe("renderLocal browser GPU config", () => {
vi.clearAllMocks();
vi.useRealTimers();
vi.restoreAllMocks();
for (const dir of tempDirs) {
rmSync(dir, { recursive: true, force: true });
}
tempDirs = [];
});

it("passes an explicit software override for --no-browser-gpu even when env requests hardware", async () => {
Expand Down Expand Up @@ -252,6 +279,33 @@ describe("renderLocal browser GPU config", () => {
expect(producerState.createdJobs[0]?.videoFrameFormat).toBe("png");
});

it("forwards gif loop and video frame format to batch row renders", async () => {
const projectDir = createRenderProject();
const rowsPath = join(projectDir, "rows.json");
writeFileSync(rowsPath, "[{}]", "utf8");

if (!renderCommand.run) throw new Error("render command missing run handler");
await renderCommand.run({
args: {
dir: projectDir,
batch: rowsPath,
output: join(projectDir, "renders", "{index}.gif"),
fps: "15",
quality: "standard",
format: "gif",
"gif-loop": "3",
"video-frame-format": "png",
quiet: true,
},
} as never);

expect(producerState.createdJobs[0]).toMatchObject({
format: "gif",
gifLoop: 3,
videoFrameFormat: "png",
});
});

it("forwards debug mode to createRenderJob", async () => {
await renderLocal("/tmp/project", "/tmp/out.mp4", {
fps: { num: 30, den: 1 },
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/src/commands/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -804,13 +804,15 @@ export default defineCommand({
quality,
authoringSkill,
format,
gifLoop,
workers,
gpu: useGpu,
browserGpuMode,
hdrMode,
crf,
vp9CpuUsed,
videoBitrate,
videoFrameFormat,
quiet: batchQuiet,
browserPath,
entryFile,
Expand Down