Skip to content

Commit de948af

Browse files
committed
Auto-film runs that produce both recordings
film.mp4 was a manual post-step, so any re-run left the viewer showing the parts (cast + browser video) instead of the spliced session. The runner now invokes scripts/film.ts after every successful run that has both terminal.cast and session.mp4 — best-effort, so missing agg/ffmpeg degrades back to the parts rather than failing the run. Every developer- session run's page now plays the single film by default.
1 parent ab96ddc commit de948af

1 file changed

Lines changed: 25 additions & 1 deletion

File tree

e2e/src/scenario.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
// recording layer. What survives per run is a small result.json (for the
1010
// scenario × target matrix) plus whatever artifacts the surfaces produced
1111
// (browser video/trace/screenshots, terminal casts).
12-
import { mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
12+
import { execFileSync } from "node:child_process";
13+
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
1314
import { join } from "node:path";
1415
import { fileURLToPath } from "node:url";
1516

@@ -136,6 +137,29 @@ export const scenario = (
136137
1,
137138
),
138139
);
140+
// A run with both recordings is ONE developer session — splice them
141+
// into film.mp4 (scripts/film.ts cuts on the focus timeline) so the
142+
// viewer plays a single recording, not parts. Best-effort: missing
143+
// agg/ffmpeg or a film failure never fails the run; the parts stay
144+
// and the viewer falls back to cast + video in story order.
145+
if (
146+
exit._tag === "Success" &&
147+
existsSync(join(dir, "terminal.cast")) &&
148+
existsSync(join(dir, "session.mp4"))
149+
) {
150+
yield* Effect.sync(() => {
151+
// oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: optional post-processing over external tooling (agg, ffmpeg)
152+
try {
153+
execFileSync(
154+
"bun",
155+
[fileURLToPath(new URL("../scripts/film.ts", import.meta.url)), dir],
156+
{ stdio: "pipe", timeout: 120_000 },
157+
);
158+
} catch {
159+
// parts remain the artifacts
160+
}
161+
});
162+
}
139163
buildManifest(RUNS_DIR);
140164
if (exit._tag === "Failure") {
141165
return yield* Effect.failCause(exit.cause);

0 commit comments

Comments
 (0)