feat(tester): SIWS test-wallet harness (//Alice) + runner fix#62
Merged
feat(tester): SIWS test-wallet harness (//Alice) + runner fix#62
Conversation
Injects a synthetic Polkadot-JS extension in the browser, backed by a real sr25519 keypair (//Alice), so the stadium-tester Skill can exercise SIWS-gated write flows in mock-mode preview URLs without a human signing step. Phase 1 spec §6 called this out as the biggest agentic-velocity blocker — six of the thirteen Phase 1 issues had Playwright-untestable write paths. Client: - testWalletInjection.ts: registers window.injectedWeb3['polkadot-js'] with a lazy enable() that derives //Alice and signs with pair.sign(). Double-gated: VITE_USE_TEST_WALLET=true AND !import.meta.env.PROD. Prod builds DCE the injection entirely (verified — __TEST_WALLET_ENABLED__ string not present in any dist/*.js chunk even with the flag set at build time). - main.tsx imports the injection at the top so it registers before React mounts and before AdminPage's 5s window.injectedWeb3 poll starts. - mockWinners.ts: Alice's SS58-42 address added as a team member on plata-mia-15ac43 so team-gated flows pass the client-side team check. - @polkadot/keyring added as explicit dep (was transitive via api/extension-dapp). Tester skill: - run-playwright.mjs: fixes a latent bug where specs/configs in /tmp couldn't resolve the bare '@playwright/test' specifier (ESM walks up from the importer's dir; /tmp has no node_modules). Rewrites spec imports and the generated config to use the absolute path under client/node_modules. This is why recent PRs' Playwright scenarios all shipped as unchecked boxes — the runner had never actually worked end-to-end. - @playwright/test promoted from "setup.sh installs on each machine" to an explicit devDep so fresh clones get it via npm install. - Forwards VITE_USE_TEST_WALLET through the Playwright spawn env. - SKILL.md: Test-wallet mode section documenting when/how to use it, which flows still can't run (admin-approval paths with no mock-mode branch in api.ts), and the hard prod-prohibition. - AGENT_GUIDE.md: Vercel Preview config note — VITE_USE_TEST_WALLET + Alice in VITE_ADMIN_ADDRESSES on Preview only, never Production. Verified locally: - cd server && npm test → 66/66 pass. - cd client && npm run build → clean. - harness check via real runner: 3/3 tests pass against http://localhost:8080 (VITE_USE_MOCK_DATA=true VITE_USE_TEST_WALLET=true npm run dev) — flag sentinel set, injection registered, enable() yields canonical Alice address 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY and produces a 0x-prefixed sr25519 signature. - prod-URL guard: exit 3 on https://stadium.joinwebzero.com, unchanged. - prod-build safety: VITE_USE_TEST_WALLET=true npm run build produces a dist with zero references to the injection sentinel — DCE works. Pre-existing lint (98 problems on develop, none introduced here) not fixed here — separate cleanup PR.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Apr 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Unblocks autonomous Playwright verification of SIWS-gated write flows. Injects a synthetic Polkadot-JS extension backed by the well-known
//Alicedev keypair sostadium-testercan sign in a headless browser. Phase 1 spec §6 flagged this as the biggest agentic-velocity blocker — six of the thirteen Phase 1 issues had write flows the tester couldn't exercise.Also fixes a latent bug in the tester runner that's why recent PRs (#45 #46 #47 etc.) all shipped with unchecked Playwright boxes in their test plans — the runner had never actually worked end-to-end from /tmp.
What's in the diff
Client:
client/src/lib/testWalletInjection.ts(new) — registerswindow.injectedWeb3['polkadot-js']synchronously at module load;enable()lazily derives//Alicevia@polkadot/keyringand returns real sr25519 signatures. Double-gated onVITE_USE_TEST_WALLET === 'true' && !import.meta.env.PROD— a prod build DCEs the whole block.client/src/main.tsx— imports the injection at the top so it registers beforeAdminPagestarts pollingwindow.injectedWeb3.client/src/lib/mockWinners.ts— Alice's SS58-42 address seeded as a team member onplata-mia-15ac43so team-gated flows pass the client-side team check.client/package.json—@polkadot/keyringpromoted to explicit dep (was transitive);@playwright/testpromoted to explicit devDep so fresh clones get it fromnpm installinstead ofsetup.sh.Tester skill:
.claude/skills/stadium-tester/scripts/run-playwright.mjs— fixes the runner. Specs and the generated config both live in/tmp, but they import@playwright/testas a bare specifier; ESM walks up from the importer's directory and/tmphas nonode_modules, so resolution fails. The runner now rewritesfrom '@playwright/test'in the spec and the generated config to the absolute pathclient/node_modules/@playwright/test/index.mjs. Also forwardsVITE_USE_TEST_WALLETthrough the Playwright spawn env..claude/skills/stadium-tester/SKILL.md— new "Test-wallet mode" section documenting when/how to use the harness, and what still can't run (webzeroApprove/requestChanges/confirmPaymenthave no mock-mode branch inapi.ts, so they stay SKIPPED pending separate mock coverage).client/.env.example,docs/AGENT_GUIDE.md— env vars + Vercel Preview-only config guidance.Guardrails
VITE_USE_TEST_WALLET=trueleaks into a prod build, the!import.meta.env.PRODcheck makes the whole injection statically false, so Rollup DCEs it.VITE_USE_TEST_WALLET=true npm run buildproduces a dist with zero references to the__TEST_WALLET_ENABLED__sentinel — confirmed by grepping every file indist/assets/*.js.VITE_ADMIN_ADDRESSESonly via Vercel Preview env var (dashboard action, not code). Production'sVITE_ADMIN_ADDRESSESstays unchanged; the server'sADMIN_WALLETS/AUTHORIZED_SIGNERSon prod must not include her either.run-playwright.mjsstill refusesstadium.joinwebzero.comwith exit 3.BYPASS_ADMIN_CHECKunchanged.Verification
Local end-to-end against
http://localhost:8080withVITE_USE_MOCK_DATA=true VITE_USE_TEST_WALLET=true npm run dev:enable()returns the canonical SS58-42 Alice address5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQYandsignRawproduces a0x-prefixed sr25519 signature that verifies through@polkadot/util-crypto.signatureVerify— i.e. if this were pointed at a real server (follow-up), the same signatures would pass the real auth middleware.Lint baseline is broken on
develop(confirmed viagit stash && npm run lint— same 98). The only GitHub Actions workflow isclaude.yml; no CI has ever enforcednpm run lint. Not fixed here — separate cleanup PR.Vercel Preview config needed (dashboard, outside code)
Before this harness is useful on preview URLs:
VITE_USE_TEST_WALLET=trueon the Preview env (not Production).5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQYtoVITE_ADMIN_ADDRESSESon the Preview env (not Production).Without these, SIWS-gated scenarios targeting a preview URL still get
SKIPPED (needs-auth-harness)— the harness is inert without the build-time flag.Out of scope (follow-ups)
webzeroApprove,requestChanges,confirmPaymentinclient/src/lib/api.tshave no mock branch — they always hit the real API. Harness doesn't help those. Separate small PR to add mocks, or keep them SKIPPED.AUTHORIZED_SIGNERSon a staging Railway env + seeding team_members in staging Supabase would let the tester hit a real backend. Needs a staging env to exist first.develop. 98 problems. Separate cleanup PR.Test plan
Automated (already passed locally):
cd server && npm test→ 66/66.cd client && npm run build→ clean.stadium.joinwebzero.com.VITE_USE_TEST_WALLET=true npm run build) DCEs the injection — grep__TEST_WALLET_ENABLED__indist/assets/*.jsreturns 0 hits.Against the Vercel Preview built from this branch (after dashboard env is set):
/m2-program/plata-mia-15ac43Updates tab visible; "Post update" button visible when connected as the injected Alice wallet.signRaw(no human prompt) → new update appears at top of list (mock-mode in-memory write)./admin→ injected Alice is auto-selected as admin account; Programs table renders.Non-code (manual before next use):
VITE_USE_TEST_WALLETset on Vercel Preview only.VITE_ADMIN_ADDRESSESon Vercel Preview only.