Files
astrolabe/docs/manual-verification.md
T

4.2 KiB

Manual Verification Checklist

A standing memo, not a milestone. These are the things automated tests can't cover — they need a real browser, a real install, or a human eye. Run the relevant sections before a release, or after any change to the app shell, PWA config, routing, theming, or focus/keyboard behavior. Tests stay green ≠ these pass.

Offline & installable (PWA)

  • First load online, then go offline (DevTools → Network → Offline) and reload — the app boots, fonts render (no system-font fallback), a previously-opened snippet still renders.
  • Install as a standalone app (desktop install button / Android "Add to Home screen") — it installs, launches in its own window, and shows the astrolabe icon (not a generic glyph).
  • Android adaptive icon (maskable) fills the OS shape without clipping the mark.
  • Service-worker update flow: ship a new build, reload — the update-available prompt appears and applying it loads the new version (registerType: 'prompt').
  • iPad add-to-home-screen (Safari → Share → Add to Home Screen) shows the astrolabe apple-touch-icon.png, not a page screenshot or generic glyph. Phones are out of scope — iPad is the only touch surface Astrolabe targets.

Keyboard & accessibility

  • Full keyboard-only run-through: create/select/edit a snippet, open and dismiss each modal, drive the pane toggle strip and both resize handles, reach Datasets.
  • Focus is never orphaned or trapped: modals trap focus and return it to the opener on close; hiding a pane from the strip keeps focus on the toggle.
  • Visible focus ring on every interactive control, in both themes.
  • Text and UI contrast pass AA in light and dark.

Routing & view-state

  • Reload restores the view from the URL hash (#snippet-<id>, #datasets/…).
  • Browser Back/Forward moves through view-state as expected.

Theming

  • Light⇄dark flip repaints the whole app — chrome, Monaco, and the chart.
  • No placeholder styling or raw hexes leak through on any surface.

Reduced motion & feedback

  • With prefers-reduced-motion, toasts and transitions honor it (no large motion).
  • Toasts stack, auto-dismiss, and fade as specified; the live-preview busy indicator appears for slow (>~1s) renders and clears after.

URL datasets (remote data snapshot)

Needs a real network, real CORS, and real offline — tests mock the fetch.

  • Add a dataset by URL from a CORS-friendly host (e.g. a GitHub raw .csv or a vega-datasets URL) — Save shows "Fetching…", then the dataset appears profiled (rows, columns, size) with a "Fetched
  • Go offline (DevTools → Network → Offline) and reload — a snippet that references that URL dataset still renders from the local snapshot (no fetch at render time).
  • Add a URL that blocks cross-origin requests (or while offline) — the form shows a cause-specific error and a "Paste data inline instead" button that switches to an inline paste keeping the name/comment; no broken record is saved.
  • Refresh a URL dataset whose source changed — rows/size and the "Fetched" time update; refreshing while offline raises an error toast and leaves the snapshot intact.
  • Build Chart from a fetched URL dataset works (columns are known); from an unfetched URL reference the builder has no schema until Refresh.

Visual sweep of the M6 surfaces

  • Library search / sort / empty states, the storage monitor, About & Donate modals, and the busy indicator all look deliberate and behave per spec.

Driving these checks headlessly

The eye-checks above can be scripted as a headless walk-through (Playwright with the already-installed Chromium browser cache) for repeatable screenshots, alongside a live browser.

  • Select by accessible name / role / placeholder, never by CSS class. CSS-module class names are content-hashed and unstable; the component tests select the same way.
  • Reaching the Chart Builder: open Datasets from the header command button (the pane-toggle-strip Datasets button only exists once the workspace has content) → New Dataset → paste rows inline → Build Chart.