Mocks & Data Providers
Playwright tests only mock the services we own. Everything else (Next.js pages, wagmi, on-chain contracts) behaves as in production. The mock entry point is dapp/e2e/playwright/mocks/index.ts, which re-exports the AI provider utilities and the chain-portfolio shims.
AI chat + MCP tooling
mocks/ai-provider/ai-provider.mock.ts installs a single route handler that only intercepts POST /api/chat. Everything else (/api/gate-access, /api/token-status, /api/mcp, etc.) falls back to the real backend even in tests.
Request flow
1. Allowlist check
When the route sees /api/chat, it makes sure the pathname is not part of the allowlist
defined in e2eEnv.mcpEndpoint or other critical endpoints. Everything else is ignored.
2. Payload inspection
The mock parses request.postData(). If JSON parsing fails, it returns a 400 with a helpful error.
3. Handler execution
The request is turned into a ResponseContext (user message, body, URL, MCP caller). The active handler (default or custom) decides what text to stream back.
4. SSE streaming
The reply is streamed as Server-Sent Events that mirror the Vercel AI message protocol
(start, text-delta, finish, [DONE]).
If you need custom AI behaviour for a spec, pass handler: composeHandlers(…) to installAIMock(). This keeps the SSE plumbing in one place.
Portfolio + Alchemy mocks
Asset-heavy pages (like /portfolio) rely on two layers:
- Chain-portfolio mock (
mocks/chain-portfolio/chain-portfolio.mock.ts) — intercepts internal endpoints (/api/portfolio/assets,/api/assets, etc.) and returns paginated ERC-20/721/1155 datasets keyed bychainId. - Alchemy mock (
mocks/chain-portfolio/alchemy-portfolio.mock.ts) — intercepts real Alchemy RPC / REST calls when the app fetches token balances or NFTs directly from Alchemy URLs.
Define the dataset
Build aPortfolioDataset object mapping chainId → { erc20, erc721, erc1155 }. Each asset type has strongly typed fields (symbol, decimals, tokenId, image, etc.).Install mocks inside the spec
await installPortfolioAlchemyMock(page, { dataset, debug: true });Add installChainPortfolioMock if the page uses first-party endpoints. Both helpers accept debug flags and route patterns.
Run the flow
Call the portfolio helpers (selectNetworks, expandTokenSection, expectGridRows, etc.). They wait for the mocked endpoints to settle (grid vs empty state vs loading).Mock response details
- The chain-portfolio mock inspects query params for
tokenType,chainId,address,page, andcursor. Missing fields triggerroute.fallback()so real API routes stay untouched. - Pagination is deterministic: page size defaults to 50 but can be overridden.
- The Alchemy mock inspects the hostname (
eth-mainnet,eth-sepolia, etc.) to infer the chain. For NFT endpoints it handlespageKeypagination. - ERC-20 balances are normalised to hex using
normalizeErc20Balance, mimicking Alchemy’stokenBalanceshape.
Never intercept endpoints that mutate user data (e.g. /api/gate-access). The mocks already maintain an allowlist to prevent accidental overrides.
With mocks in place, the reusable flows tie everything together. Proceed to the next page for a catalogue of those helpers.