Files
whisper_web/tests/offline.md
T
Lucas WintherandClaude Fable 5 9f39a82982 WIP: M3 PWA/offline implementation, M4 auth (backend + frontend), D-013 faster-whisper
- M3: hand-rolled service worker (precache + runtime /ort caching), precache
  manifest injection, SW registration/update toast, manifest + generated icons,
  production build script, offline indicator in ModelPicker (D-005/D-007)
- M4 backend: bun:sqlite users/sessions (D-009), Passport local strategy behind
  connect-compat adapter (D-008), /api/auth routes wired into dev+prod serving,
  Bun.password Argon2id, 38 auth tests
- M4 frontend: AuthForms + useAuth + framework-free authClient, session-aware
  header, anonymous-first fail-silent offline handling, 18 client tests
- D-013: server engine (M5) will use faster-whisper via Python sidecar;
  browser side stays Transformers.js (CTranslate2 has no WASM build)
- bun test: 83 pass / tsc --noEmit clean
- Note: M3 doc closeout (WorkBreakdown/Architecture/tests/offline.md) still in
  flight from a background agent; follow-up commit will finish docs

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-10 04:02:28 +02:00

4.5 KiB

Manual offline verification (M3)

The service worker, precache injection, and production serving are covered by unit tests and curl smoke tests; actual offline behavior (SW lifecycle, Cache Storage, airplane mode) can only be exercised in a real browser. This is that procedure. Re-run it after any change to src/pwa/*, scripts/build.ts, or the serve paths in src/index.ts.

Prerequisites

  • Chrome or Edge (WebGPU + full PWA support; Firefox works for the WASM/offline parts but not WebGPU as of mid-2026).
  • Production build served locally:
    bun run build
    bun run start        # NODE_ENV=production bun src/index.ts → http://localhost:3000
    
    Service workers require a secure context; http://localhost qualifies.

1. First visit — install + precache

  1. Open http://localhost:3000/ in a fresh profile (or after DevTools → Application → Storage → "Clear site data").
  2. DevTools → Application → Service Workers: /sw.js should be activated and running. No reload prompt should appear on this first install (register.ts only reloads after the user accepts the update toast).
  3. Application → Cache Storage: expect
    • whisper-shell-<version> — the precached app shell: /, the hashed chunk-*.js / chunk-*.css, /inference.worker.js, /manifest.webmanifest (+ a hashed copy), /icons/icon-192.png, /icons/icon-512.png (+ a hashed 192 copy). The <version> matches the "cache version" printed by bun run build.
    • whisper-runtime-<version> appears only after step 2 below (it holds /ort/* fetched during model load).
  4. The ModelPicker status line should read "The app is cached for offline use. Load a model once to make it available offline too."
  5. Installability: the browser should offer an install icon in the address bar (manifest + SW + icons). Optional: install and confirm standalone display.

2. Load a model once (online)

  1. Select a model (tiny.en is fastest) and let it load fully.
  2. Application → Cache Storage now also contains:
    • transformers-cache — Whisper weights (.onnx, config/tokenizer JSON), written by Transformers.js itself, never touched by our SW (D-005).
    • whisper-runtime-<version> — /ort/ort-wasm-simd-threaded*.{wasm,mjs} (onnxruntime-web loads one variant per backend, e.g. the .jsep build for WebGPU; the worker points wasmPaths at /ort/ so nothing hits the jsdelivr CDN).
  3. The model now shows the "available offline" badge in ModelPicker, and the status line switches to "Offline ready — …".

3. Go offline and transcribe

  1. DevTools → Network → throttling Offline (or OS airplane mode — stronger, also proves nothing relies on localhost). Optionally also stop bun run start to prove the app survives our server being down.
  2. Reload the page. The app shell must render normally (served from whisper-shell-*, cache-first). Also try a deep link like http://localhost:3000/foo — the SW falls back to the cached shell for navigations.
  3. Load the previously-downloaded model. It must become ready with no network (weights from transformers-cache, ort runtime from whisper-runtime-*). The DevTools Network tab should show every request answered by the service worker / cache, zero failed fetches escaping to the network.
  4. Drop a local audio file and confirm a complete transcription offline.
  5. Still offline, confirm a not-downloaded model fails gracefully (error surfaced, app usable) rather than hanging.

4. Update flow (toast)

  1. Back online, with the old tab still open: make any visible change (e.g. edit a string in src/App.tsx), then bun run build and restart bun run start. The cache version in sw.js changes.
  2. Reload the tab once so the browser re-checks /sw.js (served Cache-Control: no-cache). When the new SW reaches "installed/waiting", the toast "A new version of Whisper Web is available." appears.
  3. "Later" dismisses it; the old version keeps running.
  4. "Reload" posts SKIP_WAITING, the new SW activates, and the page reloads itself once. After activation, Cache Storage must contain only the new whisper-shell-* / whisper-runtime-* pair — old versions deleted — while transformers-cache is left intact (model still "available offline").

Recording the result

When this passes in a real browser, flip the [~] offline-verification item in WorkBreakdown.md M3 to [x] and note browser + version here.

  • Verified on: browser/version, date