freezmo/tests
Martin Dvorak 786d6cf1ae Chat chrome: one gutter, one radius scale, one even glass recipe
The header and composer were full-bleed bands (flush to the top/right/bottom
viewport edges, composer corners off-screen) next to a rail that floats with a
12px margin. The new --layout-gutter (12px) spaces the rail, header, empty-state
card and composer identically on every side; --radius-panel/-control/-chip
(-pill) replace the ad-hoc radii across the shared classes, so every panel is
rounded on all four corners and shared controls match in every theme. The
desktop-only ::after hairlines and the left-corner-only radius are gone.

Aero: the rail and the chat chrome (answers included) share one even recipe -
the wallpaper extra-blurred into a hue-free wash (background-glass.webp) under a
uniform ~50% white veil and a whisper of gloss. Measured within ~10 RGB units
across the rail top->bottom and the card/composer left->right; the blue->green
smear and the teal composer are gone. The composer's field is a clean even tile
with no wallpaper gradient inside it.

Chat fixes: send is a filled primary tile shaped exactly like attach (dimmed
while the input is empty), suggestion/context chips use the shared .chip token
(40/44px target, visible rim, full-contrast text, raw model id in the tooltip),
the AI note reads at 12px --text-muted (.ai-disclaimer), the selected sidebar
row carries the accent border + accent icon, the theme toggle is back in Aero
(the moon flips to Dark; Settings brings Aero back), and the empty state is
centered exactly between header and composer.

Outside CSS: the wallpaper's top-left HUD-circle decoration (it peeked through
the 12px gutters on wide windows) was healed out of background.webp and
background-blur.webp; the orbs/bubbles ride one masked .ice-floats layer that
fades them under the chrome bands and the rail strip, so none is sliced by a
panel edge (still parked under reduced motion).

Version 0.6.0, SW -> freezmo-v82. Tests: chat suite pins the new geometry (12px
gutter, 24px corners, even wash on all four panels, send-vs-attach shape,
chips/input radii); mobile pins the phone chrome and the Aero toggle; bubbles
pins the floats layer + its reduced-motion opt-out.
2026-10-14 21:32:50 +00:00
..
bubble-perf.mjs Stop blurring the animated scene on static glass (2x frame time) 2026-10-12 19:47:36 +00:00
bubbles-test.mjs Chat chrome: one gutter, one radius scale, one even glass recipe 2026-10-14 21:32:50 +00:00
chat-test.mjs Chat chrome: one gutter, one radius scale, one even glass recipe 2026-10-14 21:32:50 +00:00
contrast.mjs Custom Frutiger Aero 404 2026-10-14 15:27:47 +00:00
freeze-loading-test.mjs Move the e2e suites into the repo (tests/), out of /tmp 2026-10-11 15:11:06 +00:00
i18n-test.mjs Follow the copy pass: tests, docs, version, SW 2026-10-14 20:22:12 +00:00
lib.mjs Touch devices blur the live backdrop instead of the baked layer 2026-10-13 14:07:24 +00:00
mobile-test.mjs Chat chrome: one gutter, one radius scale, one even glass recipe 2026-10-14 21:32:50 +00:00
model-compare.mjs Chat mode, phase 1: grounded streaming chat over your notes 2026-10-11 18:32:11 +00:00
native-test.mjs Follow the copy pass: tests, docs, version, SW 2026-10-14 20:22:12 +00:00
phase1-test.mjs Deck/homework writes sync themselves when sync is on 2026-10-12 16:40:49 +00:00
phase2-test.mjs Fix the clipped answer field + the doubled AI note; ordering only where it fits 2026-10-13 07:27:39 +00:00
phase3-test.mjs Aero button glass + homework report control; reduced-motion sheet glitch 2026-10-14 09:19:54 +00:00
providers-test.mjs Follow the copy pass: tests, docs, version, SW 2026-10-14 20:22:12 +00:00
README.md Chat mode, phase 2: local history, answer actions, motion polish 2026-10-11 19:03:48 +00:00
regression.mjs Follow the copy pass: tests, docs, version, SW 2026-10-14 20:22:12 +00:00
review-test.mjs Aero uses the real wallpaper + liquid glass buttons 2026-10-13 06:21:43 +00:00
run-all.mjs Bring-your-own keys for cloud providers (OpenAI-compatible) 2026-10-14 06:29:39 +00:00
security-test.mjs Security: model budget + concurrency caps, SSRF guards, spoof-proof limits 2026-10-12 20:40:57 +00:00
wizard-test.mjs Follow the copy pass: tests, docs, version, SW 2026-10-14 20:22:12 +00:00

