name: dev-testing-frontend description: Testing the Capsem frontend (Astro 5 + Svelte 5 + Tailwind v4 + Preline). Use when writing frontend tests, running type checks, debugging UI issues, or doing visual verification with Chrome DevTools MCP. Covers vitest, svelte-check, astro check, mock mode, and systematic visual verification workflow.
Frontend Testing
Stack
Astro 5 + Svelte 5 (runes only) + Tailwind v4 + Preline + LayerChart v2.
Running tests
cd frontend
pnpm run check # astro check + svelte-check (type errors)
npx vitest run --coverage # Unit tests with coverage
pnpm run build # Production build (catches bundling issues dev misses)
All three run as part of just test. The production build is important -- Tailwind v4's Vite plugin can miss client:only components in the SSR module graph, so @source directives in global.css must explicitly include .svelte and .ts files.
Test files
Tests live in frontend/src/lib/__tests__/. Use vitest with standard patterns:
import { describe, it, expect } from 'vitest';
Mock mode
When window.__TAURI_INTERNALS__ is absent (browser via just ui), api.ts auto-switches all IPC calls to return fake data from mock.ts. Settings data comes from mock-settings.generated.ts (auto-generated from config/defaults.json by the builder). Other mock data (MCP servers, VM state, logs) lives in mock.ts.
This means you can test the full UI without a VM by running just ui.
Generated mock data: mock-settings.generated.ts is produced by scripts/generate_schema.py from the TOML configs in guest/config/. It runs as part of just run and just test via the _generate-settings recipe. Never hand-edit this file.
Visual verification with Chrome DevTools MCP
Every UI change requires visual verification via Chrome DevTools MCP. No exceptions. Type checks and unit tests pass on broken UIs all the time. The only way to know the UI actually works is to look at it.
Workflow for every UI change
- Start
just ui(if not already running) navigate_pagetohttp://localhost:5173list_console_messagestypes=["error","warn"] -- expect zero- Navigate to the view(s) affected by your change
take_screenshoteach affected view -- visually confirm it renders correctly- If the change affects multiple views or layout, screenshot all views (Terminal, Sessions, Network, Settings)
- Check console again after navigation for new errors
Settings view
Click through every section (AI Providers, Repositories, Security, VM, Appearance). Verify:
- All settings from
defaults.jsonare present (currently 68 leaf settings) - Provider toggle enables/disables child settings visually
- API key reveal button works (password <-> text)
- Snapshots section shows auto_max, manual_max, auto_interval
- VM Resources section shows all resource settings including min_content_sessions
- Theme toggle switches live
- Lint warnings display inline
After changing TOML configs or generated mock data
When modifying guest/config/*.toml or regenerating mock-settings.generated.ts:
- Run
just _generate-settings(or letjust run/just testdo it) - Start
just ui - Navigate to Settings view
- Screenshot and verify new/changed settings appear correctly
- Check that setting counts match (grep
mockSettings.findin generated file)
Color rules (firm)
- Blue (
info) = positive (allowed, running, ok). No green in UI chrome. - Purple (
secondary) = negative (denied, stopped, error). No red in UI chrome. - Terminal emulation colors (xterm green) are fine -- that's xterm, not UI.
Svelte 5 reference
Read references/svelte5.md for Svelte 5 patterns and the @sveltejs/mcp CLI for doc lookups.
Gotchas
vm-state-changedpayload is{ state, trigger }(object), not a plain string- Dynamic Svelte components: use
<svelte:component this={item.icon} />, not<item.icon /> - Tailwind v4 +
client:only: needs@sourcedirectives to scan Svelte files - Preline is CSS-only -- no JS plugins, no
data-hs-*attributes, noHSStaticMethods