返回 DeepSeek-Reasonix
completion-summary-ui.test.tsx
根目录 / desktop / frontend / src / __tests__ / completion-summary-ui.test.tsx
1 // Run: tsx src/__tests__/completion-summary-ui.test.tsx
2
3 import { createTranscriptHarness } from "./transcript-dom-harness";
4 import type { Item } from "../lib/useController";
5 import type { WireCompletionSummary } from "../lib/types";
6
7 let passed = 0;
8 let failed = 0;
9
10 function ok(value: unknown, label: string) {
11 if (value) {
12 process.stdout.write(` PASS ${label}\n`);
13 passed += 1;
14 } else {
15 process.stdout.write(` FAIL ${label}\n`);
16 failed += 1;
17 }
18 }
19
20 console.log("\ncompletion summary UI");
21
22 const harness = await createTranscriptHarness();
23 const changesOpens: (WireCompletionSummary | undefined)[] = [];
24 const earlierSummary = {
25 preset: "balanced",
26 verdict: "partial",
27 mutations: 1,
28 checks_passed: 2,
29 checks_failed: 1,
30 checks_suppressed: 0,
31 review: "passed",
32 } satisfies WireCompletionSummary;
33 const laterSummary = {
34 preset: "balanced",
35 verdict: "partial",
36 mutations: 3,
37 checks_passed: 4,
38 checks_failed: 0,
39 checks_suppressed: 1,
40 review: "passed",
41 } satisfies WireCompletionSummary;
42 type CompletionNotice = Extract<Item, { kind: "notice" }> & { completionSummary: WireCompletionSummary };
43 const completionNotice = (id: string, summary: WireCompletionSummary): CompletionNotice => ({
44 kind: "notice",
45 id,
46 level: "warn",
47 variant: "completion",
48 title: "This turn still needs attention",
49 text: "One or more checks did not pass. Review the changes before continuing.",
50 action: "open_changes",
51 completionSummary: summary,
52 });
53 const items: Item[] = [
54 { kind: "user", id: "u1", text: "update it" },
55 { kind: "assistant", id: "a1", text: "Updated.", reasoning: "", streaming: false },
56 completionNotice("q1", earlierSummary),
57 { kind: "user", id: "u2", text: "update it again" },
58 { kind: "assistant", id: "a2", text: "Updated again.", reasoning: "", streaming: false },
59 completionNotice("q2", laterSummary),
60 ];
61
62 try {
63 await harness.render(items, { running: false }); await harness.settle();
64 const records = harness.container.querySelectorAll(".chat-notice");
65 ok(records.length === 2, "completion results remain ordinary records outside folds");
66 ok(records[0].textContent?.includes(items[2].text), "record preserves its explanation");
67 ok(records[0].querySelector("details pre")?.textContent?.includes('"checks_failed": 1'), "older result preserves its own details");
68 ok(records[1].querySelector("details pre")?.textContent?.includes('"checks_passed": 4'), "newer result preserves its own details");
69 ok(!records[0].querySelector("button"), "retired delivery and verification actions are absent");
70 } finally {
71 await harness.unmount();
72 await harness.close();
73 }
74
75 console.log(`\n${passed} passed, ${failed} failed`);
76 if (failed > 0) process.exit(1);
77
77 lines Plain Text