Skip to content

test(e2e): cover the terminal WS contract with a real shell connect - #220

Open
thinkbig1979 wants to merge 2 commits into
mainfrom
test/terminal-e2e
Open

test(e2e): cover the terminal WS contract with a real shell connect#220
thinkbig1979 wants to merge 2 commits into
mainfrom
test/terminal-e2e

Conversation

@thinkbig1979

Copy link
Copy Markdown
Owner

Closes the coverage gap that let the terminal sit broken in production for three weeks (#219): the frontend dials /ws/terminal/:id/:container with the container ID, the membership check matched names — each side's unit tests passed against its own assumption, and nothing ever crossed the contract with a real connect.

What the spec does

terminal-flow.spec.ts, running in the existing backup-flow CI job (auto-discovered — bare npx playwright test with --grep-invert auth-session, no workflow change):

  • Arrange: starts the seeded test-app stack via the lifecycle API and polls until running (generous timeout for the first-run nginx image pull).
  • TERM-PW-001: Overview row → Shell: test-app-web-1 → asserts the ?container=<hex id> deep link and the connected state ("Disconnect terminal" renders only while connected) and the BusyBox / # prompt in xterm's DOM rows.
  • TERM-PW-002: types echo capstan-e2e-$((21+21)) and asserts capstan-e2e-42 appears — computed output proves a live duplex PTY, not keystroke echo.
  • TERM-PW-003: the Terminal tab's dropdown (keyed on container.id — the exact path that was denied for three weeks) connects from a fresh navigation.

One shared page across the serial block keeps the suite under the backend's 10-per-user WS connection cap (AUTH_DISABLED makes every socket "anonymous", and dead sockets linger for the 60s read deadline).

Verification

Recon done with agent-browser against a CI-identical local environment (vite :3001 proxying to backend :5001, AUTH_DISABLED=true, seeded stopped test-app); all selectors in the spec are recon-verified. Suite run twice back-to-back locally: 3/3 passed both times (11.5s cold with stack start, 5.2s warm), confirming idempotence against an already-running stack.

🤖 Generated with Claude Code

thinkbig1979 and others added 2 commits August 21, 2026 22:15
The terminal was silently broken in production for three weeks (frontend
dials the WS route with the container ID, the membership check matched
names only — fixed in #219) because both sides' unit tests passed against
their own assumption and nothing ever crossed the contract with a real
connect.

terminal-flow.spec.ts is that connect: it starts the seeded test-app
stack, opens a shell via both entry points (the Overview row's Shell
action and the Terminal tab's container-ID-keyed dropdown), and proves
the session is a live PTY by running a command and reading its computed
output back out of xterm's DOM rows. One shared page across the serial
block keeps the suite under the backend's 10-per-user WS cap.

Picked up automatically by the backup-flow CI job (bare playwright
invocation, grep-invert auth-session); no workflow change needed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
TERM-PW-003 flaked on its first CI run and intermittently locally
(3 of 6 runs): a full-page goto() raced the stack query's one-shot fetch
for the toolbar, and after switching to SPA tab navigation, a tab click
could land in the same tick as a React re-render of the freshly-mounted
Overview (metrics stream + stack refetch) and dispatch into a swapped
node, leaving the route unchanged.

Navigate via the tabs instead of goto(), and wrap each tab click in an
expect().toPass() that re-clicks until the route actually changes.
6/6 consecutive local runs clean with zero Playwright retries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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