Integration tests across the cn-dappbooster's four packages.
Does:
- Test the cross-package wiring: dApp ↔ wallet ↔ wallet-service ↔ Canton
- Drive real browser sessions with the Carpincho extension loaded
- Verify wire shapes against the documented public surfaces
- Run deterministically in CI
Doesn't:
- Test internals of any individual package (each owns its own unit tests)
- Import source from other packages — this is a strict black-box consumer
- Manage the lifecycle of Canton, wallet-service, Carpincho, or the dApp directly. Bring them up via their own
dev/startscripts before running tests; e2e just consumes their stable surfaces
This package depends on nothing in this repo at the TypeScript level. Every cross-package touch goes through one of three doors:
| Door | Default | Override |
|---|---|---|
| wallet-service HTTP | http://localhost:3010 |
WALLET_SERVICE_URL |
| Carpincho web | http://localhost:3011 |
CARPINCHO_URL |
| dApp | http://localhost:3012 |
DAPP_URL |
| Carpincho extension bundle | ../../carpincho-wallet/dist-extension |
EXTENSION_PATH |
When the four packages publish independently and the dev kit becomes a monorepo of NPM workspaces, these env-overrides let e2e target either:
- the in-tree dev stack (default),
- a
node_modules/@canton-dappbooster/*install, - a remote staging environment.
The full local stack must be running. From the repo root:
# Start the canton stack (postgres + canton + wallet-service)
npm run canton:up && npm run canton:health
# Deploy the Counter DAR
./canton-barebones/scripts/deploy-dar.sh dapp/daml/.daml/dist/quickstart-counter-0.0.1.dar
# Build the Carpincho extension
npm --prefix carpincho-wallet run build:extension
# In separate terminals:
npm run wallet:dev # terminal 1 — Carpincho web UI on :3011
npm run app:dev # terminal 2 — dApp on :3012npm --prefix dapp/e2e install
npm --prefix dapp/e2e run install:browsernpm --prefix dapp/e2e test # headless (where the extension support allows)
npm --prefix dapp/e2e run test:headed
npm --prefix dapp/e2e run test:ui # interactive Playwright UI
npm --prefix dapp/e2e run report # open the last HTML reportOr from the repo root: npm run e2e.
Boundary smoke (tests/smoke.spec.ts) — fast (<2s each):
- wallet-service
/healthresponds with the configured service - wallet-service
/wallet-service/infoexposes the dapp-api surface (10 supportedMethods, two admin endpoints, three reserved methods) - dApp loads and offers both connect paths (extension + WC fallback)
- Carpincho extension is discoverable from a dApp page via
canton:requestProvider/canton:announceProvider
/rpc spec conformance (tests/spec-conformance.spec.ts) — guards the wire shape:
ledgerApireturns the raw participant response (no{response, status}or{contracts}wrapping)ledgerApirejects non-native bodies with-32000rather than silently translating- Native ACS body shape works end-to-end against Canton
- Removed dapp-api methods (
prepareCreateParty,completeCreateParty) stay-32601 - Reserved methods (
prepareExecute,prepareExecuteAndWait,signMessage) stay-32004
Full dApp ↔ wallet flows (each walks vault setup → party create → dApp connect → action):
tests/features/sign-message/sign-message.spec.ts—signMessageround-trips a base64 signaturetests/accounts-changed.spec.ts— switching primary in Carpincho propagates to the dApp viaaccountsChangedtests/features/counter/tx-changed.spec.ts— captures the fullpending → signed → executedlifecycle duringprepareExecuteAndWait
13 tests total. All deterministic via data-testid + data-* attribute reads, no sleep guesses.
- WC fallback path (would need a real Reown project ID)
- dApp's Increment / Add user / Add viewer flows (covered manually via agent-browser; could add Playwright if we want full UI coverage)
connectedandstatusChangedare emitted by the wallet on vault lifecycle transitions but no dApp surface consumes them yet, so there is no e2e test for them.messageSignaturelifecycle events are not emitted (signMessageis request/response via the Promise; lifecycle events would have no consumer).
- One spec file per integration concern (
smoke,party-onboarding, dApp flow,spec-conformance) - Use
data-testidselectors viapage.getByTestId(...). Avoid CSS-by-position or text-only locators — they break on UI tweaks - Tests must be runnable individually (no order dependencies)
- Each test starts from a known browser context (the
contextfixture gives a fresh persistent profile per test) - Don't add
expects that depend on heuristic sleeps — useexpect.pollor wait-for assertions
Phase 1 deliberately requires the stack to be up beforehand. This keeps the boundary clean — the package isn't a sidecar deployment tool. If we later want one-command CI that brings everything up, the right move is either:
- a
globalSetupscript inplaywright.config.tsthat shells out tonpm run canton:up && …(acceptable in dev / CI) - a docker-compose meta-service that pre-stages all four packages (more invasive, monorepo-friendly)
Both can be layered later without changing tests.