From 7a271b89662a45adccb99444c3094cba0d1e6725 Mon Sep 17 00:00:00 2001 From: David Hagerty Date: Wed, 11 Feb 2026 15:01:19 -0500 Subject: [PATCH] docs: add human test plan for V2 Phase 4 web UI Co-Authored-By: Claude Opus 4.6 --- docs/test-plans/2026-02-10-v2-phase4.md | 186 ++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 docs/test-plans/2026-02-10-v2-phase4.md diff --git a/docs/test-plans/2026-02-10-v2-phase4.md b/docs/test-plans/2026-02-10-v2-phase4.md new file mode 100644 index 0000000..8e12833 --- /dev/null +++ b/docs/test-plans/2026-02-10-v2-phase4.md @@ -0,0 +1,186 @@ +# Human Test Plan: V2 Phase 4 Web UI + +## Prerequisites + +- Rust toolchain 1.85.0+ installed +- Bun runtime installed +- Working directory: `/Users/david.hagerty/code/personal/rustagent/new-directions` +- Branch: `new-directions` +- Install dependencies: `cd web && bun install` +- Verify automated tests pass: `cd web && bun run test` +- Verify TypeScript compiles: `cd web && npx tsc --noEmit` +- Build the web UI: `cd web && bun run build` + +## Phase 1: Project Scaffolding (P4a) + +| Step | Action | Expected | +|------|--------|----------| +| 1.1 | Run `ls web/` in the project root | Directory contains: `package.json`, `vite.config.ts`, `svelte.config.js`, `tsconfig.json`, `index.html`, `src/`, `bun.lock` | +| 1.2 | Run `ls web/src/` | Contains `main.ts` and `App.svelte` | +| 1.3 | Run `cd web && bun install` | Exit code 0, `node_modules/` directory created | +| 1.4 | Run `cd web && bun run dev` | Vite outputs "Local: http://localhost:5173/" (or similar port). Ctrl+C to stop. | +| 1.5 | Start dev server (`cd web && bun run dev`), then open `http://localhost:5173` in a browser | Browser renders page with "Rustagent" content -- a sidebar on the left and a main content area | +| 1.6 | With daemon running on port 7400 and dev server running, execute `curl http://localhost:5173/api/health` | Returns `{"status":"ok"}` (proxied through Vite to daemon) | +| 1.7 | With daemon and dev server both running, open browser console on `http://localhost:5173` and check Network tab for WebSocket connection to `/ws` | WebSocket connection established (or attempting reconnection if daemon WS endpoint is not yet active) | + +## Phase 2: API Client and WebSocket (P4b) + +| Step | Action | Expected | +|------|--------|----------| +| 2.1 | With daemon running and UI open in browser, kill the daemon process | Browser console shows "WebSocket closed" or similar. WsConnection begins reconnection attempts. Observe console messages at ~1s, ~2s, ~4s, ~8s intervals. | +| 2.2 | Restart the daemon while UI is still open | WsConnection reconnects automatically. The `connected` state becomes true. Console shows successful reconnection. | + +## Phase 3: Stores, App Shell, and Routing (P4c) + +| Step | Action | Expected | +|------|--------|----------| +| 3.1 | Open `http://localhost:5173` in a browser | Page renders with a sidebar on the left (~240px wide) and a main content area to the right | +| 3.2 | Click "Dashboard" link in the sidebar | URL changes to `http://localhost:5173/#/`, main area shows Dashboard view | +| 3.3 | Click "Projects" link in the sidebar | URL changes to `http://localhost:5173/#/projects`, main area shows ProjectList view | +| 3.4 | Click "Search" link in the sidebar | URL changes to `http://localhost:5173/#/search`, main area shows GraphSearch view | +| 3.5 | Navigate to Projects, then Dashboard, then Search. Press browser Back button. | Returns to Dashboard view. URL hash is `#/`. | +| 3.6 | Press browser Forward button | Returns to Search view. URL hash is `#/search`. | +| 3.7 | With daemon running and UI open on Dashboard, create a node via `curl -X POST http://localhost:7400/api/projects` (with valid JSON body) | UI updates without page refresh to show the new project (WebSocket event triggers store update) | + +## Phase 4: Dashboard and Project Views (P4d) + +| Step | Action | Expected | +|------|--------|----------| +| 4.1 | Create test data: register a project via API (`POST /api/projects`), create a goal (`POST /api/projects//goals`), create child tasks. Navigate to `http://localhost:5173/#/` | Dashboard shows project cards. Each card displays the project name and goal count. | +| 4.2 | Inspect the Dashboard active goals section | Goals listed with colored status badges (e.g., green for active, blue for in_progress) | +| 4.3 | Run an agent against a goal (via CLI: `cargo run -- run "" --profile coder`), then check Dashboard | Dashboard shows running agents count and current task information | +| 4.4 | Navigate to `http://localhost:5173/#/projects` | Table displays projects with columns: Name, Path (monospace font), Registered Date (formatted) | +| 4.5 | Click a project row in the ProjectList table | URL changes to `/#/projects/`, ProjectDetail view renders | +| 4.6 | On ProjectDetail page, inspect the goals section | Goals displayed with: title, status badge (colored by status), priority badge, completion percentage ("X/Y tasks completed") | +| 4.7 | On a goal card, click the "Tasks" link | URL changes to `/#/goals//tasks` | +| 4.8 | Navigate back to ProjectDetail, click "Decisions" link on a goal | URL changes to `/#/goals//decisions` | +| 4.9 | Click "Agents" link | URL changes to `/#/goals//agents` | +| 4.10 | Click "Sessions" link | URL changes to `/#/goals//sessions` | + +## Phase 5: Task Tree View (P4e) + +| Step | Action | Expected | +|------|--------|----------| +| 5.1 | Navigate to `/#/goals//tasks` for a goal with tasks and subtasks | Hierarchical tree renders: goal at root, tasks as children, subtasks nested under parent tasks | +| 5.2 | Inspect a tree node row | Shows: title text, status badge (colored), priority badge, agent chip (if assigned) | +| 5.3 | Click the expand/collapse toggle on a node that has children | Children hide when collapsed, reappear when expanded | +| 5.4 | Create a `dependson` edge between two tasks via API | The dependent task shows a "depends on: ra-xxxx.N" indicator in the tree | +| 5.5 | Set a task status to "ready" | The task row has a visually distinct background or border color (differs from pending/in_progress) | +| 5.6 | Inspect the bottom panel for "Ready Tasks" | Lists tasks from `/tasks/ready` endpoint | +| 5.7 | Inspect the "Next recommended" section in the ready tasks panel | One task is highlighted as the recommended next task (from `/tasks/next`) | +| 5.8 | Click a tree node | A detail panel appears on the right showing: full description, acceptance criteria, dependencies list, and edge connections | + +## Phase 6: Decision Graph View (P4f) + +| Step | Action | Expected | +|------|--------|----------| +| 6.1 | Navigate to `/#/goals//decisions` for a goal with decision nodes | Cytoscape canvas renders with nodes arranged in top-to-bottom DAG layout (dagre) | +| 6.2 | Navigate away from the decision graph view, then back | No JavaScript errors in console. Cytoscape initializes and destroys cleanly. | +| 6.3 | Click and drag the background of the graph | Canvas pans | +| 6.4 | Scroll wheel on the graph | Canvas zooms in/out | +| 6.5 | Click and drag a node | Node moves to new position | +| 6.6 | Inspect decision nodes | Rendered as diamond shapes with gold (#FFD700) background | +| 6.7 | Inspect option nodes | Rendered as hexagon shapes. Chosen options are green (#32CD32), rejected options are gray (#666) with dashed border | +| 6.8 | Inspect outcome nodes | Rendered as ellipses | +| 6.9 | Inspect revisit nodes (if present) | Rendered as triangles with orange background | +| 6.10 | Inspect edges | Labels show relationship types: "chosen", "rejected", "leadsto", etc. | +| 6.11 | Click "Now" toggle button | Graph shows only active/decided decisions and chosen options. Rejected/abandoned nodes disappear. | +| 6.12 | Click "History" toggle button | Graph shows all nodes including rejected, abandoned, and superseded | +| 6.13 | Click a decision node | Detail panel appears on the right showing GraphNodeCard with node information | +| 6.14 | Click an option node that has `pros`/`cons` in its metadata | Detail panel shows pros and cons rendered as styled lists | +| 6.15 | Click "Fit to view" button | Graph centers and zooms to show all visible nodes | + +## Phase 7: Agent Monitor, Session History, and Graph Search (P4g) + +| Step | Action | Expected | +|------|--------|----------| +| 7.1 | Run an agent (via CLI), then navigate to `/#/goals//agents` | Event feed shows real-time events as they arrive via WebSocket: agent_spawned, agent_progress, tool_execution | +| 7.2 | During agent execution, inspect status badges | Badges change color through lifecycle: blue/gray for spawning, green for working, etc. | +| 7.3 | Inspect a tool_execution event in the feed | Shows tool name, truncated args, and result summary | +| 7.4 | Generate more than 200 events (or simulate) | Feed caps at 200 items (oldest removed). Feed auto-scrolls to show newest events at the bottom. | +| 7.5 | Create multiple sessions for a goal, then navigate to `/#/goals//sessions` | Sessions listed in reverse chronological order (newest first) | +| 7.6 | Inspect a session card | Shows: start timestamp, end timestamp, duration, agent IDs as chips, and summary text | +| 7.7 | Create a session with handoff notes containing `## Done` and `## Remaining` markdown sections | Handoff notes render with formatted headers and text | +| 7.8 | Navigate to `/#/search`, type a query (e.g., the name of a task), click Search button | Matching nodes appear as result cards | +| 7.9 | After getting search results, click type filter buttons ("Goals", "Tasks", "Decisions") | Results update to show only the selected type | +| 7.10 | Inspect a result card | Shows: title, type badge (e.g., "task"), status badge, and description snippet (~150 chars) | +| 7.11 | Click a goal result in the search results | Navigates to `/#/goals//tasks` | +| 7.12 | Click a decision result in the search results | Navigates to `/#/goals//decisions` | + +## Phase 8: Build Integration and Production Serving (P4h) + +| Step | Action | Expected | +|------|--------|----------| +| 8.1 | Run `cargo build --features bundle-ui` | Exit code 0. Build log includes web build output (Vite compilation). | +| 8.2 | Run `cargo build` (without `bundle-ui` feature) | Exit code 0. Build log does NOT include web build output. | +| 8.3 | Run `cd web && bun run build && ls web/dist/` | `web/dist/` contains `index.html` and `assets/` directory with `.js` and `.css` files | +| 8.4 | After building with `bundle-ui`, start daemon: `./target/debug/rustagent daemon`. Then run `curl http://localhost:7400/` | Returns HTML containing "Rustagent" | +| 8.5 | Open `http://localhost:7400/#/projects` in a browser | SPA route loads correctly, showing the ProjectList view | +| 8.6 | Run `curl -I http://localhost:7400/assets/.js` (using an actual filename from `web/dist/assets/`) | Response includes `Content-Type: application/javascript` | +| 8.7 | While the UI is being served, run `curl http://localhost:7400/api/health` | Returns `{"status":"ok"}` -- API endpoints work alongside embedded UI | +| 8.8 | Build without `bundle-ui`, start daemon, run `curl http://localhost:7400/` | Returns a helpful message containing instructions for "bun run dev" and "--features bundle-ui" | + +## End-to-End: Full-Stack WebSocket Integration + +**Purpose:** Validates the architecture-level requirement that creating a goal via API updates the UI in real-time via WebSocket. + +| Step | Action | Expected | +|------|--------|----------| +| E2E.1 | Build with `bundle-ui`: `cargo build --features bundle-ui` | Build succeeds | +| E2E.2 | Start daemon: `./target/debug/rustagent daemon` | Daemon starts on port 7400 | +| E2E.3 | Open `http://localhost:7400` in browser | Dashboard loads | +| E2E.4 | Register a project: `curl -X POST http://localhost:7400/api/projects -H 'Content-Type: application/json' -d '{"name":"test-project","path":"/tmp/test"}'` | Returns JSON with project ID. Note the `id` field. | +| E2E.5 | Observe Dashboard in browser | Project appears on Dashboard without page refresh | +| E2E.6 | Create a goal: `curl -X POST http://localhost:7400/api/projects//goals -H 'Content-Type: application/json' -d '{"title":"Test Goal","description":"E2E test","priority":"high"}'` | Returns JSON with goal ID | +| E2E.7 | Observe Dashboard in browser | Goal appears under the project without page refresh | +| E2E.8 | Navigate to `/#/goals//tasks` | Task tree shows the goal node | +| E2E.9 | Create a child task: `curl -X POST http://localhost:7400/api/nodes//children -H 'Content-Type: application/json' -d '{"node_type":"task","title":"Child Task","description":"Created via API"}'` | Returns JSON with task node | +| E2E.10 | Observe Task Tree in browser | Child task appears in the tree without page refresh | + +## Traceability Matrix + +| Acceptance Criterion | Automated Test | Manual Step | +|----------------------|----------------|-------------| +| P4a.AC1.1 | -- | 1.1 | +| P4a.AC1.2 | -- | 1.2 | +| P4a.AC1.3 | -- | 1.3 | +| P4a.AC2.1 | -- | 1.4 | +| P4a.AC2.2 | -- | 1.5 | +| P4a.AC3.1 | -- | 1.6 | +| P4a.AC3.2 | -- | 1.7 | +| P4b.AC1.1 | `tsc --noEmit` (types.ts) | -- | +| P4b.AC1.2 | `tsc --noEmit` + websocket.test.ts | -- | +| P4b.AC1.3 | `tsc --noEmit` (types.ts enums) | -- | +| P4b.AC2.1 | `tsc --noEmit` (client.ts) | -- | +| P4b.AC2.2 | `tsc --noEmit` (client.ts ApiError) | -- | +| P4b.AC2.3 | `tsc --noEmit` (client.ts constructor) | -- | +| P4b.AC3.1 | `tsc --noEmit` + websocket.test.ts | -- | +| P4b.AC3.2 | websocket.test.ts (backoff tests) | 2.1, 2.2 | +| P4b.AC3.3 | `tsc --noEmit` + websocket.test.ts | -- | +| P4c.AC1.1 | `tsc --noEmit` (projects.svelte.ts) | -- | +| P4c.AC1.2 | `tsc --noEmit` (graph.svelte.ts) | -- | +| P4c.AC1.3 | `tsc --noEmit` (agents.svelte.ts) | -- | +| P4c.AC1.4 | `tsc --noEmit` (search.svelte.ts) | -- | +| P4c.AC1.5 | -- | 3.7 | +| P4c.AC2.1 | -- | 3.1 | +| P4c.AC2.2 | router.test.ts (10 cases) | -- | +| P4c.AC2.3 | -- | 3.2, 3.3, 3.4 | +| P4c.AC2.4 | -- | 3.5, 3.6 | +| P4d.AC1.1-3 | -- | 4.1-4.3 | +| P4d.AC2.1-2 | -- | 4.4-4.5 | +| P4d.AC3.1-3 | -- | 4.6-4.10 | +| P4e.AC1.1-3 | tree.test.ts (6 cases) | 5.1-5.3 | +| P4e.AC2.1-3 | tree.test.ts (countTaskStats) | 5.4-5.5 | +| P4e.AC3.1-3 | -- | 5.6-5.8 | +| P4f.AC1.1-3 | -- | 6.1-6.5 | +| P4f.AC2.1-4 | decision-graph.test.ts (9 cases) | 6.6-6.10 | +| P4f.AC3.1-3 | decision-graph.test.ts (4 cases) | 6.11-6.12 | +| P4f.AC4.1-3 | -- | 6.13-6.15 | +| P4g.AC1.1-4 | -- | 7.1-7.4 | +| P4g.AC2.1-3 | -- | 7.5-7.7 | +| P4g.AC3.1-4 | -- | 7.8-7.12 | +| P4h.AC1.1-3 | -- | 8.1-8.3 | +| P4h.AC2.1-4 | -- | 8.4-8.7 | +| P4h.AC3.1 | -- | 8.8 | + +All 68 acceptance criteria accounted for: 21 by automated tests/build checks, 47 by manual steps. -- 2.51.2