test(e2e): PTY-driven TUI regressions and screen-interaction coverage - #179
Merged
Conversation
Nine new integration tests in internal/e2e, all driving the real ccmux binary through a PTY on a hermetic fixture. Regression tests for the PR #168 key-routing fixes (each verified to FAIL with the corresponding fix reverted, then pass at HEAD): - TestTUIFlow_SettingsEditorCapturesTypedKeys — typing "~/repos2q" into the projects.root inline editor lands every character; no refresh, no screen switch, no quit modal. Esc cancels without touching config.toml. - TestTUIFlow_AgentsModelPickerSwallowsGlobalKeys — the open Claude model picker swallows Tab and digits (no Codex sub-tab yank, no Projects jump); Esc returns to the Agents screen. - TestTUIFlow_ProjectsCommittedFilterEscClears — a committed no-match filter shows the empty state and Esc restores the full project list. - TestTUIFlow_SpinnerScreensStayResponsive — Conversations and Notes render their chrome and keep answering input (help open/close, screen switches); asserts responsiveness, not animation frames. Coverage for surfaces with no prior e2e test: - TestTUIFlow_UsageOverlayOpenCloseSwallowsKeys — `u` overlay opens, swallows `p` (preview must not toggle underneath), Esc restores the session detail pane. - TestTUIFlow_SessionPreviewToggle — `p` swaps the detail pane for a live capture of the real tmux pane (asserted via an echoed marker), `p` again restores metadata; rapid double-toggle leaves the UI responsive. - TestTUIFlow_NotesFolderExpandCollapse — Right expands a collapsed docs/ folder (child note appears, ▸→▾), Left collapses it back. - TestTUIFlow_TerminalResize — pty.Setsize 120x40 → 60x20 → 120x40: narrow tab bar renders, wide hero returns, no panic, process stays responsive. - TestTUIFlow_TourCompletionPersists — skipping the first-run tour persists Tour.Shown; a second launch in the same env boots straight to Sessions. New driver helpers (tui_driver_ext_test.go): Mark / OutputSince / WaitForSince / RefuteSince add since-a-mark matching against the cumulative PTY buffer — needed both for "this repainted after the action" and "this key was swallowed" assertions — plus Resize (pty.Setsize → SIGWINCH) and Alive. Tests follow the wait-between- keys discipline because bytes landing in one PTY read coalesce into a single multi-rune key ("/z") or an alt-chord (Esc+4). go test ./... green; make test-e2e green (internal/e2e 48s of the 180s budget). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The final assertion waited for "[2] Projects" to appear after pressing 2, but the wide tab bar lists every tab all the time — that string was already on screen. Passing therefore required the repaint to happen to redraw that exact span, which differential rendering doesn't promise: green on macOS, red on Linux CI (8s timeout). Wait for a fixture project name instead. It appears only once the Projects body paints, so it's unambiguously new output. Also drops the test from 8.2s (timeout) to 0.4s. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Nine new PTY-driven e2e tests exercising the real TUI through a terminal. No production changes (diff is
internal/e2e/only).Regression tests for this week's fixes — each verified to fail against the reverted fix, with the exact pre-fix symptom observed:
TestTUIFlow_SettingsEditorCapturesTypedKeys— types~/repos2qinto the projects.root editor. Reverting fix(tui): settings-editor key capture, spinner starvation, picker modal leaks, filter esc, copy fixes #168's fix reproduces the original bug precisely: the dump contains bothQuit ccmux?and the Projects screen, i.e.qopened the quit modal and2switched tabs mid-edit.TestTUIFlow_AgentsModelPickerSwallowsGlobalKeys— Tab and2while the Claude model picker is open. Reverted →2leaks to the Projects screen.TestTUIFlow_ProjectsCommittedFilterEscClears— Esc clears a committed no-match filter. Reverted → the project list never comes back.TestTUIFlow_SpinnerScreensStayResponsive— Conversations and Notes keep answering input (asserts responsiveness, not animation frames, so it can't flake on timing).New coverage:
TestTUIFlow_UsageOverlayOpenCloseSwallowsKeys—uoverlay opens, swallowsp(no preview toggle underneath), Esc restores the detail pane.TestTUIFlow_SessionPreviewToggle— asserts the preview shows a live capture by echoing a unique marker into the real tmux pane and finding it, then thatprestores the metadata view.TestTUIFlow_NotesFolderExpandCollapse— Right/Left on adocs/folder row, checked via both the child note and the▸/▾glyph.TestTUIFlow_TerminalResize— 120x40 → 60x20 → back, via a newResizehelper (real SIGWINCH). Narrow tab bar renders, wide layout returns, no panic, process still responsive.TestTUIFlow_TourCompletionPersists— the tour doesn't re-fire in a second launch sharing the same env (complements the existing in-session slide test).Also adds driver helpers —
Mark/WaitForSince/RefuteSincefor since-a-mark assertions against the cumulative PTY buffer, which is what makes "this key was swallowed" testable at all, plusResizeandAlive.Verification
All 9 pass, stable under
-count=2;make test-e2egreen (e2e 48s vs 37s baseline, well inside the 180s package timeout);go test ./...green.Harness note worth knowing: Bubble Tea coalesces bytes arriving in one PTY read, so
/followed within ~20ms byzparses as a single multi-rune key (matching no binding), and Esc immediately followed by a key parses as an alt-chord. That's input-stack behavior rather than a ccmux bug — a human can't type that fast and paste is legitimately one event — but it's a hard constraint for PTY tests: always wait for the mode change to paint before the next keystroke. These tests follow that discipline explicitly.🤖 Generated with Claude Code