Skip to content

test(e2e): full Playwright/WebKit suite over a mocked Tauri bridge#7

Merged
guuse merged 1 commit into
mainfrom
feat/e2e-suite
Jun 3, 2026
Merged

test(e2e): full Playwright/WebKit suite over a mocked Tauri bridge#7
guuse merged 1 commit into
mainfrom
feat/e2e-suite

Conversation

@guuse

@guuse guuse commented Jun 2, 2026

Copy link
Copy Markdown
Owner

What

A full end-to-end suite that walks every primary user flow on every PR — without any network, auth, SSO, or platform calls. This directly targets the recurring problem of features breaking when new ones land.

Playwright drives the real production bundle (vite build --mode e2evite preview) on WebKit (the engine the Tauri webview actually ships). The store, hooks, usecases, deterministic packer, timeline and leftover sidebar all run for real — only the backend is faked.

How it works

The whole backend reduces to two seams, both intercepted in the browser by a stateful in-memory fake (tests/e2e/bridge/fakeBridge.ts):

  • window.__TAURI_INTERNALS__.invoke — Simplicate (simplicate_request), Gemini, keychain, and the plugin:fs|* / plugin:path|* IPC the storage layer rides on.
  • window.fetch — GitHub, Linear, Google Calendar, Google OAuth.

State is mutable: booking adds an hour entry a later week-read returns (blue), submitting locks the week read-only, delete/edit mutate. So flows are tested by cause→effect, not by asserting a call was made.

  • Auth is always seeded, never driven through the UI (SSO is never performed). The Zustand store is exposed only in the e2e build (import.meta.env.MODE === 'e2e') and is inert in dev/prod.
  • Determinism via a frozen clock (page.clock) + fixtures keyed to it; timezone pinned to Europe/Amsterdam.
  • Selectors prefer Dutch role/text; data-testid added only to dynamic items.

See docs/adr/0005-e2e-playwright-mocked-tauri-bridge.md for the full rationale and the alternatives considered (tauri-driver, vitest browser mode, Chromium).

Flows covered (20 specs, all green locally)

restore → existing hours · verwerk day · verwerk week · timeline edit + delete-from-timeline · boeken (+ a regression guard that a failed booking surfaces the real Simplicate error, not "Boeken mislukt") · leftover dismiss/book · indienen (+ submitted week is read-only on load) · clear day/week · settings · no-history warning · entry edit/delete · week navigation + connection banner.

CI

New e2e job in ci.yml (parallel to the unit/coverage job): installs WebKit + system deps, builds the prod bundle, runs the suite, uploads the Playwright report/trace on failure.

⚠️ One manual step: mark the E2E (Playwright / WebKit) check as required in branch protection so a red e2e blocks merge — that's a GitHub setting, not code.

Notes

  • Unit suite still green; coverage unchanged (the e2e-only store seam is v8 ignore'd).
  • vitest now excludes tests/e2e/**.

🤖 Generated with Claude Code

Adds an end-to-end suite that walks every primary flow on every PR without
any real network, auth, SSO, or platform calls. Playwright drives the real
prod bundle (vite build --mode e2e -> preview) on WebKit (the engine the
Tauri webview ships). A stateful in-memory fake intercepts the two backend
seams — window.__TAURI_INTERNALS__.invoke (Simplicate, Gemini, keychain,
plugin:fs/path) and fetch (GitHub, Linear, Google Calendar, OAuth) — so
booking adds an entry a later read returns, submitting locks the week, etc.

Coverage: restore/existing-hours, verwerk day + week, timeline edit + delete,
boeken (+ real-error regression guard), leftover dismiss/book, indienen
(+ submitted read-only), clear day/week, settings, no-history warning,
entry edit/delete, week nav + connection banner. 20 specs, all green.

- Auth is always seeded (no UI login); the store is exposed only in the e2e
  build (import.meta.env.MODE === 'e2e'), inert in dev/prod.
- Determinism via a frozen clock + fixtures keyed to it; WebKit only.
- New required-able `e2e` job in ci.yml; data-testids added to dynamic UI.

See docs/adr/0005-e2e-playwright-mocked-tauri-bridge.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 99.21% (🎯 95%) 2670 / 2691
🔵 Statements 98.64% (🎯 95%) 3050 / 3092
🔵 Functions 98.24% (🎯 95%) 784 / 798
🔵 Branches 96.08% (🎯 95%) 1717 / 1787
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/store/appStore.ts 100% 100% 100% 100%
src/ui/components/DayTimeline.tsx 99.3% 92.42% 100% 100% 141
src/ui/components/LeftoverSidebar.tsx 85.71% 76.47% 88.23% 88.23% 39, 58-59, 114
src/ui/components/MonthPickerPopup.tsx 100% 100% 100% 100%
src/ui/components/SearchableSelect.tsx 100% 97.22% 100% 100%
src/ui/components/WeekDayList.tsx 100% 100% 100% 100%
src/ui/pages/BookingModal.tsx 100% 98.86% 100% 100%
Generated in workflow #21 for commit 4b20c8c by the Vitest Coverage Report Action

@guuse guuse merged commit 2c5fa8e into main Jun 3, 2026
2 checks passed
@guuse guuse deleted the feat/e2e-suite branch June 3, 2026 07:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant