feat(config): consistent CLI behaviour and e2e test coverage#801
Merged
natalie-o-perret merged 13 commits intomasterfrom Feb 25, 2026
Merged
Conversation
- Add PTY infrastructure for testing interactive commands using testscript - Add execpty command with support for 8 input tokens - Add automated tests for interactive flows - Fix config file creation when adding first account - Fix circular dependency in config set command - Fix panic when used without default account set #798 - Update CI workflow to use build action and add test job dependencies - Remove redundant testscript.yml workflow - Make integration tests resilient when no test files exist #800
- Exit with code 130 and print 'Error: Operation Cancelled' on Ctrl+C in exo config menu and exo config add flows - Propagate zone selection cancellation cleanly via io.EOF - Rename tests/integ/ to tests/integration/ with clearer split: - without-api/ for CI-safe tests - with-api/ for tests requiring real API credentials - Add tests/integration/README.md documenting test structure - Add 13 new e2e testscript scenarios covering cancellation, input validation, multi-account workflows and edge cases Relates-to: SC-167884
utils.AskQuestion uses bufio.ReadString('\n') which blocks in PTY raw
mode — after promptui.Select (zone picker) returns, the terminal buffer
already holds '\r' from raw mode, which is never translated to '\n'.
Replace with a promptui.Prompt (askSetDefault) that reads character-by-
character in raw mode and accepts '\r' as confirmation, matching the
behaviour of the other interactive prompts.
Fixes timeout in:
- add_interactive_second_account
- add_interactive_make_new_default
- add_interactive_duplicate_name
Relates-to: SC-167884
…Y race - Rename tests/integration/ to tests/integ/ for consistency - Fix package name in suite.go from 'integration' to 'integ' - Fix tests/e2e module name to github.com/exoscale/cli/internal/e2e (was incorrectly sharing the same name as tests/integ) - Fix race condition in runInPTY: cmd.Wait() was running in a goroutine without synchronisation, causing ProcessState to be unpopulated when cmdExecPTY read the exit code (always -1 on Linux via EIO path)
The goroutine-based cmd.Wait() approach introduced a race where ProcessState could be nil when cmdExecPTY read the exit code. Revert to the simpler sequential approach: wait for the process, close the PTY master, then drain the output channel.
…o reader
promptui.Prompt uses readline which defers its initial PTY render until the
first keystroke arrives. This creates a deadlock with the settle-based PTY
test harness: the harness waits for output-then-silence before sending each
keystroke, but the prompt waits for a keystroke before producing output.
Replace with a plain bufio.ReadString('\n') that mirrors the other prompts
and avoids readline raw-mode entirely. The PTY line discipline (cooked mode,
restored by the preceding promptui.Select) translates '\r' -> '\n' for us.
…ness The 80ms inter-keystroke delay was too short on CI: keystrokes sent after zone selection arrived before the process had rendered the next prompt (e.g. 'Make default? [y/n]'), causing the process to hang waiting for input with an empty inputs channel. Increase the fixed delay to 300ms to give the process enough time to render each prompt before the next keystroke is sent.
…i-consistent-behaviour
afe431b to
c51ae1d
Compare
pierre-emmanuelJ
approved these changes
Feb 24, 2026
nerzhul
reviewed
Feb 24, 2026
- Add ExitCodeInterrupt constant (130) for SIGINT in cmd/common.go - Distinguish between Ctrl+C (ErrInterrupt) and Ctrl+D (ErrEOF) - Ctrl+C: shows 'Operation Cancelled', exits 130 - Ctrl+D: exits gracefully with code 0 - Applied to config.go and config_add.go prompt handlers
nerzhul
approved these changes
Feb 25, 2026
- Add TTY check to prevent prompting in non-interactive contexts - Fix zone selection to properly propagate ErrInterrupt and ErrEOF - Add interrupt handling for zone selection in config add - Add test for Ctrl+C cancellation (exits 130, shows error) - Update test for Ctrl+D cancellation (exits 0, graceful) - All 18 E2E scenarios now passing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Checklist
(For exoscale contributors)
CHANGELOG.md)Testing