Skip to content

test(e2e): PTY-driven TUI regressions and screen-interaction coverage - #179

Merged
skzv merged 2 commits into
mainfrom
claude/e2e-tui-flows
Aug 4, 2026
Merged

test(e2e): PTY-driven TUI regressions and screen-interaction coverage#179
skzv merged 2 commits into
mainfrom
claude/e2e-tui-flows

Conversation

@skzv

@skzv skzv commented Aug 4, 2026

Copy link
Copy Markdown
Owner

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 ~/repos2q into 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 both Quit ccmux? and the Projects screen, i.e. q opened the quit modal and 2 switched tabs mid-edit.
  • TestTUIFlow_AgentsModelPickerSwallowsGlobalKeys — Tab and 2 while the Claude model picker is open. Reverted → 2 leaks 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_UsageOverlayOpenCloseSwallowsKeysu overlay opens, swallows p (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 that p restores the metadata view.
  • TestTUIFlow_NotesFolderExpandCollapse — Right/Left on a docs/ folder row, checked via both the child note and the / glyph.
  • TestTUIFlow_TerminalResize — 120x40 → 60x20 → back, via a new Resize helper (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/RefuteSince for since-a-mark assertions against the cumulative PTY buffer, which is what makes "this key was swallowed" testable at all, plus Resize and Alive.

Verification

All 9 pass, stable under -count=2; make test-e2e green (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 by z parses 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

skzv and others added 2 commits August 4, 2026 11:52
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>
@skzv
skzv merged commit a0ee1ff into main Aug 4, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant