@@ -193,7 +193,7 @@ async function render(
193193 requestMode : 'agent' | 'assistant' = 'assistant' ,
194194 controls : Pick <
195195 ComponentProps < typeof Composer > ,
196- 'isSending' | 'showModeSelector' | 'onModeChange' | 'restoredContexts'
196+ 'isSending' | 'showModeSelector' | 'onModeChange' | 'restoredContexts' | 'onSendQueuedHead'
197197 > = { isSending : false }
198198) {
199199 function Harness ( ) {
@@ -215,6 +215,7 @@ async function render(
215215 isInitialView = { isInitialView }
216216 isSending = { controls . isSending }
217217 onStop = { vi . fn ( ) }
218+ onSendQueuedHead = { controls . onSendQueuedHead }
218219 onSubmit = { ( text , contexts ) => {
219220 mocks . submit ( text , files . attachedFiles )
220221 mocks . contexts ( contexts )
@@ -919,3 +920,42 @@ it('offers the advanced models and each model’s supported efforts', async () =
919920 )
920921 ) . toEqual ( [ 'Low' , 'Medium' , 'High' , 'Extra High' , 'Max' ] )
921922} )
923+
924+ it . each ( [
925+ [ 'agent' , false ] ,
926+ [ 'assistant' , false ] ,
927+ [ 'agent' , true ] ,
928+ [ 'assistant' , true ] ,
929+ ] as const ) (
930+ 'queues once then sends immediately on rapid double Enter (%s, attachment: %s)' ,
931+ async ( mode , withAttachment ) => {
932+ const sendHead = vi . fn ( )
933+ await render ( false , withAttachment ? '' : 'Use the latest report' , mode , {
934+ isSending : true ,
935+ onSendQueuedHead : sendHead ,
936+ } )
937+ if ( withAttachment ) await paste ( [ new File ( [ 'image' ] , 'follow-up.png' , { type : 'image/png' } ) ] )
938+ const input = container . querySelector < HTMLTextAreaElement > ( '[aria-label="Ask Sim"]' ) !
939+ await act ( async ( ) => {
940+ input . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'Enter' , bubbles : true } ) )
941+ expect ( mocks . submit ) . toHaveBeenCalledTimes ( 1 )
942+ expect ( sendHead ) . not . toHaveBeenCalled ( )
943+ input . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'Enter' , bubbles : true } ) )
944+ } )
945+ expect ( mocks . submit ) . toHaveBeenCalledTimes ( 1 )
946+ expect ( sendHead ) . toHaveBeenCalledExactlyOnceWith ( )
947+ expect ( input . value ) . toBe ( '' )
948+ }
949+ )
950+
951+ it ( 'does not send a queued head on empty Enter when idle' , async ( ) => {
952+ const sendHead = vi . fn ( )
953+ await render ( false , '' , 'assistant' , { isSending : false , onSendQueuedHead : sendHead } )
954+ await act ( async ( ) => {
955+ container
956+ . querySelector < HTMLTextAreaElement > ( '[aria-label="Ask Sim"]' ) !
957+ . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'Enter' , bubbles : true } ) )
958+ } )
959+ expect ( sendHead ) . not . toHaveBeenCalled ( )
960+ expect ( mocks . submit ) . not . toHaveBeenCalled ( )
961+ } )
0 commit comments