Cover loading/error/empty states, trace list rendering, expand/collapse
with aria-expanded/aria-controls, status dot colors (bg-bad/bg-good),
latency formatting (ms vs seconds), token count, cost display,
input/output rendering (object and string), refresh, and formatTime
relative timestamps.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add 49 test cases covering schedule list, status dot colors,
toggle/edit/delete/run-now, create/edit forms, form validation,
auto-refresh (10s interval), cronToHuman/relativeTime formatting,
and error states.
Also fix ScheduleTab: (1) set error state on GET failure so the
banner is visible, (2) move error banner outside the form block so
non-form errors are shown to the user.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Cover channel list, toggle, delete, discover, form validation,
schema-driven inputs (password/textarea/text), platform switching,
allowed_users, auto-refresh, and error states.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Covers: loading/empty/event-list states, event_type color mapping,
expand/collapse with aria-expanded/aria-controls, refresh button,
error state from API rejection, auto-refresh interval via setInterval mock,
and unmount cleanup.
Key patterns:
- vi.hoisted() for module-level api mock (vi.mock hoisting)
- vi.useRealTimers() for non-timing tests; spyOn(setInterval/clearInterval)
for auto-refresh tests to avoid Vitest fake-timer infinite loops
- fireEvent.click + native .click() via act() for expand/collapse
- Re-query DOM after state flush to avoid stale element references
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds first test coverage for canvas/ExternalConnectModal. Tests: renders null
when info absent, dialog open/close, default tab selection (Universal MCP vs
Python), tab switching and visibility (Hermes/Codex conditional), auth token
stamping for Python/MCP/curl snippets, clipboard.writeText API call,
close button callback, security warning, Fields tab with (missing) fallback.
Radix Dialog tested by rendering with open=true. Clipboard API mocked via
Object.defineProperty in beforeEach. renderAndFlush uses act(()=>{}) to
synchronously flush Radix portal rendering so dialog queries work without
waitFor (which times out under vi.useFakeTimers).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>