Uh oh!
There was an error while loading. Please reload this page.
test(wallet): Tier-2 browser-signing e2e (Playwright + mock provider on anvil) - #380
Conversation
…on anvil) Add a headless, deterministic Tier-2 e2e harness that drives the real bridge page (bridgePage.ts) in chromium with an injected mock window.ethereum. eth_sendTransaction is delegated to Node via page.exposeFunction(__glSign), where a viem local account (anvil dev key) actually signs+broadcasts to an ephemeral anvil, so the full loop runs for real: bridge + page JS + session daemon + chain, with zero human/extension. Lanes (all green on anvil): - S1 connect/status/disconnect (descriptor 0600, /api/ping, teardown) - S2 validator-join --wallet browser signs + mines against a recording StakingStub, asserted via real receipt + on-chain callCount - S4 session reuse: two sequential joins over one daemon/tab - S5 config default walletMode=browser; --wallet keystore overrides - S6 user-reject (4001) + tab-closed fail-fast (short env timeouts) Lane B (S3, IC deploy on Docker localnet) is deferred as a nightly follow-up: describe.skip guarded by GENLAYER_E2E_LOCALNET. Prod-safe support changes: GENLAYER_E2E_* env overrides for the timing constants (unset in prod) and a GENLAYER_E2E_NO_OPEN guard so the daemon does not auto-open a system browser under test. New e2e-wallet.yml CI job (informational, not a required gate initially). Playwright specs are kept out of the vitest glob so test:coverage is unaffected.
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Uh oh!
There was an error while loading. Please reload this page.
What
Adds the Tier-2 browser-wallet signing e2e harness for genlayer-cli, per the design doc. It drives the real daemon bridge page (
src/lib/wallet/bridgePage.ts) in a headless chromium with an injected mockwindow.ethereum, and delegates signing to Node viapage.exposeFunction("__glSign", …)where a viem local account (anvil dev key) actually signs + broadcastseth_sendTransactionto an ephemeral anvil, returning a real tx hash.So the full loop runs for real — bridge + served page JS + session daemon + real chain — with zero human and zero MetaMask.
How the mock works
e2e/fixtures/mockProvider.ts—installMockProvider({address, chainIdHex, behavior})returns an init-script string installed viapage.addInitScript(...)beforepage.goto()(beats the injection race). Behaviors:approve|reject(4001) |wrong-network(4901).eth_sendTransaction→window.__glSign.e2e/helpers/bridgePage.ts— launches chromium, wires__glSignto a viemsendTransactionon anvil, injects the mock, and drives connect.e2e/fixtures/chain.ts—startAnvil()boots anvil on a random port and deploys the recordingStakingStub.e2e/fixtures/cli.ts— runsdist/index.jsunder a scratchHOMEwith a seeded custom-network config (chain-id / rpc / staking → the anvil + stub) soensureChain()matches;spawnConnect()scrapes the printed session URL.Lanes (all green on anvil, ~16s, serial
workers:1)0600{pid live, port, token, address, chainId},/api/ping200, "Connected as …", teardown removes descriptor + pid.staking validator-join --wallet browser— page auto-signs → asserted via a real receipt + on-chain stubcallCount.walletMode=browser— barevalidator-joinsigns via session;--wallet keystoreoverrides (keystore path, no enqueue).page.close()→ stale heartbeat → fail-fast "tab appears to be closed"). ShortGENLAYER_E2E_*timeout overrides keep these in seconds.Staking stub
e2e/fixtures/StakingStub.sol(+ committed compiledStakingStub.json) is a ~10-line recording stub:validatorJoin()/validatorJoin(address)are payable, record the call (callCount,lastOperator/Validator/Amount), and emit theValidatorJoin(operator, validator, amount)event the CLI decodes. It proves the sign→broadcast→receipt loop only — no consensus.Deferred (nightly follow-up)
localnet:describe.skip, guarded byGENLAYER_E2E_LOCALNET, documented ine2e/lane-b-deploy.e2e.ts. Bare anvil has no GenVM/consensus.Prod-safe support changes
sessionConstants.ts—GENLAYER_E2E_{LONG_POLL,HEARTBEAT_DEAD,CONNECT_TIMEOUT}_MSoverrides; unset/invalid → production defaults unchanged.browserBridge.ts— skipopenUrlwhenGENLAYER_E2E_NO_OPENis set (harness drives its own chromium); production unaffected.CI
New
.github/workflows/e2e-wallet.yml(distinct name from the syncede2e.yml): ubuntu + node 20 →npm ci→ build → foundry-toolchain →playwright install --with-deps chromium→npm run test:e2e. Informational — keep off required checks until stable, then promote.How to run
Verification
npm run test:e2e→ 9 passed, 1 skipped (Lane B), stable across 3 runs.npm run test:coverage(Tier-1 vitest) → 733 passed; Playwright specs excluded from the vitest glob.npm run buildclean;tsc --noEmit= 32 errors (pre-existing baseline, zero new).