test: pin presentation rehearsal branches

This commit is contained in:
lda
2026-07-12 01:03:23 +07:00 Verified
parent cd8bbbcc27
commit a5e955f702
2 changed files with 23 additions and 2 deletions
+4 -2
View File
@@ -321,16 +321,18 @@ export const useDemoTimeline = (
const primeReplayToStage = useCallback((stage: DemoEvent["stage"] | null) => { const primeReplayToStage = useCallback((stage: DemoEvent["stage"] | null) => {
if (stage === null || state.mode !== "replay") return; if (stage === null || state.mode !== "replay") return;
const isRevisionBranch = state.events.some((event) => event.id === "revision-3-run-resume");
if (isRevisionBranch) return;
const recording = activeRecording.current; const recording = activeRecording.current;
if (!recording) return; if (!recording) return;
// The revision request updates the active recording before its reducer
// action is visible. Read this ref so a direct hash change cannot re-prime
// the canonical submitted branch during that render gap.
const appliedCount = appliedCountForStage(recording.events, stage); const appliedCount = appliedCountForStage(recording.events, stage);
if (appliedCount === 0) return; if (appliedCount === 0) return;
// Presentation priming projects the reviewed recording to the current beat. // Presentation priming projects the reviewed recording to the current beat.
// It is not runtime execution and must never run while the live timeline is active. // It is not runtime execution and must never run while the live timeline is active.
resetRuntime(); resetRuntime();
activeRecording.current = recording;
projectTransientState(recording.events, appliedCount); projectTransientState(recording.events, appliedCount);
dispatch({ dispatch({
type: "prime_replay", type: "prime_replay",
@@ -268,6 +268,18 @@ describe("PresentationRoute", () => {
expect(screen.queryByText(/checking reachability/i)).not.toBeInTheDocument(); expect(screen.queryByText(/checking reachability/i)).not.toBeInTheDocument();
}); });
it("shows the live prepared-workflow action after a healthy target probe", async () => {
window.sessionStorage.setItem("lda.workflowConsole.target", "http://127.0.0.1:8765/rpc");
window.location.hash = "#scene/agent-handoff/request";
const { PresentationRoute } = await import("./PresentationRoute.js");
render(<PresentationRoute />);
expect(await screen.findByText(/Live target ready/i)).toBeInTheDocument();
const runActions = screen.getAllByRole("button", { name: "Run prepared workflow" });
expect(runActions.length).toBeGreaterThanOrEqual(1);
expect(runActions.every((action) => !action.hasAttribute("disabled"))).toBe(true);
});
it("opens Scene 10 approval from the canonical hash", async () => { it("opens Scene 10 approval from the canonical hash", async () => {
window.location.hash = "#scene/typed-human-boundary/approval"; window.location.hash = "#scene/typed-human-boundary/approval";
const { PresentationRoute } = await import("./PresentationRoute.js"); const { PresentationRoute } = await import("./PresentationRoute.js");
@@ -359,6 +371,13 @@ describe("PresentationRoute", () => {
expect(window.location.hash).toBe("#scene/resume-output-evidence/resume"); expect(window.location.hash).toBe("#scene/resume-output-evidence/resume");
expect(screen.getByLabelText("workflow.runs.resume operation")).toBeInTheDocument(); expect(screen.getByLabelText("workflow.runs.resume operation")).toBeInTheDocument();
expect(screen.getByText(/Revision Requested/i)).toBeInTheDocument(); expect(screen.getByText(/Revision Requested/i)).toBeInTheDocument();
window.location.hash = "#scene/resume-output-evidence/trace";
window.dispatchEvent(new HashChangeEvent("hashchange"));
expect(await screen.findByText("revision_requested")).toBeInTheDocument();
expect(screen.getByText("end_cancelled")).toBeInTheDocument();
expect(screen.getByRole("region", { name: "workflow output summary" })).toBeInTheDocument();
}); });
it("opens approval with enabled approval controls immediately after priming", async () => { it("opens approval with enabled approval controls immediately after priming", async () => {