@@ -8,8 +8,10 @@ import {
88 createAppShell ,
99 enterCopyMode ,
1010 toggleMouseCapture ,
11+ type FlashSchedule ,
1112} from "./shell" ;
1213import { createRecordingClipboard } from "./copy-path" ;
14+ import { RUNTIME_FLASH_MS } from "./runtime-notices" ;
1315
1416// One renderer for the whole file: harness renderers are a scarce native
1517// resource and the suite exhausts them when every test claims its own.
@@ -23,6 +25,15 @@ afterAll(() => {
2325 harness . destroy ( ) ;
2426} ) ;
2527
28+ /** Capture scheduled flash expiries so tests can lapse without wall time. */
29+ function capturingSchedule ( lapse : ( ( ) => void ) [ ] , expectedMs = RUNTIME_FLASH_MS ) : FlashSchedule {
30+ return ( fn , ms ) => {
31+ expect ( ms ) . toBe ( expectedMs ) ;
32+ lapse . push ( fn ) ;
33+ return ( ) => { } ;
34+ } ;
35+ }
36+
2637describe ( "Alt+C reaches the injected clipboard" , ( ) => {
2738 test ( "confirming a copy target writes its text" , ( ) => {
2839 const clipboard = createRecordingClipboard ( ) ;
@@ -46,6 +57,36 @@ describe("Alt+C reaches the injected clipboard", () => {
4657 expect ( clipboard . writes [ 0 ] ) . toContain ( "two" ) ;
4758 shell . dispose ( ) ;
4859 } ) ;
60+
61+ test ( "copy confirmation clears itself when the flash window lapses" , ( ) => {
62+ const lapse : ( ( ) => void ) [ ] = [ ] ;
63+ const clipboard = createRecordingClipboard ( ) ;
64+ const shell = createAppShell ( harness . renderer , {
65+ clipboard,
66+ flashSchedule : capturingSchedule ( lapse ) ,
67+ } ) ;
68+ appendStreamRow ( shell , { role : "assistant" , text : "copy me" } ) ;
69+ enterCopyMode ( shell ) ;
70+ expect ( confirmCopySelection ( shell ) ) . toBe ( true ) ;
71+ expect ( shell . statusFlash ) . toContain ( "Copied" ) ;
72+ expect ( lapse ) . toHaveLength ( 1 ) ;
73+ lapse [ 0 ] ?.( ) ;
74+ expect ( shell . statusFlash ) . toBeNull ( ) ;
75+ shell . dispose ( ) ;
76+ } ) ;
77+
78+ test ( "nothing-to-copy flash clears itself when the window lapses" , ( ) => {
79+ const lapse : ( ( ) => void ) [ ] = [ ] ;
80+ const shell = createAppShell ( harness . renderer , {
81+ flashSchedule : capturingSchedule ( lapse ) ,
82+ } ) ;
83+ expect ( enterCopyMode ( shell ) ) . toBe ( false ) ;
84+ expect ( shell . statusFlash ) . toBe ( "nothing to copy" ) ;
85+ expect ( lapse ) . toHaveLength ( 1 ) ;
86+ lapse [ 0 ] ?.( ) ;
87+ expect ( shell . statusFlash ) . toBeNull ( ) ;
88+ shell . dispose ( ) ;
89+ } ) ;
4990} ) ;
5091
5192describe ( "drag-select auto-copy" , ( ) => {
@@ -62,6 +103,24 @@ describe("drag-select auto-copy", () => {
62103 shell . dispose ( ) ;
63104 } ) ;
64105
106+ test ( "SELECTION flash clears itself when the window lapses" , ( ) => {
107+ const lapse : ( ( ) => void ) [ ] = [ ] ;
108+ const clipboard = createRecordingClipboard ( ) ;
109+ const shell = createAppShell ( harness . renderer , {
110+ clipboard,
111+ flashSchedule : capturingSchedule ( lapse ) ,
112+ } ) ;
113+ harness . renderer . emit ( CliRenderEvents . SELECTION , {
114+ isDragging : false ,
115+ getSelectedText : ( ) => "dragged snippet" ,
116+ } ) ;
117+ expect ( shell . statusFlash ) . toContain ( "Copied 15 chars" ) ;
118+ expect ( lapse ) . toHaveLength ( 1 ) ;
119+ lapse [ 0 ] ?.( ) ;
120+ expect ( shell . statusFlash ) . toBeNull ( ) ;
121+ shell . dispose ( ) ;
122+ } ) ;
123+
65124 test ( "SELECTION while dragging is a no-op" , ( ) => {
66125 const clipboard = createRecordingClipboard ( ) ;
67126 const shell = createAppShell ( harness . renderer , { clipboard } ) ;
@@ -105,6 +164,26 @@ describe("Alt+M mouse capture", () => {
105164 shell . dispose ( ) ;
106165 } ) ;
107166
167+ test ( "mouse-toggle flash clears itself when the window lapses" , ( ) => {
168+ const lapse : ( ( ) => void ) [ ] = [ ] ;
169+ let enabled = false ;
170+ const shell = createAppShell ( harness . renderer , {
171+ flashSchedule : capturingSchedule ( lapse ) ,
172+ mouseCapture : {
173+ get : ( ) => enabled ,
174+ set : ( v ) => {
175+ enabled = v ;
176+ } ,
177+ } ,
178+ } ) ;
179+ expect ( toggleMouseCapture ( shell ) ) . toBe ( true ) ;
180+ expect ( shell . statusFlash ) . toContain ( "drag text to copy" ) ;
181+ expect ( lapse ) . toHaveLength ( 1 ) ;
182+ lapse [ 0 ] ?.( ) ;
183+ expect ( shell . statusFlash ) . toBeNull ( ) ;
184+ shell . dispose ( ) ;
185+ } ) ;
186+
108187 test ( "reports unavailable when the host exposes no control" , ( ) => {
109188 const shell = createAppShell ( harness . renderer ) ;
110189 expect ( toggleMouseCapture ( shell ) ) . toBeNull ( ) ;
0 commit comments