返回 DeepSeek-Reasonix
remoteHistoryProjectionCases.tsx
根目录 / desktop / frontend / src / __tests__ / helpers / remoteHistoryProjectionCases.tsx
1 import React, { act } from "react";
2 import { createRoot } from "react-dom/client";
3 import { LocaleProvider } from "../../lib/i18n";
4 import { useRemoteSession, type RemoteSessionApi } from "../../lib/useRemoteSession";
5
6 /** Cases that assert what a remote snapshot projects into the transcript. */
7 interface RemoteProjectionHarness {
8 ok: (value: boolean, label: string) => void;
9 flush: () => Promise<void>;
10 }
11
12 /** History from a serve keeps the tool args and output its transcript shows. */
13 export async function runRemoteToolHistoryCase({ ok, flush }: RemoteProjectionHarness) {
14 let toolProbe: RemoteSessionApi | undefined;
15 function ToolProbe() {
16 toolProbe = useRemoteSession("tab-tool-history");
17 return null;
18 }
19 const toolRoot = createRoot(document.createElement("div"));
20 await act(async () => {
21 toolRoot.render(<LocaleProvider><ToolProbe /></LocaleProvider>);
22 await flush();
23 });
24 const remoteTool = toolProbe?.transcript.items.find((item) => item.kind === "tool" && item.id === "remote-tool");
25 ok(remoteTool?.kind === "tool" && remoteTool.args.includes("go test ./...")
26 && remoteTool.output === "remote tool output" && remoteTool.dataArchived !== true,
27 "remote history retains expandable tool args and output without a local rehydrate endpoint");
28 await act(async () => toolRoot.unmount());
29 }
30
31 // Pending prompt frames retained by Desktop are replayed by the next snapshot,
32 // which restores decisions missed while the tab had no frontend listener.
33 export async function runRemotePendingPromptReplayCase({ ok, flush }: RemoteProjectionHarness) {
34 let replayProbe: RemoteSessionApi | undefined;
35 function ReplayProbe() { replayProbe = useRemoteSession("tab-replay"); return null; }
36 const replayRoot = createRoot(document.createElement("div"));
37 await act(async () => {
38 replayRoot.render(<LocaleProvider><ReplayProbe /></LocaleProvider>);
39 await flush();
40 });
41 ok(replayProbe?.transcript.approval?.id === "replayed-approval", "snapshot replays a prompt emitted while the remote tab was inactive");
42 ok(replayProbe?.transcript.extensionForm?.pluginId === "replayed-plugin" && replayProbe.transcript.extensionForm.surfaceId === "replayed-form", "snapshot replays an extension form emitted while the remote tab was inactive");
43 await act(async () => { replayProbe?.drainApprovals(["different-approval"]); await flush(); });
44 ok(replayProbe?.transcript.approval?.id === "replayed-approval", "a remote mode transaction preserves approvals it did not drain");
45 await act(async () => { replayProbe?.drainApprovals(["replayed-approval"]); await flush(); });
46 ok(replayProbe?.transcript.approval === undefined, "a remote mode transaction clears the exact approval it auto-allowed");
47 await act(async () => replayRoot.unmount());
48 }
49
49 lines Plain Text