Skip to content

Latest commit

 

History

History
206 lines (156 loc) · 6.4 KB

File metadata and controls

206 lines (156 loc) · 6.4 KB

Golden Path E2E: Add Server → Create Project → Create Session → Create Terminal → Terminal I/O

Field Value
Priority P0 (Smoke)
Source 00-strategy.md, architecture/domain-model.md
Time budget < 10 minutes from app launch to verified terminal output
Status Active

Prerequisites

Server environment

Requirement Details
OS Linux (Ubuntu 24.04 LTS recommended) or macOS with Docker
Docker Engine 24.0+, daemon running
Ports 50051 (gRPC), 8080 (REST/SSE) free
Network Client machine can reach server on both ports
Git repo A small public repository for cloning

Client environment

Requirement Details
OS macOS 26+ (Apple Silicon)
App Relay.app built and installed

Server setup

# 1. Build the runner (or use a pre-built binary)
cd runner && cargo build --release

# 2. Initialize cloud mode
./target/release/relay-runner init --cloud
# Save the bearer token printed to stdout

# 3. Start the server
RUST_LOG=info ./target/release/relay-runner
# Confirm gRPC :50051 and REST :8080 in logs

Scenario

Step 1 — Add Server

Action Open Relay.app. Sidebar → "+" (Add Server). Select Cloud REST. Fill: REST API URL = http://<host>:8080, Token = bearer token. Click Add.
Expected Server appears in sidebar.
Fail Form missing fields, Add unavailable, server not in list.

Step 2 — Connect

Action Click server → Connect.
Expected Green indicator. Projects list displayed (empty on fresh server).
Fail Connect fails, error loading projects.

Step 3 — Create Project

Action Click "+" (Create Project). Fill: Name = e2e-test, Git URL = https://github.com/nicklockwood/SwiftFormat.git. Click Create.
Expected Sheet dismisses. Project appears with badge cloning.
Fail Validation error, project not appearing.

Step 4 — Wait for clone (SSE)

Action Watch project list. No manual refresh.
Expected Badge changes cloningready via SSE project_state_changed. < 60s for small repo.
Fail Stays cloning > 2 min, goes to failed, manual refresh needed.

Step 5 — Open project sessions

Action Click e2e-test project (state = ready).
Expected Session Management view. Sessions list empty. Project name in header.
Fail Nothing happens, navigation broken.

Step 6 — Create Session

Action Click "+" (Create Session). Select a profile. Click Create.
Expected Sheet dismisses. Session appears with badge starting.
Fail Validation error, session not appearing.

Step 7 — Wait for session start (SSE)

Action Watch session list. No manual refresh.
Expected Badge startingrunning via SSE session_state_changed. < 30s.
Fail Stays starting > 2 min, goes to failed.

Step 8 — Open Terminal

Action Click "Open Terminal" on running session.
Expected New terminal tab opens. Shell prompt visible. Tab title includes project/session name.
Fail Button not enabled, tab doesn't open, blank terminal.

Step 9 — Verify terminal I/O

Action Type echo e2e-ok and press Enter.
Expected Terminal displays e2e-ok. No garbled characters, latency < 1s.
Fail No output, garbled output, freeze.
Bonus Try ls, pwd, whoami, clear.

Step 10 — Close terminal tab

Action Close tab (Cmd+W or close button).
Expected Tab closes. Session remains running in session list.
Fail Session state changes, app crash.

Step 11 — Stop session

Action Click Stop on running session.
Expected Badge → stopped via SSE. "Open Terminal" disabled.
Fail Session stays running, no SSE update.

Step 12 — Verify final state

Action Navigate back to project list, then server list.
Expected Project = ready. Server = Connected. Stopped session visible with stopped badge.
Fail Unexpected state changes.

SSE verification checklist

Step SSE event Observable effect
4 project_state_changed Badge: cloning → ready
7 session_state_changed Badge: starting → running
11 session_state_changed Badge: running → stopped

Pass / Fail criteria

Criteria Requirement
All 12 steps pass without errors MUST
SSE updates visible real-time (3 events) MUST
Total scenario time < 10 minutes MUST
No app crashes or hangs MUST
Terminal I/O latency < 1 second SHOULD
No manual refresh needed SHOULD

Verdict: PASS only if all MUST criteria are met.


Code path reference

ServerListView (sidebar)
  → ServerFormView (Add Server sheet)
    → ServerFormFeature (validates, saves ServerCredential)
  → ServerListFeature (connects, green badge)

Cloud server tapped:
  → CloudNavigationFeature
    → ProjectListView
      → CreateProjectSheet / CreateProjectFormFeature
      → ProjectClient (REST: POST /api/v1/projects)
      → SSE: project_state_changed → ProjectListFeature updates state
    → Project tapped (ready):
      → SessionManagementView / SessionManagementFeature
        → CreateSessionSheet / CreateSessionFormFeature
        → SessionClient (REST: POST /api/v1/projects/{id}/sessions)
        → SSE: session_state_changed → SessionListFeature updates state
      → "Open Terminal":
        → CloudNavigationFeature.Delegate.openCloudTerminal(server, session)
          → MainFeature → TerminalFeature with remoteServer
            → REST: POST /api/v1/sessions/{id}/terminals
            → RemoteTerminalSession (gRPC: AttachTerminal)
              → TabFeature adds terminal tab

Tab closed:
  → TerminalFeature detaches (gRPC DetachRequest) — session stays running

Stop session:
  → SessionClient (REST: POST /api/v1/sessions/{id}/stop)
  → SSE: session_state_changed → stopped