test(frontend): cover the lifecycle, the voice and the repaints

Component and store cases for everything in this series, several of
which exist because the thing they pin is invisible everywhere else:

- `view-lifecycle` and `keyboard-reach` — a document listener count
  that does not grow across a simulated navigate cycle, and a tab
  sequence that reaches the sidebar and plays a row without a mouse.
- `notifications`, `notification-store`, `confirm-dialog`,
  `empty-states` — the four levels, the (level, region, key)
  coalescing window, and loading/failed/empty as three states.
- `card-grid-repaint` — fails if `artists-view`'s or `genres-view`'s
  per-render arrow functions are hoisted to stable fields, which is
  the audit's own recommendation and takes the cards from 1 highlighted
  to 0. It exists for no other reason.
- `lazy-track-details` — reads the five sources and fails on a
  returning static import, the same shape as `TestNoDirectRuntimeEmits`
  and for the same reason: the invariant is about what the code does
  *not* say.
- `now-playing` — a position report that changes nothing must not
  touch the DOM again, and a track change must. The first fails
  against the old unconditional `updated()`.
- `playlist-virtualization`, `list-render-cost`, `selection`, `icons`,
  and the store cases for the library-filter race, the never-settling
  waiter and the per-playlist patch.
This commit is contained in:
2026-08-12 01:20:03 -04:00
parent 2518385330
commit 5830b1ba17
25 changed files with 2498 additions and 37 deletions
+15 -5
View File
@@ -4,12 +4,16 @@
* 1. Install the Wails fake. Store singletons call `EventsOn` and load
* from the backend *in their constructors*, which run when a test
* module imports them — so the globals have to exist first.
* 2. Point Web Awesome at its assets. Without this every `<wa-icon>`
* silently 404s and screenshots come out with holes in them.
* 2. Point Web Awesome at its assets, and register the *bundled* icon
* library — the same call `index.ts` makes. Without the second
* one this tier renders icons from fontawesome.com, so a green
* `make ui-test` would depend on the network and the screenshot
* baselines would be of something the app no longer ships.
*/
import { afterEach, beforeEach } from 'vitest';
import { setBasePath } from '@awesome.me/webawesome/dist/webawesome.js';
import '@awesome.me/webawesome/dist/styles/themes/default.css';
import { registerBundledIcons } from '../src/icons';
import { installWailsFake, wails } from './support/wails-fake';
import { resetHarness } from './support/harness';
import { cleanupFixtures } from './support/render';
@@ -43,10 +47,16 @@ for (const [path, value] of importTimeDefaults) {
wails.stub(path, value);
}
// Vite serves the dependency's own directory, so icons resolve from
// node_modules rather than from the built `dist/webawesome` copy the
// app uses.
// Vite serves the dependency's own directory, so Web Awesome's own
// assets resolve from node_modules rather than from the built
// `dist/webawesome` copy the app uses.
//
// Note this does *not* cover icons: `getBasePath` is read only by the
// component autoloader, never by the icon resolver, which is the
// original half of audit finding H-4 and the reason the line below
// exists rather than being implied by this one.
setBasePath('/node_modules/@awesome.me/webawesome/dist');
registerBundledIcons();
// index.ts imports the theme store for its side effect: it derives the
// --yj-* custom properties and applies them to :root, where every