fix(cli): preserve media at snapshot end boundary (#2475)

* fix(cli): preserve media at snapshot end boundary

* test(cli): cover snapshot media boundary branches
This commit is contained in:
Miguel Ángel
2026-07-15 08:13:20 -04:00
committed by GitHub
parent 47e4b18f99
commit ca69b6b080
2 changed files with 169 additions and 31 deletions
+101
View File
@@ -4,6 +4,7 @@ import {
computeSnapshotTimes,
parseZoomScale,
requireSnapshotFfmpeg,
resolveSnapshotVideoFrameTime,
tailFrameTime,
} from "./snapshot.js";
@@ -36,6 +37,106 @@ describe("transparent snapshot capture", () => {
});
});
describe("resolveSnapshotVideoFrameTime", () => {
it("keeps media active at the inclusive clip end and samples its last decodable frame", () => {
expect(
resolveSnapshotVideoFrameTime({
globalTime: 15,
clipStart: 0,
clipDuration: 15,
relativeTime: 15,
sourceDuration: 15,
}),
).toBeCloseTo(15 - 1 / 30, 6);
});
it("keeps ordinary in-window media timestamps unchanged", () => {
expect(
resolveSnapshotVideoFrameTime({
globalTime: 7.5,
clipStart: 0,
clipDuration: 15,
relativeTime: 7.5,
sourceDuration: 15,
}),
).toBe(7.5);
});
it("does not activate media after the clip end", () => {
expect(
resolveSnapshotVideoFrameTime({
globalTime: 15.001,
clipStart: 0,
clipDuration: 15,
relativeTime: 15.001,
sourceDuration: 15,
}),
).toBeNull();
});
it.each([
{
name: "before clip start",
input: {
globalTime: 4.9,
clipStart: 5,
clipDuration: 10,
relativeTime: 0,
sourceDuration: 10,
},
expected: null,
},
{
name: "negative relative time",
input: {
globalTime: 5,
clipStart: 5,
clipDuration: 10,
relativeTime: -0.1,
sourceDuration: 10,
},
expected: null,
},
{
name: "unknown source duration",
input: {
globalTime: 15,
clipStart: 5,
clipDuration: 10,
relativeTime: 10,
sourceDuration: 0,
},
expected: 10 - 1 / 30,
},
{
name: "offset clip inclusive end",
input: {
globalTime: 15,
clipStart: 5,
clipDuration: 10,
relativeTime: 10,
sourceDuration: 10,
},
expected: 10 - 1 / 30,
},
{
name: "clip end within floating-point tolerance",
input: {
globalTime: 15 + 5e-10,
clipStart: 5,
clipDuration: 10,
relativeTime: 10,
sourceDuration: 10,
},
expected: 10 - 1 / 30,
},
])("handles $name", ({ input, expected }) => {
const result = resolveSnapshotVideoFrameTime(input);
if (expected === null) expect(result).toBeNull();
else expect(result).toBeCloseTo(expected, 6);
});
});
describe("computeSnapshotTimes (FINDING [7]: tail is always captured)", () => {
it("default frames: last point is the readable tail, never exact duration", () => {
const { times, appendedTail } = computeSnapshotTimes(8, { frames: 5 });