diff --git a/packages/cli/src/utils/checkBrowser.test.ts b/packages/cli/src/utils/checkBrowser.test.ts index d7a138bf6e..333cdad758 100644 --- a/packages/cli/src/utils/checkBrowser.test.ts +++ b/packages/cli/src/utils/checkBrowser.test.ts @@ -9,11 +9,15 @@ import { captureOverviewShot, runBrowserCheck } from "./checkBrowser.js"; import type { ProjectDir } from "./project.js"; const mocks = vi.hoisted(() => ({ + bundleWithLocalizedFonts: vi.fn(async () => ""), serverClose: vi.fn(async () => undefined), })); -vi.mock("@hyperframes/core/compiler", () => ({ - bundleToSingleHtml: vi.fn(async () => ""), +vi.mock("./bundleWithLocalizedFonts.js", () => ({ + // Keep browser-check unit tests focused on the page driver and audit pipeline. + // The real helper cold-loads the producer/font graph, which is covered by its + // own tests and can exhaust this suite's timeout under Windows CI contention. + bundleWithLocalizedFonts: mocks.bundleWithLocalizedFonts, })); vi.mock("../capture/captureCompositionFrame.js", async (importOriginal) => ({ @@ -47,6 +51,7 @@ const PROJECT: ProjectDir = { }; afterEach(() => { + vi.clearAllMocks(); vi.restoreAllMocks(); vi.unstubAllGlobals(); document.body.innerHTML = ""; @@ -100,6 +105,7 @@ it("carries raw browser geometry through the page driver and pipeline", async () runAuditGrid, ); + expect(mocks.bundleWithLocalizedFonts).toHaveBeenCalledWith(PROJECT.dir); expect(result.layoutIssues).toEqual([ expect.objectContaining({ code: "frame_out_of_frame", diff --git a/packages/studio/src/player/hooks/useTimelinePlayer.test.ts b/packages/studio/src/player/hooks/useTimelinePlayer.test.ts index 91a1f87cf1..81830f1c21 100644 --- a/packages/studio/src/player/hooks/useTimelinePlayer.test.ts +++ b/packages/studio/src/player/hooks/useTimelinePlayer.test.ts @@ -437,12 +437,19 @@ describe("anonymous timeline identity", () => { }); describe("mergeTimelineElementsPreservingDowngrades", () => { - it("preserves missing current elements when a shorter manifest arrives", () => { + it("preserves missing sub-composition elements when a shorter manifest arrives", () => { expect( mergeTimelineElementsPreservingDowngrades( [ { id: "hero", tag: "div", start: 0, duration: 4, track: 0 }, - { id: "cta", tag: "div", start: 4, duration: 2, track: 1 }, + { + id: "cta", + tag: "div", + start: 4, + duration: 2, + track: 1, + compositionSrc: "scenes/cta.html", + }, ], [{ id: "hero", tag: "div", start: 0, duration: 4, track: 0 }], 8, @@ -450,10 +457,31 @@ describe("mergeTimelineElementsPreservingDowngrades", () => { ), ).toEqual([ { id: "hero", tag: "div", start: 0, duration: 4, track: 0 }, - { id: "cta", tag: "div", start: 4, duration: 2, track: 1 }, + { + id: "cta", + tag: "div", + start: 4, + duration: 2, + track: 1, + compositionSrc: "scenes/cta.html", + }, ]); }); + it("drops missing top-level elements so undo does not leave ghost clips", () => { + expect( + mergeTimelineElementsPreservingDowngrades( + [ + { id: "hero", tag: "div", start: 0, duration: 4, track: 0 }, + { id: "split-clone", tag: "div", start: 4, duration: 2, track: 1 }, + ], + [{ id: "hero", tag: "div", start: 0, duration: 4, track: 0 }], + 8, + 8, + ), + ).toEqual([{ id: "hero", tag: "div", start: 0, duration: 4, track: 0 }]); + }); + it("accepts longer-duration or same-size updates as authoritative", () => { expect( mergeTimelineElementsPreservingDowngrades( @@ -477,6 +505,7 @@ describe("mergeTimelineElementsPreservingDowngrades", () => { start: 0, duration: 3, track: 0, + compositionSrc: "scenes/cards.html", }, { id: "Card", @@ -486,6 +515,7 @@ describe("mergeTimelineElementsPreservingDowngrades", () => { start: 3, duration: 3, track: 1, + compositionSrc: "scenes/cards.html", }, ], [ @@ -497,6 +527,7 @@ describe("mergeTimelineElementsPreservingDowngrades", () => { start: 0, duration: 3, track: 0, + compositionSrc: "scenes/cards.html", }, ], 8, @@ -511,6 +542,7 @@ describe("mergeTimelineElementsPreservingDowngrades", () => { start: 0, duration: 3, track: 0, + compositionSrc: "scenes/cards.html", }, { id: "Card", @@ -520,6 +552,7 @@ describe("mergeTimelineElementsPreservingDowngrades", () => { start: 3, duration: 3, track: 1, + compositionSrc: "scenes/cards.html", }, ]); });