Context
#257 (delivered by PR #258) added the in-core mock host: MockPlatform (Rust) and createMockHost (JS), proven through the real dispatcher and a headless wasm-bridge.test.ts that drives the real WASM core across the JS↔SCALE↔WASM boundary. By design that test uses no real Web Worker, no iframe, and no product transport — so the highest-fidelity path is still unproven: a real product, in a real browser, talking to the real core over the production transport. Adopting the mock in a product test is also more setup than it should be (createMockHost + provider + createClient by hand).
Goal
Prove the mock host end to end in a real browser — the real truapi-server WASM core in a Web Worker, a product in an iframe connecting via the SDK's real getClientSync() sandbox path over a real MessageChannel, driven headless by Playwright — and make "switch a product to mock mode" a one-liner so product tests adopt it trivially.
Proposed shape
@parity/truapi-mock-e2e — a private (unpublished) workspace package holding the browser harness. Two topologies:
- single-page (
src/main.tsx): host + product in one page, wired with a single createMockClient() call;
- iframe (
src/host.tsx + src/product.tsx): mirrors production embedding — the host boots the core + createIframeHost; the product runs in an iframe with no mock code, connecting through getClientSync().
Dependencies resolve through the npm workspace (no machine-specific paths), so it runs anywhere the repo does.
createMockClient — a @parity/truapi-host-wasm/testing subpath export that collapses createMockHost + createWebWorkerProvider + createClient into one call, returning the product client plus the mock for assertions:
import HostWorker from "@parity/truapi-host-wasm/worker-runtime?worker";
import { createMockClient } from "@parity/truapi-host-wasm/testing";
const { client, mock } = await createMockClient(new HostWorker(), { devicePermissions: "allow-all" });
await client.system.handshake();
// ... drive the product client; assert via mock.navigations(), etc.
Scope
@parity/truapi-mock-e2e package: Vite + React harness (single-page + iframe topologies), portable workspace file: deps.
createMockClient (+ MockClient type) exported from @parity/truapi-host-wasm/testing.
- Playwright suite: (1) product-in-iframe round-trip through the real core; (2) a single-page test that executes
createMockClient at runtime. Assert on both product results and the mock's recorded oracles (e.g. navigations()).
- A
mock-e2e CI job: build the WASM + workspace packages, install Chromium, run Playwright. Runs for signal; not a required ci-status gate until it has a green baseline in CI.
- README docs for the new package and the
/testing export.
Acceptance criteria
- The suite passes headlessly with a real
Web Worker and real iframe (not a stubbed transport).
- The product reaches the core only through the SDK's real
getClientSync() sandbox path; the product contains no mock code.
createMockClient has executing runtime coverage, not just typecheck.
- No dependency on a device or a live chain; the run is deterministic and repeatable.
- The harness is dev-only / private and never enters a production build.
Gating
Stacked on #257 / PR #258 (createMockHost, the providers, and the /testing export live there)
Context
#257 (delivered by PR #258) added the in-core mock host:
MockPlatform(Rust) andcreateMockHost(JS), proven through the real dispatcher and a headlesswasm-bridge.test.tsthat drives the real WASM core across the JS↔SCALE↔WASM boundary. By design that test uses no realWeb Worker, noiframe, and no product transport — so the highest-fidelity path is still unproven: a real product, in a real browser, talking to the real core over the production transport. Adopting the mock in a product test is also more setup than it should be (createMockHost+ provider +createClientby hand).Goal
Prove the mock host end to end in a real browser — the real
truapi-serverWASM core in aWeb Worker, a product in aniframeconnecting via the SDK's realgetClientSync()sandbox path over a realMessageChannel, driven headless by Playwright — and make "switch a product to mock mode" a one-liner so product tests adopt it trivially.Proposed shape
@parity/truapi-mock-e2e— a private (unpublished) workspace package holding the browser harness. Two topologies:src/main.tsx): host + product in one page, wired with a singlecreateMockClient()call;src/host.tsx+src/product.tsx): mirrors production embedding — the host boots the core +createIframeHost; the product runs in an iframe with no mock code, connecting throughgetClientSync().Dependencies resolve through the npm workspace (no machine-specific paths), so it runs anywhere the repo does.
createMockClient— a@parity/truapi-host-wasm/testingsubpath export that collapsescreateMockHost+createWebWorkerProvider+createClientinto one call, returning the product client plus the mock for assertions:Scope
@parity/truapi-mock-e2epackage: Vite + React harness (single-page + iframe topologies), portable workspacefile:deps.createMockClient(+MockClienttype) exported from@parity/truapi-host-wasm/testing.createMockClientat runtime. Assert on both product results and the mock's recorded oracles (e.g.navigations()).mock-e2eCI job: build the WASM + workspace packages, install Chromium, run Playwright. Runs for signal; not a requiredci-statusgate until it has a green baseline in CI./testingexport.Acceptance criteria
Web Workerand realiframe(not a stubbed transport).getClientSync()sandbox path; the product contains no mock code.createMockClienthas executing runtime coverage, not just typecheck.Gating
Stacked on #257 / PR #258 (
createMockHost, the providers, and the/testingexport live there)