File
Blob: test/MANUAL_TEST_CHECKLIST.md
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 helloand press Enter — output appears correctly - Check browser console — no errors during initial connection
- Banner lists bundled tools such as
claude,codex,vim, andemacs
Control codes
- Run
cat(orsleep 999) and press Ctrl+C — process is interrupted - Run
catand 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
$FOOis empty and cwd is/workspacein 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
vimoremacs— alternate screen renders correctly - Resize the window while in the editor — no rendering glitches
- Exit the editor — normal scrollback is restored
- Run
toporhtop— 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_AUDandCF_ACCESS_TEAMsecrets - 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