T-UU4J-pumice-real-backend-e2e
State: planning/proposed · Impact: medium · Complexity: large
Move pumice’s Playwright suite off its browser mock and onto the real backend over HTTP in a
scratch root. Pumice is the first Tauri app to move, so this task also builds the shared pieces the
other Tauri apps reuse: a headless server helper and the scratchTauriApp adapter.
| Location | Role today |
|---|---|
apps/pumice/src-tauri/src/api/transport/http/generated.rs | Ontogen-generated Axum routes over the API handlers |
apps/pumice/src-tauri/src/lib.rs | The Tauri setup serves those routes on a hardcoded 127.0.0.1:4321 with permissive CORS; there is no headless bin |
apps/pumice/src-nuxt/app/generated/transport.ts | The web build already has an HTTP transport |
apps/pumice/src-nuxt/app/plugins/browser-mock.client.ts, app/utils/browser-mock.ts | Dev-only IPC stand-in with fixtures; installed when import.meta.dev and no Tauri |
apps/pumice/src-nuxt/tests/e2e/ | 2 Playwright specs against bun run dev on 18134 and the mock |
apps/pumice/moon.yml | No e2e task |
apps/pumice/src-tauri/src/commands/data.rs | Resolves state through fleet_tauri::AppDirs::resolve(app) |
dev-ports.yaml | pumice-http 18133 (unused by the code), pumice-e2e 18134 |
Proposed
Section titled “Proposed”A pumice-server bin builds pumice state from fleet dirs with no Tauri window and serves the
generated routes, a resolved-paths endpoint and the static web build on one port. The server main
is a shared Rust helper (in packages/rust/fleet-tauri or a new packages/rust crate): given an
app router and its state, it takes the port from args or env, adds the resolved-paths route, serves
the SPA and handles shutdown. A scratchTauriApp adapter in @sksizer/app-harness launches any
bin built on that helper. The pumice suite runs through it, under a moon e2e task. The desktop app
reads its HTTP port from dev-ports.yaml’s pumice-http instead of 4321.
Approach
Section titled “Approach”- Split state construction out of the Tauri
setupso a bin can build it from fleet dirs, without anAppHandle. - Write the shared server helper; add the resolved-paths route it serves.
- Add the
pumice-serverbin on the helper. - Add
scratchTauriAppto the harness. - Port the Playwright suite; replace fixture data with seeded state in the scratch root. Add the
moon
e2etask. - Delete the mock if no prototype or story uses it.
| Area | Note |
|---|---|
apps/pumice/src-tauri/ | State split, pumice-server bin |
apps/pumice/src-nuxt/ | Suite, mock removal |
apps/pumice/moon.yml | E2e task |
packages/rust/ | Shared headless server helper |
packages/ts/app-harness/ | scratchTauriApp |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1:
moon run pumice:e2epasses againstpumice-serverin a scratch root, with the isolation check on. - AC-2: No e2e spec imports or relies on
browser-mock. - AC-3: The desktop app still serves its HTTP API, on the
pumice-httpport. - AC-4: The helper and
scratchTauriAppcarry no pumice-specific names, and their READMEs show how another Tauri app adopts them.
Out of scope
Section titled “Out of scope”- Desktop smoke.
- Other Tauri apps (
T-KOTJ,T-AAR2,T-TLET).
Dependencies
Section titled “Dependencies”T-NNAGso pumice state followsFLEET_ROOT.T-4HBCfor the harness.
Discovery context
Section titled “Discovery context”- Pumice already has the HTTP half; the gap is a headless entry point and the e2e wiring.
- Agentpants has the same shape (generated Axum routes served in-app on a hardcoded port), so the helper is written for both from the start.
Depends on
Section titled “Depends on”T-NNAG, T-4HBC