import { act, cleanup, fireEvent, render, screen, } from "@testing-library/react"; import { afterEach, describe, expect, it, vi } from "vitest"; import { defineToolcraft } from "../../schema/define-toolcraft"; import type { ToolcraftExternalStore } from "../../state/toolcraft-external-store"; import { ToolcraftRoot } from "./toolcraft-root"; import { useToolcraftStore } from "./toolcraft-store-context"; import { useToolcraftDispatch } from "./use-toolcraft"; const playbackPersistenceSchema = defineToolcraft({ canvas: { enabled: true }, panels: { timeline: { mode: "playback" } }, persistence: { include: ["panels", "timeline"], key: "toolcraft:playback-boundary:state:v1", storage: "localStorage", version: 1, }, }); function CaptureStore({ capture, }: { capture: (store: ToolcraftExternalStore) => void; }): null { capture(useToolcraftStore()); return null; } function PublicPlaybackControls(): React.JSX.Element { const dispatch = useToolcraftDispatch(); return ( <> ); } afterEach(() => { vi.useRealTimers(); cleanup(); window.localStorage.clear(); }); describe("public playback persistence boundary", () => { it.each([ { buttonName: "Pause through public dispatch", label: "setPlaying(false)" }, { buttonName: "Toggle through public dispatch", label: "togglePlayback" }, ])( "persists and reloads transient time when public $label stops playback", ({ buttonName }) => { vi.useFakeTimers(); let store: ToolcraftExternalStore | undefined; const view = render( { store = value; }} /> , ); act(() => { vi.advanceTimersByTime(120); store?.dispatchTransient({ currentTimeSeconds: 2, type: "timeline.setCurrentTime", }); }); fireEvent.click(screen.getByRole("button", { name: buttonName })); expect(store?.getCommittedState().timeline).toMatchObject({ currentTimeSeconds: 2, isPlaying: false, }); act(() => { vi.advanceTimersByTime(120); }); view.unmount(); let reloadedStore: ToolcraftExternalStore | undefined; render( { reloadedStore = value; }} /> , ); expect(reloadedStore?.getState().timeline).toMatchObject({ currentTimeSeconds: 2, isPlaying: false, }); }, ); });