- name
- dev-testing-frontend
- description
- Testing the Capsem frontend. Use when writing frontend tests, running type checks, or doing visual verification with Chrome DevTools MCP.
# Frontend Testing
## Stack
Astro 7 + Svelte 5 (runes only) + Tailwind v4 + Capsem-owned semantic CSS + LayerChart v2.
## Running tests
```bash
pnpm --dir web/app run check # astro check + svelte-check
pnpm --dir web/app exec vitest run --coverage
pnpm --dir web/app run build # Production bundle
```
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 `web/app/src/lib/__tests__/`. Use vitest with standard patterns:
```ts
import { describe, it, expect } from 'vitest';
```
## Browser and test data
Browser and Tauri sessions both use the real gateway through the SDK in
`api.ts`. The absence of `window.__TAURI_INTERNALS__` does not enable mock
responses. Start the real service and gateway for browser acceptance, or
explicitly supply a hermetic test transport in unit tests.
`just dev ui` starts the frontend; its API requests use the gateway. Stopped
fixture sessions can exercise UI states without booting a VM, but cannot
establish working guest execution or credential connection flows.
**Generated test data**: `mock-settings.generated.ts` is produced by
`build_system/scripts/build/generate_schema.py` from the canonical settings
metadata. It supports explicit test fixtures, not an automatic browser mode.
Use the schema-generation owner included in `just test`; never hand-edit it.
## 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
1. Start `just dev ui` (if not already running)
2. `navigate_page` to `http://localhost:5173`
3. `list_console_messages` types=["error","warn"] -- expect zero
4. Navigate to the view(s) affected by your change
5. `take_screenshot` each affected view -- visually confirm it renders correctly
6. If the change affects multiple views or layout, screenshot all views (Terminal, Sessions, Network, Settings)
7. Check console again after navigation for new errors
### Settings view
Click through every section (AI Providers, Repositories, Security, VM, Appearance). Verify:
- All settings from `config/settings/ui-metadata.generated.json` are present;
derive the expected settings from that metadata instead of copying a count
- Provider toggle enables/disables child settings visually
- API key reveal button works (password <-> text)
- 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 `config/settings/ui-metadata.generated.json` or regenerating `mock-settings.generated.ts`:
1. Use the schema-generation owner included in `just test`
2. Start `just dev ui`
3. Navigate to Settings view
4. Screenshot and verify new/changed settings appear correctly
5. Check that setting counts match (grep `mockSettings.find` in 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-changed` payload 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 `@source` directives to scan Svelte files
- The semantic theme is checked in at `src/styles/capsem-theme.css`; tests must reject any Preline package, `node_modules/preline` scan, upstream CSS import, JS plugin, `data-hs-*` attribute, or `HSStaticMethods` use.
Ver no GitHub