@@ -24,6 +24,22 @@ vi.mock('../hooks/useSync.js', () => ({
2424
2525const testHeader = < Text > HEADER</ Text > ;
2626
27+ async function waitForFrameContains (
28+ instance : ReturnType < typeof render > ,
29+ needle : string ,
30+ timeoutMs = 1500 ,
31+ ) : Promise < string > {
32+ const start = Date . now ( ) ;
33+ let frame = stripAnsi ( instance . lastFrame ( ) ?? '' ) ;
34+
35+ while ( ! frame . includes ( needle ) && Date . now ( ) - start < timeoutMs ) {
36+ await wait ( 25 ) ;
37+ frame = stripAnsi ( instance . lastFrame ( ) ?? '' ) ;
38+ }
39+
40+ return frame ;
41+ }
42+
2743describe ( 'MainShell' , ( ) => {
2844 let onNavigate : ReturnType < typeof vi . fn < ( target : NavigationTarget , props ?: NavigationProps ) => void > > ;
2945
@@ -49,11 +65,9 @@ describe('MainShell', () => {
4965 ) ;
5066
5167 // Use /h alias which is shorter and more reliable in CI
52- await typeText ( instance , '/h ' ) ;
68+ await typeText ( instance , '/help ' ) ;
5369 pressEnter ( instance ) ;
54- await wait ( 100 ) ;
55-
56- const frame = stripAnsi ( instance . lastFrame ( ) ?? '' ) ;
70+ const frame = await waitForFrameContains ( instance , 'Available commands' ) ;
5771 expect ( frame ) . toContain ( 'Available commands' ) ;
5872 instance . unmount ( ) ;
5973 } ) ;
@@ -110,9 +124,7 @@ describe('MainShell', () => {
110124
111125 await typeText ( instance , '/h ' ) ;
112126 pressEnter ( instance ) ;
113- await wait ( 50 ) ;
114-
115- const frame = stripAnsi ( instance . lastFrame ( ) ?? '' ) ;
127+ const frame = await waitForFrameContains ( instance , 'Available commands' ) ;
116128 expect ( frame ) . toContain ( 'Available commands' ) ;
117129 instance . unmount ( ) ;
118130 } ) ;
0 commit comments