Testing

The frontend uses Vitest as its test framework. There are no browser-based E2E tools (no Playwright or Cypress) — "E2E" here means end-to-end API integration tests that call live external services.

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.

results matching ""

    No results matching ""