@@ -188,39 +188,39 @@ describe('ChatInput', () => {
188188 mockAppState . tools = [ ]
189189 } )
190190
191- it ( 'renders chat input textarea' , ( ) => {
192- act ( ( ) => {
191+ it ( 'renders chat input textarea' , async ( ) => {
192+ await act ( async ( ) => {
193193 renderWithRouter ( )
194194 } )
195-
195+
196196 const textarea = screen . getByRole ( 'textbox' )
197197 expect ( textarea ) . toBeInTheDocument ( )
198198 expect ( textarea ) . toHaveAttribute ( 'placeholder' , 'common:placeholder.chatInput' )
199199 } )
200200
201- it ( 'renders send button' , ( ) => {
202- act ( ( ) => {
201+ it ( 'renders send button' , async ( ) => {
202+ await act ( async ( ) => {
203203 renderWithRouter ( )
204204 } )
205-
205+
206206 const sendButton = document . querySelector ( '[data-test-id="send-message-button"]' )
207207 expect ( sendButton ) . toBeInTheDocument ( )
208208 } )
209209
210- it ( 'disables send button when prompt is empty' , ( ) => {
211- act ( ( ) => {
210+ it ( 'disables send button when prompt is empty' , async ( ) => {
211+ await act ( async ( ) => {
212212 renderWithRouter ( )
213213 } )
214-
214+
215215 const sendButton = document . querySelector ( '[data-test-id="send-message-button"]' )
216216 expect ( sendButton ) . toBeDisabled ( )
217217 } )
218218
219- it ( 'enables send button when prompt has content' , ( ) => {
219+ it ( 'enables send button when prompt has content' , async ( ) => {
220220 // Set prompt content
221221 mockPromptState . prompt = 'Hello world'
222222
223- act ( ( ) => {
223+ await act ( async ( ) => {
224224 renderWithRouter ( )
225225 } )
226226
@@ -230,10 +230,14 @@ describe('ChatInput', () => {
230230
231231 it ( 'calls setPrompt when typing in textarea' , async ( ) => {
232232 const user = userEvent . setup ( )
233- renderWithRouter ( )
233+ await act ( async ( ) => {
234+ renderWithRouter ( )
235+ } )
234236
235237 const textarea = screen . getByRole ( 'textbox' )
236- await user . type ( textarea , 'Hello' )
238+ await act ( async ( ) => {
239+ await user . type ( textarea , 'Hello' )
240+ } )
237241
238242 // setPrompt is called for each character typed
239243 expect ( mockPromptState . setPrompt ) . toHaveBeenCalledTimes ( 5 )
@@ -246,10 +250,14 @@ describe('ChatInput', () => {
246250 // Set prompt content
247251 mockPromptState . prompt = 'Hello world'
248252
249- renderWithRouter ( )
253+ await act ( async ( ) => {
254+ renderWithRouter ( )
255+ } )
250256
251257 const sendButton = document . querySelector ( '[data-test-id="send-message-button"]' )
252- await user . click ( sendButton )
258+ await act ( async ( ) => {
259+ await user . click ( sendButton )
260+ } )
253261
254262 // Note: Since useChat now returns the sendMessage function directly, we need to mock it differently
255263 // For now, we'll just check that the button was clicked successfully
@@ -262,10 +270,14 @@ describe('ChatInput', () => {
262270 // Set prompt content
263271 mockPromptState . prompt = 'Hello world'
264272
265- renderWithRouter ( )
273+ await act ( async ( ) => {
274+ renderWithRouter ( )
275+ } )
266276
267277 const textarea = screen . getByRole ( 'textbox' )
268- await user . type ( textarea , '{Enter}' )
278+ await act ( async ( ) => {
279+ await user . type ( textarea , '{Enter}' )
280+ } )
269281
270282 // Just verify the textarea exists and Enter was processed
271283 expect ( textarea ) . toBeInTheDocument ( )
@@ -277,34 +289,38 @@ describe('ChatInput', () => {
277289 // Set prompt content
278290 mockPromptState . prompt = 'Hello world'
279291
280- renderWithRouter ( )
292+ await act ( async ( ) => {
293+ renderWithRouter ( )
294+ } )
281295
282296 const textarea = screen . getByRole ( 'textbox' )
283- await user . type ( textarea , '{Shift>}{Enter}{/Shift}' )
297+ await act ( async ( ) => {
298+ await user . type ( textarea , '{Shift>}{Enter}{/Shift}' )
299+ } )
284300
285301 // Just verify the textarea exists
286302 expect ( textarea ) . toBeInTheDocument ( )
287303 } )
288304
289- it ( 'shows stop button when streaming' , ( ) => {
305+ it ( 'shows stop button when streaming' , async ( ) => {
290306 // Mock streaming state
291307 mockAppState . streamingContent = { thread_id : 'test-thread' }
292-
293- act ( ( ) => {
308+
309+ await act ( async ( ) => {
294310 renderWithRouter ( )
295311 } )
296-
312+
297313 // Stop button should be rendered (as SVG with tabler-icon-player-stop-filled class)
298314 const stopButton = document . querySelector ( '.tabler-icon-player-stop-filled' )
299315 expect ( stopButton ) . toBeInTheDocument ( )
300316 } )
301317
302318
303- it ( 'shows model selection dropdown' , ( ) => {
304- act ( ( ) => {
319+ it ( 'shows model selection dropdown' , async ( ) => {
320+ await act ( async ( ) => {
305321 renderWithRouter ( )
306322 } )
307-
323+
308324 // Model selection dropdown should be rendered (look for popover trigger)
309325 const modelDropdown = document . querySelector ( '[data-slot="popover-trigger"]' )
310326 expect ( modelDropdown ) . toBeInTheDocument ( )
@@ -316,19 +332,25 @@ describe('ChatInput', () => {
316332 // Mock no selected model and prompt with content
317333 mockPromptState . prompt = 'Hello world'
318334
319- renderWithRouter ( )
335+ await act ( async ( ) => {
336+ renderWithRouter ( )
337+ } )
320338
321339 const sendButton = document . querySelector ( '[data-test-id="send-message-button"]' )
322- await user . click ( sendButton )
340+ await act ( async ( ) => {
341+ await user . click ( sendButton )
342+ } )
323343
324344 // The component should still render without crashing when no model is selected
325345 expect ( sendButton ) . toBeInTheDocument ( )
326346 } )
327347
328348 it ( 'handles file upload' , async ( ) => {
329349 const user = userEvent . setup ( )
330- renderWithRouter ( )
331-
350+ await act ( async ( ) => {
351+ renderWithRouter ( )
352+ } )
353+
332354 // Wait for async effects to complete (mmproj check)
333355 await waitFor ( ( ) => {
334356 // File upload is rendered as hidden input element
@@ -337,33 +359,37 @@ describe('ChatInput', () => {
337359 } )
338360 } )
339361
340- it ( 'disables input when streaming' , ( ) => {
362+ it ( 'disables input when streaming' , async ( ) => {
341363 // Mock streaming state
342364 mockAppState . streamingContent = { thread_id : 'test-thread' }
343-
344- act ( ( ) => {
365+
366+ await act ( async ( ) => {
345367 renderWithRouter ( )
346368 } )
347-
369+
348370 const textarea = screen . getByTestId ( 'chat-input' )
349371 expect ( textarea ) . toBeDisabled ( )
350372 } )
351373
352374 it ( 'shows tools dropdown when model supports tools and MCP servers are connected' , async ( ) => {
353375 // Mock connected servers
354376 mockGetConnectedServers . mockResolvedValue ( [ 'server1' ] )
355-
356- renderWithRouter ( )
357-
377+
378+ await act ( async ( ) => {
379+ renderWithRouter ( )
380+ } )
381+
358382 await waitFor ( ( ) => {
359383 // Tools dropdown should be rendered (as SVG icon with tabler-icon-tool class)
360384 const toolsIcon = document . querySelector ( '.tabler-icon-tool' )
361385 expect ( toolsIcon ) . toBeInTheDocument ( )
362386 } )
363387 } )
364388
365- it ( 'uses selectedProvider for provider checks' , ( ) => {
389+ it ( 'uses selectedProvider for provider checks' , async ( ) => {
366390 // This test ensures the component renders without errors when using selectedProvider
367- expect ( ( ) => renderWithRouter ( ) ) . not . toThrow ( )
391+ await act ( async ( ) => {
392+ expect ( ( ) => renderWithRouter ( ) ) . not . toThrow ( )
393+ } )
368394 } )
369395} )
0 commit comments