feat: expand e2e coverage with new specs and 3-layer transaction verification#393
Open
LautaroPetaccio wants to merge 2 commits into
Open
feat: expand e2e coverage with new specs and 3-layer transaction verification#393LautaroPetaccio wants to merge 2 commits into
LautaroPetaccio wants to merge 2 commits into
Conversation
… 3-layer transaction verification
Why
- Several critical-path flows had no e2e coverage: SetupPage (`/auth/setup`),
production routing under `dapps-onboarding-to-explorer=true`, NFT/MANA/generic
`eth_sendTransaction` request types, and OAuth callback edge cases.
- The existing suite mocked the auth-server `/v2/requests/**` endpoints, so the
request-types specs never exercised real recover/outcome behaviour.
How
- New helpers
- `injectFullSession` generates a real wallet keypair + AuthIdentity per test
so signatures pass auth-server verification.
- `createAuthServerRequest` POSTs to the real auth-server at
auth-api.decentraland.zone with the auth-chain in the body (the SIGNER +
ECDSA_EPHEMERAL links), matching how dapps actually create requests.
- `captureWalletTransactions` exposes `__e2eRecordTx` to the mock provider so
`eth_sendTransaction` submissions are journalled in Node for assertions.
- `pollForOutcome` polls `GET /requests/{id}` (204 while pending, 200 with
`{sender,result}` once submitted) to verify the dapp reported the outcome.
- Three Playwright projects
- `local` — fast, mock-driven, runs against the local Vite preview.
- `real-auth` — runs request-types specs against decentraland.zone/auth + the
live auth-server. Only the wallet is mocked; everything else is real.
- `real-oauth` — nightly-only spec for the full Magic + Google OAuth round-
trip; auto-skips without `E2E_GOOGLE_EMAIL`/`E2E_GOOGLE_PASSWORD`.
- request-types specs verify three layers
1. Display: decoded UI matches encoded tx data (e.g. "Confirm 5 MANA Tip for").
2. Forwarding: tx the dapp forwards to the wallet on Allow is byte-equal to
the tx params POSTed to the auth-server.
3. Outcome: auth-server records the tx hash under the connected wallet.
- Mock provider stubs `eth_sendTransaction`/`eth_sendRawTransaction` with a
deterministic fake hash to avoid real broadcasts.
Adds 32 new tests across 11 spec files. All `local` and `real-auth` specs pass;
`real-oauth` is wired but skips without test credentials.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
Why
The existing Playwright suite is mature for happy-path login flows, but several critical surfaces had no e2e coverage:
/auth/setup(the newSetupPageregistered atsrc/main.tsx:88) had zero tests, even though it's a real onboarding path.dapps-onboarding-to-explorer = truewas only implicitly exercised — no spec asserted the URL the user lands on after login.eth_sendTransactionrequests inRequestPage.tsxbranch three ways (NFT transfer, MANA transfer, generic fallback) and none of them were tested.accountsChanged/chainChanged/disconnect), and cached-session corruption were uncovered.A second, structural gap: every existing spec mocked the auth-server (
/v2/requests/**). That meant no test ever exercised real recover/outcome behaviour — the dapp's HTTP contract with the auth-server was never validated end-to-end.This PR fills both gaps in one branch.
How
1. New helpers in
e2e/helpers/setup.tsinjectFullSession(context)viemkeypair per test and uses@dcl/crypto'sAuthenticator.initializeAuthChainto produce a structurally validAuthIdentity. Pre-populatesdecentraland-connect-storage-keyand the SSO storage key so the dapp restores the session on first load. The ephemeral key is real, so any laterAuthenticator.signPayloadproduces a signature that passes server-side ECDSA verification.createAuthServerRequest({method, params, identity?})POST https://auth-api.decentraland.zone/requeststo mint a realrequestId. Foreth_sendTransactionit includes the auth-chain (SIGNER+ECDSA_EPHEMERAL) in the request body (not headers — that was the discovery that unblocked these tests).captureWalletTransactions(context)window.__e2eRecordTxso the mock provider'seth_sendTransaction/eth_sendRawTransactioncases journal every submission into a Node-side array. Tests assert on it after clicking Allow.pollForOutcome(requestId)GET /requests/{id}(the auth-server returns204 No Contentwhile pending,200with{sender, result}once the dapp posts the outcome). Mirrors the pattern fromauth-e2e-testsso behaviour is consistent.mockCatalystDeployRoute,mockNewsletterRoute,mockReferralRouteSetupPagedeploy path, with body-capture for assertions.2. Three Playwright projects (
playwright.config.ts)local(default)localhost:5174real-authhttps://decentraland.zone/auth+ liveauth-api.decentraland.zonereal-oauthreal-auth+ real Google OAuthE2E_GOOGLE_EMAIL/E2E_GOOGLE_PASSWORDwebServer.timeoutwas bumped from 30s to 180s (Vite cold start was timing out).SKIP_WEBSERVER=1env guard added so projects that target deployed dapps don't spin up a local server.3. Mock provider extended (
e2e/fixtures/ethereum-provider.ts)eth_sendTransactionandeth_sendRawTransactionnow:{method, params, ts}viawindow.__e2eRecordTx(no-op if not registered).0x+'ab'.repeat(32)).This means tests can verify the dapp's tx forwarding without actually broadcasting on Polygon — broadcasting would either cost real money or clutter the testnet.
4. Three-layer verification for request-types specs
Each
request-types-*spec checks:"5 MANA"after decoding ourtransfer(addr, 5e18)payload.)expect(txLog[0].params[0]).toMatchObject(txParams).)pollForOutcomereturns{sender, result}.)Together these catch: decoder regressions, accidental tx mangling, missing outcome submission, wrong sender reporting, dropped recover calls.
What's new
11 new spec files, 32 new tests:
setup-flow.spec.ts/auth/setupvalidation, deploy, newsletter, referral, error UIfeature-flag-onboarding-to-explorer.spec.tswallet-runtime-events.spec.tsaccountsChanged/chainChanged/disconnectmid-sessionotp-edge-cases.spec.tscached-session-edge-cases.spec.tssetItemsocial-callback-edge-cases.spec.ts/callbacknavigation,server_error, malformed staterequest-types-sign-message.spec.tsdcl_personal_signauto-sign + verification-code branchesrequest-types-generic-transaction.spec.tseth_sendTransactiongeneric fallback viewrequest-types-mana-donation.spec.tseth_sendTransactiondecoded as MANA transferrequest-types-nft-gift.spec.tseth_sendTransactiondecoded as ERC721 transferFrommagic-google-real-oauth.spec.tsTrade-offs and gotchas
real-authspecs need the dapp deployment to be reachable. They usedecentraland.zone/authandauth-api.decentraland.zone; CI should run them on a separate job that doesn't need the local Vite server.toaddress matters. Real DCL contract addresses (e.g. the canonical MANA token) live indecentraland-transactions' registry, which routes the dapp through the meta-tx path. The transaction specs deliberately use a clearly-random address (0x1111...1111) so the dapp takes the regulareth_sendTransactionpath that our journal observes.to, the on-chaintokenURIlookup fails andRequestPagefalls back fromWALLET_NFT_INTERACTIONtoWALLET_INTERACTION. The spec accepts either terminal Allow CTA. To assert the actual NFT view, a real Decentraland Wearables contract on Amoy would be needed.localregression. All 26 new local-project tests + the 76 existing tests pass withCI=true npx playwright test --project=local.Test plan
CI=true npx playwright test --project=local --workers=1passes (full local-project regression).SKIP_WEBSERVER=1 npx playwright test --project=real-auth --workers=1passes (5 tests against live dev auth-server).SKIP_WEBSERVER=1 npx playwright test --project=real-oauthauto-skips without env vars.E2E_GOOGLE_EMAIL+E2E_GOOGLE_PASSWORDand run--project=real-oauthonce headed to verify the OAuth flow renders correctly.e2e/README.mdfor project descriptions, env-var requirements, and known caveats.