Skip to content

feat(mock-e2e): browser E2E harness + createMockClient testing export#261

Draft
decrypto21 wants to merge 1 commit into
feat/mock-platformfrom
feat/mock-e2e
Draft

feat(mock-e2e): browser E2E harness + createMockClient testing export#261
decrypto21 wants to merge 1 commit into
feat/mock-platformfrom
feat/mock-e2e

Conversation

@decrypto21

@decrypto21 decrypto21 commented Jul 3, 2026

Copy link
Copy Markdown

feat(mock-e2e): browser E2E harness + createMockClient testing export

Resolves #260 (the browser-E2E follow-up). Stacked on #258. Ported onto the current #104: createMockClient and the harness use the new createWebWorkerPairingHostRuntime + createProvider runtime API; e2e is green (2/2).

Draft PR. Base branch is feat/mock-platform (#258), not main. This is the top of a three-PR draft stack rooted in #104 — see PR stack, draft status & breaking changes below before reviewing.

Suggested title

feat(mock-e2e): browser E2E harness + createMockClient testing export

Summary

On top of the mock host from #258, this adds the highest-fidelity proof and the ergonomic entry point that were left as follow-ups:

  • @parity/truapi-mock-e2e — a private workspace package that drives a product against the mock host in a real browser: the real truapi-server WASM core runs in a Web Worker, the product runs in an iframe and connects via the SDK's real getClientSync() sandbox path over a real MessageChannel, and Playwright drives it headless. This is a level above the headless wasm-bridge.test.ts (which stops at the JS↔SCALE↔WASM boundary): it exercises the full production transport, with no mock code in the product.
  • createMockClient — a @parity/truapi-host-wasm/testing subpath export that collapses createMockHost + createWebWorkerPairingHostRuntime().createProvider() + createClient into one call, returning the product client plus the mock for assertions.
  • A mock-e2e CI job that builds the WASM + workspace packages, installs Chromium, and runs the Playwright suite.

The harness resolves its dependencies through the npm workspace, so it runs anywhere the repo does — no machine-specific paths.

What's in it

@parity/truapi-mock-e2e — new private (unpublished) package

A Vite + React browser harness with 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().

Files: package.json, tsconfig.json, vite.config.ts, playwright.config.ts, index.html / host.html / product.html, src/{main,host,product}.tsx, tests/e2e.spec.ts, README.md, .gitignore.

@parity/truapi-host-wasmsrc/testing.ts (new ./testing export)

createMockClient(worker, config?){ client, mock }. Composes createMockHost + createWebWorkerProvider + createClient(createTransport(...)); the caller supplies the core Worker so their bundler owns how it's produced. client is the exact object a product uses in production; mock exposes the recorded oracles for assertions.

Public API: createMockClient, MockClient.

Why it's additive (and what it proves)

  • The headless wasm-bridge.test.ts (feat: mock platform #258) proves the SCALE bridge decodes/dispatches, but with no real Web Worker, no iframe, and no product transport. This harness closes that gap: a real product, in a real browser, over the production transport, reaching the real core only through getClientSync().
  • createMockClient makes "switch a product to mock mode" a one-liner. It is dogfooded by the single-page harness and has executing runtime coverage via test (2) below — not just typecheck.

Verification

All green locally (this is the executed state, not aspiration):

  • codegen → build @parity/truapi → build @parity/truapi-host-wasm (compiles createMockClient) — pass.
  • tsc typecheck of the harness (@parity/truapi-mock-e2e) — pass.
  • make wasm / build:wasmtruapi_server_bg.wasm1.96 MB.
  • Playwright suite — 2/2 pass on Chromium: (1) product-in-iframe round-trip through the real core; (2) single-page test that executes createMockClient at runtime.
  • Two independent adversarial code-review rounds — converged clean.
  • CI mock-e2e job — not yet run in CI (branch verified locally only; CI runs it on first push).

CI

A new mock-e2e job (needs: codegen): downloads the codegen artifact, npm ci, builds @parity/truapi, installs wasm-pack 0.15.0, runs build:wasm, builds @parity/truapi-host-wasm, installs Chromium (npx playwright install --with-deps chromium), then runs the Playwright suite; the report is uploaded on failure.

Deliberately not a required gate yet: mock-e2e is omitted from the ci-status needs and results (with an explaining comment) — it runs for signal but neither gates merges nor makes the aggregate status wait on its (up to 30-min) run. Promote it into the gate once it has a green CI baseline.

Production safety

  • @parity/truapi-mock-e2e is private (unpublished) and dev/test-only.
  • createMockClient lives under the /testing subpath and only composes existing test helpers — it adds no production code path. The mock feature and createMockHost remain dev-gated exactly as in feat: mock platform #258.

Dependencies

  • The new private package adds react / react-dom / vite / @vitejs/plugin-react / @playwright/test / typescript / @types/* — all harness/dev scoped to the unpublished package and hoisted at the workspace root. No new runtime dependency for any shipped package.
  • @parity/truapi-host-wasm: one new subpath export (./testing); createMockClient imports createClient / createTransport from @parity/truapi, already a dependency — no new host-wasm dep.
  • package-lock.json refreshed for the new workspace member.

PR stack, draft status & breaking changes

This is a draft PR — the top of a three-PR draft stack. Review it against its base branch, not main:

#104  worktree-issue-96-rust-core-port  (draft)  — "feat: port Rust core runtime"
  └─ #258  feat/mock-platform  (draft)  — mock host: MockPlatform + createMockHost + mock wallet
       └─ THIS  feat/mock-e2e  (draft)  — browser E2E harness + createMockClient

The breaking changes live in #104, not in this PR. #104 is an in-flight port of the Rust core runtime that reshaped the host-facing API — truapi-platform's capability traits moved to #[async_trait] and types moved to truapi::latest. Consequences for this stack:

This PR itself introduces no breaking changes. It is purely additive: a new private (unpublished) @parity/truapi-mock-e2e package and a new @parity/truapi-host-wasm/testing subpath export. It touches no shipped runtime code path and changes no existing public API — the breaking surface is inherited entirely from the #104 base.

Docs updated: truapi-host-wasm/README.md (/testing), root README.md, CLAUDE.md layout, and the new package README.md.

Diff

  • Source / config: 19 files, +611 / −1
  • Including the package-lock.json refresh: 20 files, +2494 / −100 (the lockfile is ~1.98k of the insertions).

Reviewer guide

  • Start with js/packages/truapi-host-wasm/src/testing.tscreateMockClient (~30 lines); confirm the composition and the documented as WebWorkerHostCallbacks cast (safe: the mock builds a Required<HostCallbacks>).
  • Then js/packages/truapi-mock-e2e/src/{host,product,main}.tsx — the two topologies; note the product (product.tsx) reaches the core only through getClientSync() and contains no mock code.
  • tests/e2e.spec.ts — two tests: the iframe round-trip and the single-page createMockClient runtime coverage.
  • .github/workflows/ci.yml — the mock-e2e job, and confirm it is intentionally out of the ci-status gate/needs.
  • vite.config.ts — confirm there are no machine-specific absolute paths (deps resolve via workspace symlinks); this portability is the point of moving the harness in-repo.

What's next (follow-ups, not blockers)

  1. Drive the playground / host-playground (product-sdk) apps against the mock host — the product-sdk conversion layer end to end (the earlier "Scenario B"); separate issue.
  2. Promote mock-e2e to a required CI gate once it has a green baseline.
  3. (Base feat: mock platform #258) tighten MockHost.callbacks to Required<HostCallbacks> so the two as WebWorkerHostCallbacks casts can be dropped — fold into feat: mock platform #258's next required touch (the feat: port Rust core runtime #104 rebase).

@socket-security

socket-security Bot commented Jul 3, 2026

Copy link
Copy Markdown

@socket-security

socket-security Bot commented Jul 3, 2026

Copy link
Copy Markdown

Warning

[Security]

Socket has found a problem with the dependencies from this PR. Check the details below to solve the issue. If the affected dependency is unreachable, we still recommend you to use a patched version.

Remember: according to Parity's Security Policy, you must resolve all "Block" alerts before proceeding. It is recommended to resolve "Warn" alerts too. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
High CVE: npm vite: `server.fs.deny` bypass on Windows alternate paths

CVE: GHSA-fx2h-pf6j-xcff vite: server.fs.deny bypass on Windows alternate paths (HIGH)

Affected versions: >= 8.0.0 < 8.0.16; >= 7.0.0 < 7.3.5; < 6.4.3

Patched version: 6.4.3

From: js/packages/truapi-mock-e2e/package.jsonnpm/vite@5.4.21

ℹ Read more on: This package | This alert | What is a CVE?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Remove or replace dependencies that include known high severity CVEs. Consumers can use dependency overrides or npm audit fix --force to remove vulnerable dependencies.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/vite@5.4.21. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

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