|
| 1 | +--- |
| 2 | +name: testing-wavegrid-desktop-gui |
| 3 | +description: End-to-end GUI testing of the Wavegrid Electron desktop app (routes, Output/OSC debugger, embedded artist UI, full-screen show view) on a headless Linux box with xdotool/scrot. Use when verifying desktop renderer or packages/ui changes at runtime rather than with unit tests. |
| 4 | +--- |
| 5 | + |
| 6 | +# Testing the Wavegrid desktop app end-to-end (GUI) |
| 7 | + |
| 8 | +## Harness |
| 9 | + |
| 10 | +```sh |
| 11 | +cd /home/ubuntu/repos/wavegrid |
| 12 | +pnpm install # blueprint maintenance already does this |
| 13 | +pnpm --filter @wavegrid/ui run build # ALWAYS rebuild if packages/ui changed; |
| 14 | + # the desktop serves packages/ui/dist |
| 15 | +ELECTRON_ENABLE_LOGGING=1 DISPLAY=:0 \ |
| 16 | + pnpm --filter @wavegrid/desktop start > /tmp/desktop.log 2>&1 & |
| 17 | +``` |
| 18 | + |
| 19 | +- The CLI runs from built output, not a global binary: `node packages/cli/dist/bin.js …` |
| 20 | + (`projects config`, `signals send|probe|listen`, `doctor`). |
| 21 | +- Store lives in `~/.wavegrid`; logs in `~/.wavegrid/logs/<project>/`. |
| 22 | +- Set the layout explicitly or you may land in `distributed` run mode (49 cannons): |
| 23 | + `node packages/cli/dist/bin.js projects config set layout nova` (6-cannon ring, simple mode). |
| 24 | +- `ELECTRON_ENABLE_LOGGING=1` forwards renderer console to `/tmp/desktop.log`. Expect harmless |
| 25 | + noise: DBus `bus.cc` failures, GPU/Dri3 init errors, Electron CSP warning, and a stale |
| 26 | + `ERR_CONNECTION_REFUSED` for `http://127.0.0.1:3000` logged before the brain starts. |
| 27 | + |
| 28 | +## Window and input |
| 29 | + |
| 30 | +- `wmctrl -l` may be empty (the WM here does not export `_NET_CLIENT_LIST`). Use |
| 31 | + `xdotool search --name "Wavegrid Desktop"` plus `xdotool windowmove/windowsize` instead; |
| 32 | + a ~1600x1120 window keeps all controls on screen. |
| 33 | +- Drive the UI with `xdotool mousemove X Y click 1` / `key Escape`, capture with `scrot -o`. |
| 34 | +- If a click seems to do nothing, re-screenshot and re-read coordinates before concluding the |
| 35 | + feature is broken — control rows shift as state changes (e.g. OSC Listen/Stop swap position). |
| 36 | + Keyboard focus (`xdotool key Tab … Return`) is a reliable fallback. |
| 37 | +- When shelling out to Python/subprocess for screenshots, inherit `os.environ` and set |
| 38 | + `DISPLAY=:0`; a minimal env loses X authorization (`scrot: Can't open X display`). |
| 39 | + |
| 40 | +## App-specific facts |
| 41 | + |
| 42 | +- Sidebar routes: Run = Show, Status; Set up = Layout, Lights, Output; Advanced = Devices, |
| 43 | + People & Keys, Settings. Nova, OSC and Traffic are NOT outer-shell routes: the OSC debugger is |
| 44 | + Output → Advanced, and Nova is a tab inside the embedded artist UI. |
| 45 | +- The embedded artist UI is a native Electron `WebContentsView` (not an iframe), auto-signed-in via |
| 46 | + an operator token — no manual login. Because it is native, its pixels are outside the renderer |
| 47 | + DOM: verify it with screenshots, never with DOM queries. |
| 48 | +- Full-screen show view: renderer renders `fixed inset-0` and re-reports slot bounds via |
| 49 | + `window.wavegridLaser.sync`. Exit paths to test separately: the button, Escape in the renderer, |
| 50 | + and Escape while focus is *inside* the embedded contents (forwarded by a `before-input-event` |
| 51 | + handler as `laser:escape`) — click inside the grid first to move focus there. |
| 52 | +- There is no user-reachable way to stop the show while full screen (no custom menu/global |
| 53 | + shortcut, Show controls are unmounted). Report that as untested, not as a pass. |
| 54 | +- OSC debugger: probing with nothing bound to the port honestly reports "nothing listening"; start |
| 55 | + `node packages/cli/dist/bin.js signals listen --port 8010` to see the verdict flip. Verify a real |
| 56 | + UDP bind with `ss -uln | grep 8010` before/after the panel's Listen/Stop. |
| 57 | +- Artist UI panel layout persists in localStorage `wavegrid-panel-layout`; a stop+start of the show |
| 58 | + reloads the embedded contents and is the easiest user-reachable "reload" for the persistence test. |
| 59 | + |
| 60 | +## Measuring animation instead of guessing |
| 61 | + |
| 62 | +Frame-diff two screenshots ~0.5s apart over the grid region and compare the mean absolute |
| 63 | +difference; use it to prove an animation is running, that Speed changed the rate, and that a look |
| 64 | +survives a soak. A still frame (diff ≈ 0) means the animation stopped. |
| 65 | + |
| 66 | +## Known interaction caveats (may still be present) |
| 67 | + |
| 68 | +- Master `Bright` may appear not to dim the grid while a Nova pattern is running — the pattern |
| 69 | + re-asserts per-cannon brightness each frame. Test Bright in Paint mode (paint the grid, then drag |
| 70 | + Bright 100 → 0) to isolate the control. |
| 71 | +- The top-bar Speed slider is logarithmic; its displayed minimum has been observed as `0.001x` |
| 72 | + even though `SPEED_MIN = 0.01` in `packages/ui/src/app.tsx`. Re-check the formatting/rounding |
| 73 | + before reporting the range as in-spec. |
| 74 | + |
| 75 | +## Devin Secrets Needed |
| 76 | + |
| 77 | +None — everything runs locally with no external credentials. |
0 commit comments