Testing
The frontend uses Vitest for unit and integration tests, and Playwright for browser-based E2E tests.
Setup
Framework: Vitest ^2.1.8
Config: vitest.config.ts
defineConfig({
test: {
globals: true,
environment: 'node',
testTimeout: 30000, // 30s for API calls
hookTimeout: 30000,
teardownTimeout: 30000,
},
resolve: {
alias: { '@': './src' },
},
})
Running Tests
| Command | What it does |
|---|---|
npm test |
Watch mode (re-runs on file changes) |
npm run test:run |
Single run |
npm run test:utc |
Single run with TZ=UTC (for date-sensitive tests) |
npm run test:yearn |
Yearn-specific test script |
npm run test:yearn:watch |
Watch mode for Yearn tests only |
Test Categories
Unit Tests (src/v2/positions/__tests__/)
Mock-based tests that isolate logic from external dependencies. These use vi.mock() to replace Prisma, Zerion, and other services.
| File | What it tests |
|---|---|
helpers.test.ts |
FIFO realized PnL calculations, reward flows |
rows.test.ts |
Complex position row building, protocol-specific values |
summary.test.ts |
Position summaries, Zerion vs Valuation preference, aggregation |
wallet-cards.test.ts |
Wallet card building, EVM wallet filtering |
stacked-chart.test.ts |
Stacked chart data generation |
total-chart.test.ts |
Total portfolio chart data, valuation bucketing |
Protocol Integration Tests (src/lib/defi/)
Live API tests that call real external services. These have longer timeouts (10–60 seconds) and can fail if external APIs are down.
| File | What it tests |
|---|---|
__tests__/positions.e2e.test.ts |
Cross-protocol position fetching: Aave supplies, Uniswap V2/V3 positions, Yearn vault balances, Morpho positions |
morpho/data.test.ts |
MetaMorpho vault data, multi-chain support, performance |
uniswap/v2/data.test.ts |
Uniswap V2 pair data, pagination, user positions |
uniswap/v3/data.test.ts |
Uniswap V3 pool data, positions, APY calculations |
yearn/__tests__/sdk.test.ts |
Yearn vault listing, user balances, on-chain functions |
trends/__tests__/service.test.ts |
DeFi trends: blue-chip pools, stablecoin pools, high-APR pools |
CI Integration
Tests run automatically in the build.yml GitHub Actions workflow on every push to main/staging and on all pull requests.
- name: Unit tests (vitest src/v2)
if: ${{ github.event_name != 'workflow_call' }}
run: npm run test:run -- src/v2
Important: CI only runs src/v2/ tests (the unit tests). Protocol integration tests are not run in CI because they depend on live external APIs and have long timeouts.
Testing Patterns
Mocking: Unit tests use vi.hoisted() + vi.mock() to replace modules before import:
const prismaMock = vi.hoisted(() => ({
nmt_position: { findMany: vi.fn() },
nmt_position_valuation: { findMany: vi.fn() },
}));
vi.mock("server-only", () => ({}));
vi.mock("@/lib/prisma/client", () => ({
default: prismaMock,
}));
Multi-chain testing: Integration tests run against multiple chains (Mainnet, Optimism, Base, Arbitrum) and gracefully skip unsupported chains with console.warn.
E2E Tests (Playwright)
Browser-based end-to-end tests using Playwright. These tests run against a local dev server and exercise real user flows through the UI.
Config: playwright.config.ts
Test Projects
| Project | Pattern | Workers | Timeout | What it covers |
|---|---|---|---|---|
| fast | 01x, 02x |
parallel | 2 min | Wallet connect, connected state, Krystal routes |
| zaps | 03x |
serial | 9 min | Swaps, Uniswap V3/V4 zaps, Aerodrome Slipstream zaps |
| vaults | 04x |
serial | 9 min | Yearn, Krystal, Morpho, Aave vault operations |
| withdraw | *_withdraw_* |
serial | 9 min | USDC and ETH withdrawal flows |
Test Files
| File | What it tests |
|---|---|
010_wallet_connect.spec.ts |
Wallet connection flow |
020_connected.spec.ts |
Connected wallet state |
021_krystal_route.spec.ts |
Krystal route navigation |
030_swap.spec.ts |
Token swap flow |
031_zap_uniswap_v3.spec.ts |
Uniswap V3 zap (deposit) |
032_zap_aerodrome_slipstream.spec.ts |
Aerodrome Slipstream zap |
033_zap_uniswap_v4.spec.ts |
Uniswap V4 zap |
042_yearn.spec.ts |
Yearn vault deposit |
043_krystal.spec.ts |
Krystal vault deposit |
044_morpho.spec.ts |
Morpho vault deposit |
045_aave.spec.ts |
Aave supply |
051_withdraw_usdc.spec.ts |
USDC withdrawal |
052_withdraw_eth.spec.ts |
Native ETH withdrawal |
CI Integration
Playwright tests run in GitHub Actions on PRs. The CI workflow:
- Runs the fast project on all PRs
- Runs modified test projects (detected via diff) alongside fast
- Uses per-branch concurrency groups to avoid conflicts
- Retries failed tests up to 2 times in CI
- Captures traces and video on failure