Orchestrator Dashboard — Manual QA Checklist (v1)¶
Issue: https://github.com/rluisb/lazyai/issues/176
Scope: v1 cut shipped via PRs #180, #181, #183, #184, #185
Use: run this before merging any dashboard change that touches HTML, CSS, or dashboard.js. The Go test suite covers structure and contracts; this checklist covers what only a human eye can catch.
Browser smoke automation is intentionally out of scope for v1. This checklist is the substitute.
How to run¶
- Build and start the daemon locally:
- Open
http://127.0.0.1:<port>/dashboard/(port is announced in stdout, default:57372). - Walk each section below. Tick items in your PR description or paste a copy of this file.
If you cannot reproduce a step (no failing run, no run with steps, etc.), seed data via the orchestrator MCP tools or use existing fixtures from your local SQLite DB.
Load + theming¶
- Page loads without a console error.
- Both fonts (Fraunces serif + JetBrains Mono Nerd Font) render — headings are serif, run ids and timestamps are monospace.
- Status pill in topbar transitions from "Loading dashboard…" to "Dashboard data loaded." within ~1s.
- Open Tweaks (top-right cog) — toggling
themeflips the palette without flicker. - Toggling
densityresizes paddings/gaps;comfortableis visibly looser thancompact. - Toggling
navbetweentop tabsandsidebarshows/hides the corresponding chrome and the other one disappears entirely (no double nav). - Reload the page — Tweaks selections persist.
Navigation + hash routing¶
- Clicking each primary nav item activates only that section (others have
hidden). - Browser URL hash updates (
#/overview,#/runs,#/catalog,#/errors). - Direct visit to each hash route activates the matching section on first paint.
- Browser back/forward moves between sections without page reload.
- Unknown hash (e.g.
#/nope) falls back to Overview without a console error. - Run detail nav item is disabled before any run is opened, with hint text "Select a run first".
- After opening a run from Runs, the Run detail item enables and remembers the selection across other-section navigation.
- Planned block items (Live activity / Logs / Settings) are visually disabled, do nothing on click, and show their gating-plan rationale text.
Overview screen¶
- All four cards (Health, Active runs, Run states, Catalog) populate.
- Recent runs list renders compact rows.
- Recent errors list renders or shows "No recent errors." empty state.
- Live activity panel shows status "live · listening for events across all runs" within ~1s.
- When you trigger a run from another terminal/tool, new events animate into the activity feed.
- Clicking the activity pause toggle: status flips to "paused", feed border turns warning-yellow, no new events arrive. Clicking again resumes.
- Refreshing the page with the toggle paused remembers the paused state.
- A failed run produces a red bottom-right toast within ~1s.
- After a state-changing event (run started/completed/failed), Overview cards and Runs list refresh within ~1s.
Runs screen¶
- Attention chips: clicking
running,failed,gated,recent,has errorsfilters the list and updates the count summary. -
budgetchip filters client-side usingbudgetHealthand shows the "client-side" note in the summary. - Search box filters by id substring and definition name (case-insensitive), debounced.
- Kind dropdown narrows results.
- If
nextCursoris present, a Load more → button appears and appends the next page. - Empty filter combos render the empty state without breaking the chip bar.
- Clicking a run row opens Run detail and updates the URL to
#/runs/{kind}/{id}.
Run detail screen¶
- Hero header shows kind/id, definition + version, started + updated timestamps, state chip.
- Copy-id button copies
kind/idto clipboard (verify by pasting elsewhere) and surfaces an "ok" status pill. - Budget cards (tokens / cost / wall clock / retries) show progress bars; warning/critical states colour the border + bar.
- Timeline renders one node per step (chains) / task (teams) / phase (workflows). Failed nodes inline the structured error message.
- Events nest under the matching node by
stepId/taskId/phaseId; unscoped events fall to the bottom. - Per-run live events still arrive via the per-run SSE (open the Events collapsible, run something, see new events).
- All collapsibles open and close (Summary, Events, Budget raw, Raw state JSON, Execution plan, Handoffs).
- Reload on
#/runs/{kind}/{id}re-fetches and renders without the user re-selecting.
Catalog screen¶
- Definitions render grouped by kind.
- Search and kind filter narrow results without changing groupings.
- Sort dropdown reorders correctly.
- Clicking a definition with an active version opens the right-side detail with frontmatter, version pills, and body.
- Definitions with no active version show the warning chip and a disabled "No active version" button.
Errors screen¶
- List renders or shows "No errors. Smooth sailing." empty state.
- Refresh button re-fetches.
Accessibility¶
- Tab through the page — first tab focuses the Skip to main content link, which is visible (peach pill) and jumps to
#main-contentwhen activated. - All primary nav buttons receive a visible focus ring (Tab cycles through them).
- Compact run rows on Overview are reachable by Tab; pressing Enter or Space opens the run.
- Activity pause toggle's accessible name is announced (use VoiceOver / NVDA: "Pause or resume live activity, button, pressed/not pressed").
- In macOS Settings → Accessibility → Display → "Reduce motion" enabled: activity feed items appear without slide-in, toasts appear without slide-in.
- Screen reader announces section changes via the
status-messagearia-live region after data loads.
Responsive¶
- Resize to ~1024px desktop → no horizontal scrollbar, sidebar visible (when
data-nav="sidebar"). - Resize to ~768px tablet → grid collapses to single column, top-tabs scroll horizontally if needed.
- Resize to ~375px mobile → cards stack, toolbar inputs full width, tweaks panel takes full viewport width.
Cross-cutting¶
- No
/api/dashboard/eventserrors in browser console under normal operation. - Browser DevTools → Network: no requests to
/api/dashboard/logs,/api/dashboard/settings,/admin/*(those are explicitly out of scope). -
prefers-color-scheme: darkdoes not override the explicitdata-themeattribute set via Tweaks.
When to extend this checklist¶
Add a row whenever:
- A new dashboard section appears in primary nav.
- A new endpoint is consumed by the UI.
- A new interaction pattern is added that would not be caught by Go contract tests.
When a step becomes load-bearing enough that humans repeatedly find regressions in it, promote it to a Go contract test if possible.