144 lines
4.7 KiB
Markdown
144 lines
4.7 KiB
Markdown
# GUI Testing
|
|
|
|
## Overview
|
|
|
|
Verstak Desktop uses **Playwright** for frontend E2E tests that run in a real
|
|
Chromium browser with mocked Wails bindings. This tests the Svelte component
|
|
logic, user interactions, and UI state transitions — without needing the actual
|
|
Wails desktop shell.
|
|
|
|
## What is tested
|
|
|
|
### Frontend E2E (Playwright)
|
|
|
|
Located in `frontend/e2e/`, run via `npm run test:e2e`.
|
|
|
|
These tests:
|
|
|
|
- Launch a Vite dev server with mock Wails bindings
|
|
- Open the app in a real Chromium browser via Playwright
|
|
- Simulate user clicks, wait for UI transitions, assert DOM state
|
|
- Collect console errors and page errors on failure
|
|
- Capture screenshots on failure
|
|
|
|
### Test suites
|
|
|
|
| File | Suite | Tests | Status |
|
|
|------|-------|-------|--------|
|
|
| `plugin-manager-disable-enable.spec.js` | A: Disable/Enable refresh | 4 | 3 pass, 1 fail* |
|
|
| `sidebar-opens-view.spec.js` | B: Sidebar → view routing | 3 | 3 pass |
|
|
| `reload-updates-state.spec.js` | C: Reload updates UI | 3 | 2 pass, 1 fail* |
|
|
|
|
\* Failing tests document **known bugs** (see below).
|
|
|
|
## Known bugs detected by tests
|
|
|
|
### Bug M5-1: Sidebar does not update when plugin state changes
|
|
|
|
**Symptom:** After disabling a plugin in Plugin Manager, the sidebar item for
|
|
that plugin remains visible. After re-enabling, it stays visible (doesn't
|
|
disappear then reappear — it was never gone).
|
|
|
|
**Root cause:** `Sidebar.svelte` loads plugin/contribution data once in
|
|
`onMount` and stores it in local `sidebarItems`. When `PluginManager`
|
|
disables/enables a plugin and calls `ReloadPlugins`, the `PluginManager`
|
|
component re-fetches data, but `Sidebar` does not react to the change — it
|
|
still holds the stale list.
|
|
|
|
**Affected tests:**
|
|
- `A: Disable plugin: button changes to Enable, sidebar item disappears`
|
|
- `A: Disable → Enable full flow in sequence`
|
|
- `C: Reload after mock state change reflects new plugin status`
|
|
|
|
**Fix needed:** Sidebar must either:
|
|
1. Re-fetch contributions when it receives a custom event (e.g.
|
|
`verstak:plugins-reloaded`), or
|
|
2. Read plugin state reactively from a shared store that both
|
|
PluginManager and Sidebar subscribe to.
|
|
|
|
## What is NOT tested
|
|
|
|
### Real desktop GUI (WebKitGTK + Wails native shell)
|
|
|
|
The Playwright tests run the frontend in a **standard Chromium browser** with
|
|
mocked Wails bindings. They do **not** test:
|
|
|
|
- Actual WebKitGTK rendering (Wails uses WebKitGTK, not Chromium)
|
|
- Native window management (minimize, maximize, resize)
|
|
- Native file dialogs (SelectDirectory, SelectVaultForOpen)
|
|
- Clipboard integration
|
|
- System tray / menu bar
|
|
- Plugin frontend bundle loading from real filesystem
|
|
- Wails event system (window.runtime.EventsOn/Emit)
|
|
|
|
For real Wails smoke tests, a separate layer is needed using:
|
|
- **AT-SPI2** (Linux accessibility tree inspection)
|
|
- **xdotool** / **ydotool** (input simulation)
|
|
- **scrot** / **import** (screenshot capture)
|
|
|
|
## Running tests
|
|
|
|
```bash
|
|
cd frontend
|
|
|
|
# Run all E2E tests (headless)
|
|
npm run test:e2e
|
|
|
|
# Run with Playwright UI (interactive)
|
|
npm run test:e2e:ui
|
|
|
|
# Run in headed browser (visible)
|
|
npm run test:e2e:headed
|
|
```
|
|
|
|
## Test infrastructure
|
|
|
|
### Mock bridge (`src/lib/test/wails-mock.js`)
|
|
|
|
Replaces `window['go']['api']['App']` with in-memory mock implementations of
|
|
all Wails backend methods. Provides:
|
|
|
|
- Mutable plugin state (enable/disable/status)
|
|
- Mutable vault state
|
|
- Mutable contributions (views, commands, sidebar items, settings panels)
|
|
- Test helpers via `window.__wailsMock`:
|
|
- `reset()` — reset all state to defaults
|
|
- `setPluginStatus(id, status, enabled)` — change plugin state
|
|
- `getPluginState(id)` — read current state
|
|
- `setVaultStatus(status)` — change vault state
|
|
|
|
### Test harness (`index.html`)
|
|
|
|
The same `index.html` is used for both production and test. It detects whether
|
|
the Wails runtime (`window['go']`) is present. If not (i.e. running in a plain
|
|
browser), it loads the mock bridge before the Svelte app.
|
|
|
|
### Playwright config (`playwright.config.js`)
|
|
|
|
- Dev server: `vite --mode test --port 5174`
|
|
- Browser: Chromium headless
|
|
- Timeouts: 30s test, 10s expect
|
|
- Workers: 1 (sequential)
|
|
- Screenshots: on failure
|
|
- Traces: on first retry
|
|
- Results: `e2e-results/test-results.json`
|
|
|
|
## Adding new tests
|
|
|
|
1. Create `e2e/your-test.spec.js`
|
|
2. Import helpers from `./helpers.js`
|
|
3. Use `test.beforeEach` to reset mock state and navigate to `/`
|
|
4. Use `test.afterEach` to assert no console errors
|
|
5. Write scenarios as user actions + assertions
|
|
6. Run with `npm run test:e2e`
|
|
|
|
### Selector conventions
|
|
|
|
- Plugin cards: `.plugin-card` filtered by text
|
|
- Buttons: `.btn-disable`, `.btn-enable`, `.btn-settings`, `.reload-btn`
|
|
- Sidebar items: `.sidebar .plugin-item`
|
|
- View container: `.view-container`
|
|
- View header: `.view-header h2`
|
|
- Status badges: `.status-badge`
|
|
- Toast: `.toast`
|