11import { renderInMode , testBothModes } from "./TUIChat.dualModeHelper.js" ;
2- import { waitForCondition , waitForNextRender } from "./TUIChat.testHelper.js" ;
2+ import { waitForCondition } from "./TUIChat.testHelper.js" ;
33
44describe ( "TUIChat - Slash Commands Tests" , ( ) => {
55 testBothModes ( "shows slash when user types /" , async ( mode ) => {
66 const { lastFrame, stdin } = renderInMode ( mode ) ;
77
88 // Type / to trigger slash command
99 stdin . write ( "/" ) ;
10- await waitForNextRender ( ) ;
1110
12- const frame = lastFrame ( ) ;
11+ let frame = "" ;
12+ await waitForCondition ( ( ) => {
13+ frame = lastFrame ( ) ?? "" ;
14+ return frame . includes ( "/" ) ;
15+ } ) ;
1316
1417 // Should show the slash character
1518 expect ( frame ) . toContain ( "/" ) ;
@@ -51,14 +54,21 @@ describe("TUIChat - Slash Commands Tests", () => {
5154 testBothModes ( "handles tab key after slash command" , async ( mode ) => {
5255 const { lastFrame, stdin } = renderInMode ( mode ) ;
5356
54- // Type /exi and then tab
5557 stdin . write ( "/exi" ) ;
56- await waitForNextRender ( ) ;
58+
59+ let frame = "" ;
60+ await waitForCondition ( ( ) => {
61+ frame = lastFrame ( ) ?? "" ;
62+ return frame . includes ( "/exi" ) ;
63+ } ) ;
5764
5865 stdin . write ( "\t" ) ;
59- await waitForNextRender ( ) ;
6066
61- const frameAfterTab = lastFrame ( ) ;
67+ let frameAfterTab = "" ;
68+ await waitForCondition ( ( ) => {
69+ frameAfterTab = lastFrame ( ) ?? "" ;
70+ return frameAfterTab . length > 0 ;
71+ } ) ;
6272
6373 // Should not crash after tab
6474 expect ( frameAfterTab ) . toBeDefined ( ) ;
@@ -77,11 +87,13 @@ describe("TUIChat - Slash Commands Tests", () => {
7787 testBothModes ( "shows slash command menu when typing /" , async ( mode ) => {
7888 const { lastFrame, stdin } = renderInMode ( mode ) ;
7989
80- // Type just /
8190 stdin . write ( "/" ) ;
82- await waitForNextRender ( ) ;
8391
84- const frame = lastFrame ( ) ;
92+ let frame = "" ;
93+ await waitForCondition ( ( ) => {
94+ frame = lastFrame ( ) ?? "" ;
95+ return frame . includes ( "/" ) ;
96+ } ) ;
8597
8698 // Should show the slash
8799 expect ( frame ) . toContain ( "/" ) ;
@@ -111,9 +123,18 @@ describe("TUIChat - Slash Commands Tests", () => {
111123
112124 // Type a complete command name first
113125 stdin . write ( "/title" ) ;
114- await waitForNextRender ( ) ;
115126
116- const frameAfterCommand = lastFrame ( ) ;
127+ let frameAfterCommand = lastFrame ( ) ;
128+ await waitForCondition ( ( ) => {
129+ frameAfterCommand = lastFrame ( ) ;
130+
131+ return (
132+ frameAfterCommand ?. includes (
133+ mode === "remote" ? "Remote Mode" : "/title" ,
134+ ) ?? false
135+ ) ;
136+ } ) ;
137+
117138 if ( mode === "remote" ) {
118139 // In remote mode, /title might not be a valid command, so just check we're in remote mode
119140 expect ( frameAfterCommand ) . toContain ( "Remote Mode" ) ;
@@ -124,9 +145,12 @@ describe("TUIChat - Slash Commands Tests", () => {
124145
125146 // Now add a space and arguments
126147 stdin . write ( " My Session Title" ) ;
127- await waitForNextRender ( ) ;
128148
129- const frameAfterArgs = lastFrame ( ) ;
149+ let frameAfterArgs = lastFrame ( ) ;
150+ await waitForCondition ( ( ) => {
151+ frameAfterArgs = lastFrame ( ) ?? "" ;
152+ return frameAfterArgs . includes ( "My Session Title" ) ;
153+ } ) ;
130154
131155 // Check that the UI is still functional after adding arguments
132156 if ( mode === "remote" ) {
@@ -145,19 +169,27 @@ describe("TUIChat - Slash Commands Tests", () => {
145169 async ( mode ) => {
146170 const { lastFrame, stdin } = renderInMode ( mode ) ;
147171
148- // Type a complete command with arguments
149172 stdin . write ( "/title Test Session" ) ;
150- await waitForNextRender ( ) ;
151173
152- const frameBeforeEnter = lastFrame ( ) ;
174+ let frameBeforeEnter = lastFrame ( ) ;
175+ await waitForCondition ( ( ) => {
176+ frameBeforeEnter = lastFrame ( ) ?? "" ;
177+ return (
178+ frameBeforeEnter . includes ( "/title" ) &&
179+ frameBeforeEnter . includes ( "Test Session" )
180+ ) ;
181+ } ) ;
182+
153183 expect ( frameBeforeEnter ) . toContain ( "/title" ) ;
154184 expect ( frameBeforeEnter ) . toContain ( "Test Session" ) ;
155185
156- // Press Enter - this should execute the command, not try to autocomplete
157186 stdin . write ( "\r" ) ;
158- await waitForNextRender ( ) ;
159187
160- const frameAfterEnter = lastFrame ( ) ;
188+ let frameAfterEnter = lastFrame ( ) ;
189+ await waitForCondition ( ( ) => {
190+ frameAfterEnter = lastFrame ( ) ?? "" ;
191+ return frameAfterEnter . length > 0 ;
192+ } ) ;
161193
162194 // Should not crash and should clear the input (or show command execution)
163195 expect ( frameAfterEnter ) . toBeDefined ( ) ;
0 commit comments