fix(lab): make replay pause authoritative

This commit is contained in:
DCCONSTRUCTIONS
2026-08-24 00:12:49 +03:00
parent a7caed70c1
commit 8877ee947f
4 changed files with 72 additions and 13 deletions
@@ -12,6 +12,7 @@ let fetchM4ThreatTimelineChunk;
let selectM4ThreatTimelineFrame;
let selectM4ThreatTimelineSequence;
let advanceRecordedEvidencePlayback;
let synchronizeRecordedEvidencePlayback;
let m4ThreatChunkWindowStarts;
let buildM4LocalSurface;
@@ -31,7 +32,10 @@ before(async () => {
selectM4ThreatTimelineFrame,
selectM4ThreatTimelineSequence,
} = await server.ssrLoadModule("/src/core/laboratory/m4ReplayThreat.ts"));
({ advanceRecordedEvidencePlayback } = await server.ssrLoadModule(
({
advanceRecordedEvidencePlayback,
synchronizeRecordedEvidencePlayback,
} = await server.ssrLoadModule(
"/src/components/laboratory/useRecordedEvidencePlayback.ts",
));
({ m4ThreatChunkWindowStarts } = await server.ssrLoadModule(
@@ -391,6 +395,26 @@ test("recorded evidence clock advances by selected rate and stops at the sealed
);
});
test("recorded VIDEO clock cannot reverse an explicit operator pause", () => {
const range = { startSeconds: 10, endSeconds: 20 };
assert.deepEqual(
synchronizeRecordedEvidencePlayback(
{ currentSeconds: 15, playing: false, rate: 2 },
{ currentSeconds: 15.1, playing: true, rate: 1 },
range,
),
{ currentSeconds: 15.1, playing: false, rate: 2 },
);
assert.deepEqual(
synchronizeRecordedEvidencePlayback(
{ currentSeconds: 19.9, playing: true, rate: 1 },
{ currentSeconds: 20, playing: false, rate: 1 },
range,
),
{ currentSeconds: 20, playing: false, rate: 1 },
);
});
test("M4.6 viewer keeps media and spatial panes on one playback clock", async () => {
const [visual, visualCss, imageScene, videoScene, metricScene] = await Promise.all([
readFile(new URL("../src/workspaces/laboratory/M4ReplayThreatVisual.tsx", import.meta.url), "utf8"),
@@ -434,8 +458,10 @@ test("M4.6 viewer keeps media and spatial panes on one playback clock", async ()
assert.match(visualCss, /width: 33\.333333%/);
assert.match(visualCss, /flex-flow: column nowrap/);
assert.match(visualCss, /m4-replay-threat-visual__overlay > div/);
assert.match(visualCss, /grid-template-columns: minmax\(0, 1fr\)/);
assert.match(visualCss, /width: min\(22rem, calc\(33\.333333% - 0\.8rem\)\)/);
assert.match(visualCss, /grid-template-columns: minmax\(0, max-content\)/);
assert.match(visualCss, /width: max-content/);
assert.match(visualCss, /--m4-replay-threat-overlay-pane-width/);
assert.match(visualCss, /white-space: nowrap/);
assert.match(visualCss, /laboratory-metric-evidence-scene__legend/);
assert.match(visualCss, /bottom: auto/);
assert.match(videoScene, /<RecordedFmp4Player/);