Skip to content

Commit 6cb097d

Browse files
committed
Fix flaky E2E tests
- Ctrl+C exit tests: capture state before/after second Ctrl+C, check if exit message appeared or text changed - --help flag test: use waitForText instead of fixed sleep
1 parent b5c4da2 commit 6cb097d

File tree

2 files changed

+58
-25
lines changed

2 files changed

+58
-25
lines changed

cli/src/__tests__/e2e/cli-ui.test.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -267,20 +267,34 @@ describe('CLI UI Tests', () => {
267267
// Wait for initial render
268268
await sleep(2000)
269269

270-
// Press Ctrl+C twice to exit (first shows warning, second exits)
270+
// Press Ctrl+C once - this should show the exit warning
271271
await session.press(['ctrl', 'c'])
272-
await sleep(500)
272+
await sleep(1000)
273+
274+
// Capture text after first Ctrl+C (should show warning)
275+
const textAfterFirstCtrlC = await session.text()
276+
277+
// Press Ctrl+C again - this should trigger exit
273278
await session.press(['ctrl', 'c'])
274279

275-
// Give time for process to exit
276-
await sleep(1000)
280+
// Wait for exit message to appear (gracefulExit prints "Goodbye! Exiting...")
281+
try {
282+
await session.waitForText(/goodbye|exiting/i, { timeout: 5000 })
283+
} catch {
284+
// If waitForText times out, the process may have exited without printing
285+
}
277286

278-
const text = await session.text()
279-
const exited =
280-
text.toLowerCase().includes('exit') ||
281-
text.toLowerCase().includes('goodbye') ||
282-
text.toLowerCase().includes('quit') ||
283-
text.trim().length === 0
287+
const textAfterSecondCtrlC = await session.text()
288+
289+
// The CLI should either:
290+
// 1. Show goodbye/exiting message (graceful exit message was captured)
291+
// 2. Have changed from the first Ctrl+C state (something happened after second Ctrl+C)
292+
const hasExitMessage =
293+
textAfterSecondCtrlC.toLowerCase().includes('goodbye') ||
294+
textAfterSecondCtrlC.toLowerCase().includes('exiting')
295+
const textChanged = textAfterSecondCtrlC !== textAfterFirstCtrlC
296+
297+
const exited = hasExitMessage || textChanged
284298
expect(exited).toBe(true)
285299
} finally {
286300
session.close()

cli/src/__tests__/e2e/full-stack.test.ts

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,12 @@ describe('E2E: CLI Flags', () => {
534534
'--help',
535535
])
536536

537-
await sleep(3000)
537+
// Wait for help content to appear
538+
try {
539+
await session.cli.waitForText(/usage|options|help|command|--/i, { timeout: 10000 })
540+
} catch {
541+
// If timeout, continue and check what we have
542+
}
538543

539544
const text = await session.cli.text()
540545
// Should show help content
@@ -662,23 +667,37 @@ describe('E2E: Keyboard Interactions', () => {
662667

663668
await sleep(5000)
664669

665-
// Press Ctrl+C twice
670+
// Press Ctrl+C once - this should show the exit warning
666671
await session.cli.press(['ctrl', 'c'])
667-
await sleep(500)
672+
await sleep(1000)
673+
674+
// Capture text after first Ctrl+C (should show warning)
675+
const textAfterFirstCtrlC = await session.cli.text()
676+
677+
// Press Ctrl+C again - this should trigger exit
668678
await session.cli.press(['ctrl', 'c'])
669-
await sleep(1500)
670679

671-
// Either the CLI exits or remains responsive to further input
672-
await session.cli.type('ping')
673-
await sleep(500)
674-
const text = await session.cli.text()
675-
const exited =
676-
text.toLowerCase().includes('exit') ||
677-
text.toLowerCase().includes('goodbye') ||
678-
text.toLowerCase().includes('quit') ||
679-
text.trim().length === 0
680-
const responsive = text.toLowerCase().includes('ping')
681-
expect(exited || responsive).toBe(true)
680+
// Wait for exit message to appear (gracefulExit prints "Goodbye! Exiting...")
681+
// Use waitForText which polls the terminal output until the text appears or timeout
682+
try {
683+
await session.cli.waitForText(/goodbye|exiting/i, { timeout: 5000 })
684+
} catch {
685+
// If waitForText times out, the process may have exited without printing
686+
// (e.g., if stdout was closed before the message could be written)
687+
}
688+
689+
const textAfterSecondCtrlC = await session.cli.text()
690+
691+
// The CLI should either:
692+
// 1. Show goodbye/exiting message (graceful exit message was captured)
693+
// 2. Have changed from the first Ctrl+C state (something happened after second Ctrl+C)
694+
const hasExitMessage =
695+
textAfterSecondCtrlC.toLowerCase().includes('goodbye') ||
696+
textAfterSecondCtrlC.toLowerCase().includes('exiting')
697+
const textChanged = textAfterSecondCtrlC !== textAfterFirstCtrlC
698+
699+
const exited = hasExitMessage || textChanged
700+
expect(exited).toBe(true)
682701
},
683702
TIMEOUT_MS,
684703
)

0 commit comments

Comments
 (0)