Restore terminal-live E2E lane and fix its two flake sources - #858
Merged
Conversation
The 12 terminal-live tests have been dead code since the isolated E2E harness landed: e2e-isolated.sh hard-coded DISPATCH_AGENT_RUNTIME=inert, so the IS_LIVE gate could never be true through any pnpm run. Add an opt-in live lane and make the tests deterministic: - e2e-isolated.sh maps a dedicated E2E_AGENT_RUNTIME var (default inert) onto DISPATCH_AGENT_RUNTIME. Deliberately not a pass-through of the inherited var: the Dispatch server exports DISPATCH_AGENT_RUNTIME=tmux into every agent shell it launches, and honoring it silently flipped full-suite runs started from agent sessions into live mode. - Live sessions are namespaced under a unique per-run DISPATCH_SESSION_PREFIX and killed on teardown, so they can never collide with a production Dispatch server on the same machine, and the e2e server's orphan reconciler can never match production sessions. - New `pnpm run test:e2e:live` runs the terminal-live spec against real tmux sessions (--no-deps skips the parallel-project dependency). - Copy-mode test: tmux 3.5+ holds a bare ESC ~500ms to disambiguate it from an escape sequence (a floor - escape-time below 500 is ignored), pushing the old ESC -> banner-hidden path to ~930-1100ms against a 1s assertion. Wait for the tmux-side exit first; the 1s banner budget now measures only the poll + SSE + exit-animation pipeline. - Focus tests: the app focuses the terminal on socket open with a triple tap (immediate, next rAF, setTimeout(0) after that frame). Tests that move focus to another element right after attach raced the late taps. New waitForTerminalFocusSettled helper waits the taps out with a strictly longer rAF chain; applied to the 4 affected tests. Verified: live lane 33/33 with --repeat-each=3 plus three full passes; inert suite unchanged (175 passed / 12 skipped) even from a shell with DISPATCH_AGENT_RUNTIME=tmux inherited; no leaked tmux sessions. 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.
Summary
The 12 terminal-live E2E tests (
e2e/terminal-live.spec.ts) have been permanently skipped since the isolated harness landed —scripts/e2e-isolated.shhard-codedDISPATCH_AGENT_RUNTIME=inerton the playwright invocation, so theIS_LIVEgate could never be true through anypnpm run. This PR makes them runnable again via an opt-in lane and fixes the two real flake sources they were hiding.Live lane (opt-in)
pnpm run test:e2e:liveruns the terminal-live spec against real tmux sessions inside the usual isolated env (own DB, own port).E2E_AGENT_RUNTIMEvar (defaultinert) ontoDISPATCH_AGENT_RUNTIME. It is deliberately not a pass-through: the Dispatch server exportsDISPATCH_AGENT_RUNTIME=tmuxinto every agent shell it launches, and honoring the inherited value silently flipped full-suite runs started from inside agent sessions into live mode (empirically: 22 failures, 9.6m runtime).DISPATCH_SESSION_PREFIXand are killed on teardown — no collision with (and no reconciler visibility into) a production Dispatch server on the same machine. Verified zero leaked sessions across all runs, including an interrupted full-suite live run.Flake fixes (both reproduced, then verified deterministic)
500ms to disambiguate it from an escape sequence (a hard floor —600ms, 10→escape-timebelow 500 is ignored; measured 0→540ms, 1000→1025ms). ESC-exit + 250ms observer poll + SSE + 180ms exit animation lands at ~930–1100ms against the old 1s banner assertion. Fixed by asserting the tmux-side exit first (existing 5s helper), so the 1s banner budget measures only the product's poll + SSE + animation pipeline — same ordering the click-path half of the test already used.setTimeout(0)after that frame —focusTerminalSurface). Tests that focus another element right after attach raced the late taps, which undid their focus change. NewwaitForTerminalFocusSettledhelper waits for the first tap, then waits the rest out with a strictly-longer rAF → rAF → setTimeout chain (deterministic by registration order); applied to the 4 affected tests.Validation
--repeat-each=3, plus three separate full passes (11/11 each)DISPATCH_AGENT_RUNTIME=tmuxinheritedpnpm run check, unit suites (server 2366 / web 516 / ext 60 / scripts 4) all green🤖 Generated with Claude Code