Skip to Content
Welcome to RitoSwap's documentation!
dAppPlaywrightMocks & Data Providers

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.

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:

  1. 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 by chainId.
  2. 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 a PortfolioDataset 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, and cursor. Missing fields trigger route.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 handles pageKey pagination.
  • ERC-20 balances are normalised to hex using normalizeErc20Balance, mimicking Alchemy’s tokenBalance shape.
🚫

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.

RitoSwap Docs does not store, collect or access any of your conversations. All saved prompts are stored locally in your browser only.