返回 DeepSeek-Reasonix
turn-actions-rendering.test.ts
根目录 / desktop / frontend / src / __tests__ / turn-actions-rendering.test.ts
1 // Run: tsx src/__tests__/turn-actions-rendering.test.ts
2
3 import { readFileSync } from "node:fs";
4 import { dirname, resolve } from "node:path";
5 import { fileURLToPath } from "node:url";
6
7 const testDir = dirname(fileURLToPath(import.meta.url));
8 const styles = readFileSync(resolve(testDir, "../styles.css"), "utf8");
9
10 let passed = 0;
11 let failed = 0;
12
13 function ok(value: unknown, label: string) {
14 if (value) {
15 process.stdout.write(` PASS ${label}\n`);
16 passed += 1;
17 } else {
18 process.stdout.write(` FAIL ${label}\n`);
19 failed += 1;
20 }
21 }
22
23 console.log("\nturn actions rendering");
24
25 const creationTranscriptRule = styles.match(
26 /\.app--creation \.transcript\.transcript--creation-scrollbar,\s*:root\[data-theme-style\] \.app--creation \.transcript\.transcript--creation-scrollbar\s*\{([^}]+)\}/,
27 )?.[1] ?? "";
28
29 ok(
30 /background-color:\s*var\(--bg\);/.test(creationTranscriptRule),
31 "creation scrollbar layer paints an opaque backdrop so removed turn actions repaint (#6359)",
32 );
33
34 ok(
35 /scrollbar-width:\s*none;/.test(creationTranscriptRule),
36 "opaque backdrop preserves the custom Creation scrollbar contract",
37 );
38
39 function ruleBody(selector: string): string {
40 const ruleStart = styles.indexOf(`${selector} {`);
41 if (ruleStart < 0) return "";
42 const bodyStart = styles.indexOf("{", ruleStart) + 1;
43 const bodyEnd = styles.indexOf("\n}", bodyStart);
44 return bodyEnd < 0 ? "" : styles.slice(bodyStart, bodyEnd);
45 }
46
47 const windowsPrimaryTranscriptSelector =
48 ':root[data-platform="windows"] .app:not(.app--creation) .chat-pane > .main > .transcript-shell > .transcript';
49 const windowsThemeTranscriptSelector =
50 ':root[data-platform="windows"][data-theme-pack][data-theme-has-bg="true"] .app:not(.app--creation) .chat-pane > .main > .transcript-shell > .transcript';
51 const windowsTaskTranscriptSelector =
52 ':root[data-platform="windows"][data-theme-pack][data-theme-has-bg="true"][data-theme-scene="task"] .app:not(.app--creation) .chat-pane > .main > .transcript-shell > .transcript';
53 const windowsTaskLeftTranscriptSelector =
54 ':root[data-platform="windows"][data-theme-pack][data-theme-has-bg="true"][data-theme-scene="task"][data-theme-safe-area="left"] .app:not(.app--creation) .chat-pane > .main > .transcript-shell > .transcript';
55 const windowsTaskRightTranscriptSelector =
56 ':root[data-platform="windows"][data-theme-pack][data-theme-has-bg="true"][data-theme-scene="task"][data-theme-safe-area="right"] .app:not(.app--creation) .chat-pane > .main > .transcript-shell > .transcript';
57 const windowsTranscriptRule = ruleBody(windowsPrimaryTranscriptSelector);
58 const windowsThemeTranscriptRule = ruleBody(windowsThemeTranscriptSelector);
59 const windowsThemeImageRule = ruleBody(`${windowsThemeTranscriptSelector}::before`);
60 const windowsThemeOverlayRule = ruleBody(`${windowsThemeTranscriptSelector}::after`);
61 const windowsThemeContentRule = ruleBody(`${windowsThemeTranscriptSelector} > *`);
62 const windowsTaskTranscriptRule = ruleBody(windowsTaskTranscriptSelector);
63 const windowsTaskLeftTranscriptRule = ruleBody(windowsTaskLeftTranscriptSelector);
64 const windowsTaskRightTranscriptRule = ruleBody(windowsTaskRightTranscriptSelector);
65 const lastTransparentTranscriptRule = styles.lastIndexOf(
66 '.app:not(.app--creation) .transcript-shell {\n background: transparent !important;',
67 );
68 const windowsTranscriptRuleIndex = styles.indexOf(`${windowsPrimaryTranscriptSelector} {`);
69
70 ok(
71 /position:\s*relative;/.test(windowsTranscriptRule) &&
72 /isolation:\s*isolate;/.test(windowsTranscriptRule) &&
73 /background-color:\s*Canvas\s*!important;/.test(windowsTranscriptRule) &&
74 /linear-gradient\(var\(--chat-bg,\s*var\(--bg\)\)/.test(windowsTranscriptRule) &&
75 /linear-gradient\(var\(--bg\),\s*var\(--bg\)\)\s*!important;/.test(windowsTranscriptRule) &&
76 /clip-path:\s*inset\(0\);/.test(windowsTranscriptRule),
77 "Windows Classic and Workbench primary transcripts paint a clipped opaque repaint backing (#7011)",
78 );
79
80 ok(
81 !styles.includes(':root[data-platform="windows"] .app .transcript {') &&
82 windowsPrimaryTranscriptSelector.includes(".chat-pane > .main > .transcript-shell > .transcript"),
83 "Windows repaint backing does not leak into HistoryPanel transcripts or Creation",
84 );
85
86 ok(
87 windowsTranscriptRuleIndex > lastTransparentTranscriptRule,
88 "Windows repaint backing wins over later theme-pack transparency",
89 );
90
91 ok(
92 /background-color:\s*Canvas\s*!important;/.test(windowsThemeTranscriptRule) &&
93 /background-image:\s*linear-gradient\(var\(--bg\),\s*var\(--bg\)\)\s*!important;/.test(windowsThemeTranscriptRule) &&
94 /position:\s*fixed;/.test(windowsThemeImageRule) &&
95 /inset:\s*-4%;/.test(windowsThemeImageRule) &&
96 /z-index:\s*var\(--z-transcript-scene-image\);/.test(windowsThemeImageRule) &&
97 /pointer-events:\s*none;/.test(windowsThemeImageRule) &&
98 /background-image:\s*var\(--windows-transcript-scene-image\);/.test(windowsThemeImageRule) &&
99 /background-size:\s*cover;/.test(windowsThemeImageRule) &&
100 /background-position:\s*var\(--windows-transcript-scene-focus-x\)\s+var\(--windows-transcript-scene-focus-y\);/.test(windowsThemeImageRule) &&
101 /opacity:\s*var\(--windows-transcript-image-opacity\);/.test(windowsThemeImageRule),
102 "Windows theme image preserves the fixed -4% overscan above an opaque transcript base",
103 );
104
105 ok(
106 /position:\s*fixed;/.test(windowsThemeOverlayRule) &&
107 /inset:\s*0;/.test(windowsThemeOverlayRule) &&
108 /z-index:\s*var\(--z-transcript-scene-overlay\);/.test(windowsThemeOverlayRule) &&
109 /pointer-events:\s*none;/.test(windowsThemeOverlayRule) &&
110 /var\(--windows-transcript-pane-alpha\)/.test(windowsThemeOverlayRule) &&
111 /var\(--windows-transcript-scene-overlay\)/.test(windowsThemeOverlayRule) &&
112 /background-size:\s*100%\s+100%,\s*100%\s+100%;/.test(windowsThemeOverlayRule),
113 "Windows theme pane and safe-area wash preserve the viewport-sized overlay geometry",
114 );
115
116 const transcriptImageZ = Number(styles.match(/--z-transcript-scene-image:\s*(-?\d+);/)?.[1]);
117 const transcriptOverlayZ = Number(styles.match(/--z-transcript-scene-overlay:\s*(-?\d+);/)?.[1]);
118 const transcriptContentZ = Number(styles.match(/--z-transcript-content:\s*(-?\d+);/)?.[1]);
119
120 ok(
121 transcriptImageZ >= 0 &&
122 transcriptOverlayZ > transcriptImageZ &&
123 transcriptContentZ > transcriptOverlayZ &&
124 /position:\s*relative;/.test(windowsThemeContentRule) &&
125 /z-index:\s*var\(--z-transcript-content\);/.test(windowsThemeContentRule),
126 "Windows theme layers paint above the opaque backing and below transcript content",
127 );
128
129 ok(
130 /--windows-transcript-scene-image:\s*var\(--theme-bg-home-image/.test(windowsThemeTranscriptRule) &&
131 /--windows-transcript-image-opacity:\s*var\(--theme-bg-home-opacity/.test(windowsThemeTranscriptRule) &&
132 /--windows-transcript-pane-alpha:\s*var\(--theme-pane-alpha/.test(windowsThemeTranscriptRule) &&
133 /--windows-transcript-scene-image:\s*var\(--theme-bg-task-image/.test(windowsTaskTranscriptRule) &&
134 /--windows-transcript-image-opacity:\s*var\(--theme-bg-task-opacity/.test(windowsTaskTranscriptRule) &&
135 /--windows-transcript-pane-alpha:\s*var\(--theme-pane-task-alpha/.test(windowsTaskTranscriptRule),
136 "Windows home and task scenes use their matching image, opacity, and pane tokens",
137 );
138
139 ok(
140 /radial-gradient\(/.test(windowsTaskTranscriptRule) &&
141 /linear-gradient\(\s*90deg,/.test(windowsTaskLeftTranscriptRule) &&
142 /linear-gradient\(\s*270deg,/.test(windowsTaskRightTranscriptRule) &&
143 /--windows-transcript-scene-overlay:/.test(windowsTaskTranscriptRule) &&
144 /--windows-transcript-scene-overlay:/.test(windowsTaskLeftTranscriptRule) &&
145 /--windows-transcript-scene-overlay:/.test(windowsTaskRightTranscriptRule),
146 "Windows task scene preserves center, left, and right safe-area washes",
147 );
148
149 console.log(`\n${passed} passed, ${failed} failed, ${passed + failed} total`);
150 if (failed > 0) process.exit(1);
151
151 lines TYPESCRIPT