Browser suites

End-to-end checks for Freezmo, driven by Playwright against a running production build. Everything lives in this repo (nothing in /tmp), so a reboot cannot wipe the harness.

Requirements

  • The app is running on http://127.0.0.1:3207 (systemctl --user start freezmo).
  • A Chromium build. The suites auto-detect the newest Playwright Chromium in ~/.cache/ms-playwright/; override with CHROME=/path/to/chrome.
  • npm install (dev deps: playwright-core, axe-core).

Running

npm run build && systemctl --user restart freezmo   # fresh build first
npm run test:e2e                 # every suite, in order
npm run test:e2e -- phase1       # only suites whose name contains "phase1"

Each suite prints PASS/FAIL lines and exits non-zero on failure; the runner prints a per-suite summary at the end.

Suites

Suite Covers
regression.mjs Library, deck card + menu, study feed to results, homework entry, desktop shell + settings/health panel.
bubbles-test.mjs Ice-scene bubbles: stacking/layout contract, keyframes only transform+opacity, rise/sway/scale/fade phases, per-breakpoint counts (5/3/2), phone pacing, reduced motion, tab-hidden parking.
mobile-test.mjs Five-tab bar at 360/390 × EN/CS × dark/light × reduced motion (labels, targets, no hamburger/drawer), the library ⋯ sheet (Import JSON / New folder), the settings sheet (touch targets, key flow, drag-to-close, backdrop), axe contrast audits.
wizard-test.mjs Deck 3-step flow and homework flow, flat action bar, in-page mode switch, the loading lock, abort-on-leave.
native-test.mjs Manifest/PWA head, offline banner + disabled generate, share target GET + POST, Back-gesture layers, undo toast, tab re-tap, haptics, draft restore.
i18n-test.mjs EN/CS dictionary parity, locale switch, Czech desktop shell, Czech phone tab labels and plurals.
freeze-loading-test.mjs The generation loading screen appears immediately, hides the action bar, Cancel returns with the notice.
review-test.mjs Smart Review loading feedback under a stalled request, the session end-to-end, mistakes, and the health-probe cache.
phase1-test.mjs Backup export/import, persistence row, nudge, encrypted sync (enable/join/push/delete + API validation), usage-limit handling (client + a stub Ollama).
phase2-test.mjs Answer history + SRS from a real study run, review/mistakes, stats, exam mode, push reminders hidden without VAPID and validated with it.
phase3-test.mjs Check my work (API + phone/desktop UI), follow-ups, guide step explain, turn-into-a-study-deck.
chat-test.mjs Chat: streaming API (validation, allowlist, context travel, history window, thinking separation, usage-limit mapping), attachment extraction, entry points, streaming/stop, markdown + KaTeX, model/scope pickers, edit/regenerate, offline, reduced motion, plus history (IDB persistence, reload, rename/search/delete/undo, scope+model memory), assistant actions, the export payload and a two-device sync round-trip.

Extra instances

phase1, phase2 and phase3 start their own next start instance with a stub Ollama (or VAPID keys) on a spare port (3208/3209). Each suite checks the port is free first and kills the whole process group on exit, so ports do not leak between suites. Scratch data for the VAPID test lives in tests/.tmp/ (gitignored).

Diagnostics (not part of the run)

node tests/bubble-perf.mjs [label] measures the ice-scene frame cost with a CDP performance trace (rAF frame timing, long tasks, main-thread busy time, style recalcs) on a 4× throttled phone profile and a 2× desktop profile. It always exits 0; the numbers are for tuning the bubble count/speed.