Skip to content

Testing plan: Control Plane UI 3.0

Derived from requirements.md and design.md, before tasks.md. Authored at test-planning, completed at verification.

This file is executable content. Credentials appear by reference only — none are needed here.

Test matrix

#TypeApplies?Scope / what it provesWhere it runs
T1Unityesview-side helpers: sidebarGroup, compactRail, theme resolve/persist, search filter, renderInline; the existing model/state/client suites stay green untouchedcd ui && bun run test
T2Integration (scenario)yesthe React suite on the demo transport (App.test.tsx, Standing.test.tsx, WorkItemDetail.test.tsx, Transcript.test.tsx, ConfigEditor.test.tsx): every action and state of R3 still reachable through the new surface; new cases for the theme toggle, the tools switch, the Full graph toggle and the panel togglescd ui && bun run test
T3Contract (OpenAPI)n/a — no route, request or response shape changes; ui/src/api/ is byte-identical
T4End-to-endn/a — no live service in this environment; the demo transport is the same client interface over the same record shapes
T5UI / visualyesthe built app, demo mode, headless Chromium at 1440×900 and 390×844, both themes: home, PR session, full graph, tool calls off, gate + question banners, Standing, Settings, panels collapsednode ui/scripts/screenshots.mjs (checked in under docs/specs/issue-327/evidence/)
T6Snapshotn/a — DOM snapshots would freeze the very markup this item rewrites; the visual pass (T5) and the role/label suite (T2) are the assertion
T7Performance / loadn/a — no data path changes; the bundle size is recorded in the build evidence for the reviewer
T8Security / abuse caseyesAC1: markup and **/backtick payloads in transcript text render as text and create no element; AC2: an unknown stored theme is dropped; AC3: grep for dangerouslySetInnerHTML / innerHTML / eval is emptybun run test; grep -rn "dangerouslySetInnerHTML|innerHTML|eval(" ui/src ui/index.html
T9Accessibilityyesrole="log" + name + focus on the trace; aria-current on rows, tabs and nodes; the tools switch toggles on Enter and Space; disclosures are <details>; prefers-reduced-motion guard present in the stylesheetbun run test; grep -n "prefers-reduced-motion" ui/src/styles/app.css
T10Migration / upgradeyesa stored the-loop:settings:v1 without theme loads with theme unset and follows the browser preference; every other key round-trips as beforebun run test (settings.test.ts)
T11Manual exploratoryn/a — no live workstation service here; the demo transport exercises every verb, and the owner's PR review is the human pass
T12Lint / typecheck / buildyesthe same three commands CI and the Pages publish runcd ui && bun run lint && bun run build (build runs tsc --noEmit first)
T13Markdown lintyesthe spec, decision and docs pass the repository linternpx --yes markdownlint-cli2@0.18.1 "**/*.md" from the repo root

Scenarios & requirement trace

RowRequirement(s)Scenario / case
T1R1.5sidebarGroup puts a parked/questioned/blocked item in needs-you, an active one in in-flight, an all-done one in shipped, the rest in idle
T1R1.6compactRail keeps first, last and ±2 around the current node, one gap between
T1R2.1, R2.5theme resolves to the browser preference when unset or invalid
T1R3.4the search filter matches ref, title, repo and node, case-insensitively
T1, T8Sec AC1renderInline returns strings inside <strong>/<code>; a payload with <img> creates no element
T2R3.2, R3.3, R3.5every existing App.test.tsx scenario, re-pointed where it selected Classical classes
T2R2.2clicking the theme control flips the dark class and persists the choice
T2R1.7, R4.4the tools switch hides tool groups; Enter and Space toggle it
T2R1.6Full graph shows every node; Collapse graph compacts again
T2R4.6collapsing the sidebar shows the open-sidebar control in the header
T5R1, R2, R4.1, R5the screenshot set in both themes
T9R4.2, R4.3existing WorkItemDetail.test.tsx and App.test.tsx role assertions
T10R2.5, Sec AC2settings migration and unknown theme value
T12, T13NFRlint, types, build, markdown

Verification environment

  • Repositories: this repo only.
  • Services / containers: none — demo mode, no network beyond the fonts request the screenshot script blocks so captures are deterministic.
  • Fixtures & data: ui/src/demo/fixture.ts, unchanged.
  • Credentials: none.
  • Bring-up: cd ui && bun install --frozen-lockfile && bun run build && bun run preview (or the script's own static server over dist/). Tear-down: stop the server.
  • If bring-up fails: record it under Verification results, leave T5 unticked, escalate.

Evidence plan

RowEvidencePath under evidence/
T1, T2, T8, T9, T10vitest summary (files, tests, duration)verification.md § Tests
T12lint output; tsc + vite build output with bundle sizesverification.md § Lint · § Build
T13markdownlint outputverification.md § Markdown
T5one PNG per screen per theme, indexed with the prototype still each matches*.png, table in verification.md § UI / visual
T8the grep outputverification.md § Security

Verification activities

  • [x] T1/T2/T8/T9/T10 — cd ui && bun run test
  • [x] T12 — cd ui && bun run lint && bun run build
  • [x] T13 — npx --yes markdownlint-cli2@0.18.1 "**/*.md"
  • [x] T8 — grep -rn "dangerouslySetInnerHTML\|innerHTML\|eval(" ui/src ui/index.html (expect no matches)
  • [x] T9 — grep -n "prefers-reduced-motion" ui/src/styles/app.css (expect a match)
  • [x] T5 — node ui/scripts/screenshots.mjs against the built bundle; copy the captures into evidence/

Verification results

Executed 2026-09-09 on claude/github-issue-327-8vubsj.

ActivityCommand / procedureOutcomeEvidence
T1/T2/T8/T9/T10cd ui && bun run testpass — 16 files, 212 tests (183 before; 29 new)evidence/verification.md § Tests
T12cd ui && bun run lint && bun run buildpass — oxlint clean; tsc --noEmit clean; bundle 20.6 kB CSS + 310 kB JS§ Lint, § Build
T13npx --yes markdownlint-cli2@0.18.1 "**/*.md"pass — 991 files, 0 errors§ Markdown
T8grep for HTML-injecting callspass — no matches; abuse cases 1–2 covered by tests, 3 by review§ Security
T9role/name assertions in the suite; reduced-motion greppass§ Accessibility
T5node ui/scripts/screenshots.mjs on bun run preview over dist/, demo mode, both themes, 1440×900 and 390×844pass — 28 stills (incl. a synthetic long-text pair), fonts and dimensions measured against the prototype§ UI / visual, evidence/*.png

Not executed: T3, T4, T6, T7, T11 — n/a as planned (no API/route/model change; no live service here; the owner's PR review is the human pass).

Review comments

Appended by the-loop's record-feedback hook when a human gate approves with comments (issue-109). Append-only and attributed.

Released under the MIT License.