Skip to content
File

Blob: test/MANUAL_TEST_CHECKLIST.md

Markdown171 lines

Manual Test Checklist

Run through these scenarios after deploying or during local development.

Connection

  • Open the app — terminal connects, shows the startup tooling banner, and reaches a shell prompt
  • Connection state indicator shows green "Connected"
  • Type echo hello and press Enter — output appears correctly
  • Check browser console — no errors during initial connection
  • Banner lists bundled tools such as claude, codex, vim, and emacs

Control codes

  • Run cat (or sleep 999) and press Ctrl+C — process is interrupted
  • Run cat and press Ctrl+D — sends EOF, cat exits
  • Press Ctrl+Z in a foreground process — process is suspended
  • Press Ctrl+A, Ctrl+E in a shell — cursor moves to start/end of line
  • Press Ctrl+L — clears the terminal screen
  • Select text in terminal, then Ctrl+C — copies to clipboard (does NOT send SIGINT)

Multiple terminal tabs

  • Click "+" to create a second tab — new tab appears in tab strip, new session ID
  • Click "+" again for a third tab — "Terminal 3" title, unique session ID
  • In tab 1: export FOO=tab1 && cd /tmp
  • Switch to tab 2: echo $FOO && pwd — FOO is empty, cwd is /workspace
  • Switch back to tab 1: echo $FOO && pwd — FOO=tab1, cwd=/tmp (session preserved)
  • Each tab shows its own connection state dot in the tab strip
  • Active tab is visually highlighted

Tab persistence on refresh

  • Create 2 tabs, note their session IDs from the session bar
  • Run a command in each tab (e.g., export MARKER=tabN)
  • Refresh the browser (F5 / Ctrl+R)
  • Both tabs are restored in the tab strip with the same session IDs
  • Switch between tabs — each resumes its PTY (shell state preserved)
  • Message shows "[Resumed existing PTY session]"

Close tab

  • Create 3 tabs
  • Close the middle tab via the X button
  • Tab is removed from the strip — neighbor tab becomes active
  • The closed tab's backend session is NOT destroyed (could reconnect via API)
  • Close all tabs — a fresh default tab is created automatically
  • Close button tooltip says "Detach tab (session stays alive)"

Reconnect — browser refresh

  • Note the session ID from the session bar
  • Refresh the browser
  • The terminal reconnects to the same session (PTY buffer replayed)
  • Previous shell state (working directory, variables) is preserved
  • No duplicate output lines from the replay
  • Message shows "[Resumed existing PTY session]"
  • Indicator transitions: Connecting -> Connected

Reconnect — brief network interruption

  • Simulate network drop (DevTools -> Network -> Offline, wait 3s, re-enable)
  • Indicator transitions: Reconnecting -> Connected
  • Terminal resumes without creating a new shell
  • No duplicate or garbled output after reconnect
  • Message shows "[Resumed existing PTY session]"

Reconnect — explicit button

  • Click the "Reconnect" button in the session bar
  • Terminal briefly clears and re-renders with server-replayed output
  • Same session ID is shown

Container restart detection

  • Leave the terminal idle longer than sleepAfter (default 10m)
  • Interact with the terminal after idle
  • If container restarted: yellow warning "[Container restarted — previous state is gone unless persisted]"
  • Shell comes back in a clean state (fresh /workspace)

New Session

  • Click "New Session"
  • A new session ID appears in the session bar
  • Terminal shows a fresh shell prompt (new cwd, no history)
  • Previous session is not destroyed (could reconnect to it via code)

Shared attach warning

  • Open the app in two browser windows (not tabs within the app)
  • In window 2, ensure the same session ID is active (e.g., duplicate the browser tab)
  • Verify orange "Shared session" banner appears in both windows
  • Type in one window — output appears in both
  • Close one browser window — banner disappears in the remaining window
  • Click "New Session" in one window — banner disappears (different sessions now)

Resize

  • Resize browser window — terminal reflows correctly
  • Drag DevTools panel to resize — terminal adjusts
  • Run tput cols && tput lines — values match the visible terminal
  • Rapidly resize — no error storms in console (debounced)

Paste

  • Copy a multiline string and paste into the terminal
  • Characters appear correctly (no double-paste, no encoding issues)
  • Ctrl+V and right-click paste both work

Session isolation

  • Open two "New Session" tabs
  • In session A: export FOO=bar && cd /tmp
  • In session B: echo $FOO && pwd
  • Verify $FOO is empty and cwd is /workspace in session B

Sandbox idle / restart

  • Leave the terminal idle longer than sleepAfter (default 10m)
  • Interact with the terminal after idle
  • Verify a clear message indicates state was lost (container restarted)
  • Shell comes back in a clean state

Persistence (backup / restore)

  • Write a file in /workspace: echo "test" > /workspace/myfile.txt
  • Call backup API: curl -X POST /api/workspace/backup?workspace=default
  • Note the returned backup id
  • Let sandbox idle out or destroy it: curl -X DELETE /api/sandbox?workspace=default
  • Restore: curl -X POST /api/workspace/restore?workspace=default -d '{"id":"<backup-id>"}'
  • Verify the file survives: cat /workspace/myfile.txt

Full-screen interactive tools

  • Run vim or emacs — alternate screen renders correctly
  • Resize the window while in the editor — no rendering glitches
  • Exit the editor — normal scrollback is restored
  • Run top or htop — live-updating TUI renders properly
  • Run Claude Code (if installed) — interactive UI works
  • Run Codex CLI (if installed) — interactive UI works
  • Arrow keys, Ctrl+C, Ctrl+D behave correctly in all tools

Auth — dev mode (no Access configured)

  • Open the app without any credentials — terminal connects (dev mode)
  • Workspace label shows "default"
  • Sandbox ID is derived from "dev-user" identity

Auth — Cloudflare Access (CF_ACCESS_AUD + CF_ACCESS_TEAM set)

  • Configure Cloudflare Access on the app hostname
  • Set CF_ACCESS_AUD and CF_ACCESS_TEAM secrets
  • Access the app through the Access-protected hostname — login flow works
  • Terminal connects after Access authentication
  • Sandbox is scoped to the authenticated user (check derived sandbox ID)
  • A different user gets a different sandbox (isolated workspaces)

Authorization

  • Two different authenticated users cannot access each other's sandboxes
  • The ?workspace= param creates separate sandboxes for the same user
  • The ?id= param is ignored (sandbox derived from user identity)

Error states

  • Connect to a non-existent workspace — meaningful error or fresh sandbox created
  • Kill the container process — exit status displayed in terminal
  • Server sends an error frame — state indicator shows "Error"
  • Invalid JSON body to session creation — 400 error returned
  • cwd outside /workspace — 400 error returned