mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-10-21 05:01:26 -07:00
test: add headless end-to-end harness (#286)
* test: add headless end-to-end harness and CI job Boot the built app against a real mpv, a synthetic clip, a fixture Yomitan dictionary, and a fake AnkiConnect inside a private Xvfb display, then assert on the overlay DOM and the AnkiConnect requests. Adds the test:e2e lane, an e2e session CLI for exploratory checks, and a three-platform CI job. * ci: set e2e temp dir from a step * test: make e2e session startup robust on slow machines Bun caps node:test hooks at 5s, so boot the session inside the first test. Keep pausing until the app's resume retries stop, read cue tokens in one round trip, and resolve Electron through its package entry so CI downloads the binary. * test: harden e2e harness for CI runners Fail fast when mpv cannot be spawned, read every Yomitan popup frame instead of trusting target order, and put the chocolatey mpv directory on PATH. * test: add e2e failure diagnostics and mark Windows job experimental Report what the overlay showed when a cue never renders, dispose the session when the overlay cannot be opened, skip popup frames that vanish mid-poll, and turn off AniSkip lookups in the harness config. * test: read the lookup popup entry from textContent * test: capture renderer console and main-side subtitle state in e2e failures * test: expose the Electron main-process inspector to the e2e harness Adds session.mainProcess() and 'e2e eval main', and reports main's window list alongside the overlay state when a cue never renders. * test: tap subtitle sends and receipts in e2e failure diagnostics * test: probe alternate main-to-renderer paths in e2e failure diagnostics * test: select the visible overlay layer, not the primed modal window Windows and macOS pre-create a hidden modal window that loads the same renderer document, and the harness could attach to it instead of the visible overlay. Drops the delivery taps that found this. * ci: run the Windows e2e job as a normal matrix entry * test: address review on e2e harness Slice the app log at a byte offset before decoding, create the session state file owner-only since it carries the inspector URL, and keep the cue failure when inspector diagnostics are unavailable. * test: create the e2e session state file exclusively
This commit is contained in:
1 parent
b48083ddd8
commit
78eca52b7e
19 files changed
+1400
-2
No files matched your search
@@ -3,7 +3,7 @@
|
||||
# Verification
|
||||
|
||||
Status: active
|
||||
Last verified: 2026-08-13
|
||||
Last verified: 2026-10-05
|
||||
Owner: Kyle Yasuda
|
||||
Read when: selecting the right verification lane for a change
|
||||
|
||||
@@ -58,6 +58,8 @@ bun run docs:build
|
||||
- Launcher/plugin: `bun run test:launcher` or `bun run test:env`
|
||||
- Runtime-compat / compiled behavior after `bun run build`: `bun run test:runtime:compat`
|
||||
- Stats dashboard UI: `bun run test:stats`
|
||||
- Overlay, renderer, mpv, or mining behavior that unit tests cannot show: `bun run build`,
|
||||
then `bun run test:e2e` (see [Headless End-to-End Harness](#headless-end-to-end-harness))
|
||||
- Build/release scripts (`scripts/**`): `bun run test:scripts`
|
||||
- Packaging: build the platform package, then run `bun run test:package <resources-directory>`.
|
||||
On headless Linux: `xvfb-run -a bun run test:package release/linux-unpacked/resources`.
|
||||
@@ -93,6 +95,54 @@ bun run docs:build
|
||||
- This is not a full Electron UI startup check. It does not require a display and
|
||||
makes no claims about renderer, window, tray, or mpv behavior.
|
||||
|
||||
## Headless End-to-End Harness
|
||||
|
||||
`bun run test:e2e` boots the built app against a real mpv and asserts on what the
|
||||
overlay renders and what reaches AnkiConnect. Use it instead of a live desktop test
|
||||
whenever the behavior does not depend on a specific compositor.
|
||||
|
||||
- Needs an existing `bun run build`, plus `mpv` and `ffmpeg` on `PATH` (and `Xvfb` on
|
||||
Linux). It is not part of `test:fast` or the handoff gate. The `e2e` job in
|
||||
`.github/workflows/ci.yml` runs it on Linux, macOS, and Windows for pull requests and
|
||||
`main`, outside the reusable quality gate, and uploads the session logs when it fails.
|
||||
- Every run is sandboxed in a temp dir: its own config and Electron profile, mpv IPC
|
||||
socket, and a fake AnkiConnect on a free port. It never touches the user's running
|
||||
SubMiner, Anki, or stats database. It is not offline: the app still asks AniList for
|
||||
cover art matching the clip's title.
|
||||
- Media is synthetic: an ffmpeg test-pattern clip, a three-cue Japanese `.srt`, and a
|
||||
tiny Yomitan dictionary covering those cues (`e2e/harness/fixtures.ts`). The harness
|
||||
imports the dictionary on a first boot, then restarts the app for the scenario.
|
||||
- Display: Linux runs everything inside a private Xvfb server, so no window reaches the
|
||||
desktop. macOS and Windows have no offscreen display server, so windows open in the
|
||||
current session there; `SUBMINER_E2E_DISPLAY=host` forces the same on Linux. The
|
||||
CI job runs all three. On macOS and Windows the app pre-creates a hidden modal window
|
||||
that loads the same renderer document, so window matching must include the
|
||||
`layer=visible` query (`OVERLAY_PAGE`).
|
||||
- The app is driven over the Chrome DevTools Protocol (DOM queries, input events,
|
||||
per-window screenshots), mpv over its JSON IPC socket, and app commands through the
|
||||
normal CLI handoff (`--mine-sentence`, `--toggle-subtitle-sidebar`, ...).
|
||||
- Scenarios live in `e2e/*.e2e.test.ts` and share one session per file through
|
||||
`startE2eSession()`. Pass `config` to override settings for a scenario file.
|
||||
- On a failed startup the temp dir is kept and its path is in the error. Set
|
||||
`SUBMINER_E2E_KEEP=1` to keep it after any run (`app-stdio.log`, `app.log`, `mpv.log`).
|
||||
|
||||
For exploratory checks, keep one session up and poke at it:
|
||||
|
||||
```bash
|
||||
bun run e2e start & # prints the session JSON, stays up until stopped
|
||||
bun run e2e mpv seek 2 absolute+exact
|
||||
bun run e2e eval overlay 'document.getElementById("subtitleRoot").textContent'
|
||||
bun run e2e shot overlay /tmp/overlay.png
|
||||
bun run e2e app --mine-sentence
|
||||
bun run e2e anki # AnkiConnect requests received so far
|
||||
bun run e2e stop
|
||||
```
|
||||
|
||||
Out of scope: compositor-specific behavior (Hyprland placement, stacking, fullscreen,
|
||||
click-through), real GPU video output, and global shortcuts. Xvfb runs without a window
|
||||
manager or compositor, so the transparent overlay is not composited over the video;
|
||||
check overlay visuals with per-window screenshots, and use the live desktop for the rest.
|
||||
|
||||
## Dependency Audit Policy
|
||||
|
||||
- `bun audit --audit-level high` blocks the reusable quality gate.
|
||||
|
||||
Reference in new issue
Block a user