The Playwright net now runs every flow in three projects: chromium (Desktop Chrome), webkit (Desktop Safari) and ipad (iPad gen 7 landscape: touch, mobile viewport). WebKit catches the engine-level differences every iOS browser inherits; the config and the README say plainly what it does NOT catch: iPad media refusals. Playwright's WebKit decodes through the host OS, and on Windows it played an mp3-in-mp4 and an AV1 mp4 that a real iPad refuses, so media formats are checked on a real iPad against the dev stack over the LAN. global.setup opts the e2e account out of starting on Home (the Startup setting), which the feed, channel and player specs need since E24. It only takes effect with the new-tab boot fix: before it, all twelve of those specs landed on Home in every project. 49/49 green on :8080 across the three projects.
62 lines
3.2 KiB
Markdown
62 lines
3.2 KiB
Markdown
# E2E characterization (golden-master) net
|
||
|
||
Playwright tests that lock the app's five core flows — **feed** (scroll + filter), **channel**
|
||
(open → back), **player** (open/close), **settings** (dirty-save + guard), and **page switching** —
|
||
so the Platform refactor can _prove_ it changed nothing. They assert current, correct behavior;
|
||
they deliberately do **not** encode the known Platform bugs (those get their own specs when the
|
||
sprints that fix them land).
|
||
|
||
## Run
|
||
|
||
```sh
|
||
siftlode e2e # against the baked localdev :8080 stack (authoritative)
|
||
siftlode e2e-ui # same, Playwright UI mode
|
||
siftlode e2e-seed # (re)seed the test account only, no tests
|
||
```
|
||
|
||
The localdev stack must be up (`siftlode dev`). `global.setup.ts` reseeds the account and logs in
|
||
once, sharing the session via `e2e/.auth/state.json` (git-ignored).
|
||
|
||
**Browsers** — every flow runs in three projects: `chromium` (Desktop Chrome), `webkit` (Desktop
|
||
Safari) and `ipad` (iPad gen 7 landscape: 1080×810, touch, mobile). Install the engines once per
|
||
machine with `npx playwright install chromium webkit`; run one project with
|
||
`npx playwright test --project=ipad`. WebKit catches what every iOS browser inherits from the engine
|
||
(JS, CSS/layout, event order). It does **not** reproduce iPad media refusals: Playwright's WebKit
|
||
decodes through the host OS (Media Foundation on Windows, GStreamer on Linux), and measured on
|
||
2026-09-14 it played an mp3-in-mp4 and an AV1 mp4 that a real iPad refuses. Check a media format
|
||
on a real iPad against the dev stack over the LAN (`http://<desktop LAN IP>:8080`, e.g. a
|
||
login-free `/watch/<token>` share link).
|
||
|
||
**Target** — `PW_BASE_URL` (default `http://127.0.0.1:8080`):
|
||
|
||
- **`:8080`** (baked SPA) is authoritative and same-origin. After a **frontend change you must
|
||
`siftlode dev` (rebuild)** for its baked SPA to carry the latest test hooks.
|
||
- **`:5173`** (Vite dev) serves source live — the fast refactor loop; it proxies `/api` to `:8080`,
|
||
so the stack must still be up. All five flows are proxy-safe (none use the WebSocket):
|
||
|
||
```sh
|
||
PW_BASE_URL=http://localhost:5173 siftlode e2e
|
||
```
|
||
|
||
## Account & fixture
|
||
|
||
Tests run as a dedicated, **non-demo admin** account `e2e@siftlode.local` (never a real account;
|
||
admin so the suite can reach the admin-only pages / render branches, matching the real primary
|
||
user), reset to a deterministic baseline every run by
|
||
[`scripts/e2e_seed.py`](../../scripts/e2e_seed.py) (run
|
||
in-container so it reuses the app's models + argon2 hasher): the top-3 organic channels subscribed,
|
||
one in-progress + one watched + one saved video, prefs pinned to `language: en`. Credentials come
|
||
from `E2E_EMAIL` / `E2E_PASSWORD` (local-only defaults). Override the container name with
|
||
`E2E_API_CONTAINER`; skip the in-container seed with `E2E_SKIP_SEED=1`.
|
||
|
||
## Selectors
|
||
|
||
The app has no `data-testid`s of its own and all copy is i18n (en/hu), so the specs key on a thin
|
||
`data-testid` layer (added with this sprint) plus the locale pinned to `en`. Stable ARIA hooks that
|
||
already existed are used directly (`role="dialog"` on the player, `aria-current="page"` on the
|
||
active nav row, `aria-pressed` on the feed toggles).
|
||
|
||
## Typecheck
|
||
|
||
`npx tsc -p e2e/tsconfig.json --noEmit` (the specs are outside the app's `src` tsconfig).
|