Files
v0andMoheeb Zara bfef722a75 feat: add comprehensive test suites
Expand unit, E2E, and utility tests for full coverage.

Co-authored-by: Moheeb Zara <1184415+virgilvox@users.noreply.github.com>
2026-03-11 08:00:22 +00:00

5.5 KiB

Testing Documentation

This project uses Vitest for unit/integration tests and Playwright for end-to-end testing.

Quick Start

# Install Playwright browsers (first time only)
npx playwright install

# Run unit tests (watch mode)
pnpm test

# Run unit tests with UI
pnpm test:ui

# Run E2E tests
pnpm test:e2e

# Run E2E tests with UI
pnpm test:e2e:ui

Test Coverage

Category Tests Coverage
Actions 50+ Auth, Tasks, Projects, Members, Payments, Contacts, KB, Secrets
Components 30+ Badges, Tabs, Cards, Status, Toast, Empty, Loading
Utilities 40+ Date, String, Number, Array, Validation, URL
E2E Flows 50+ Auth, Dashboard, Tasks, Ops, Members, Payments, Projects

Unit Tests (Vitest)

Unit tests are located in __tests__/ directory.

Test Structure

  • __tests__/actions.test.ts - Server actions and business logic (50+ tests)

    • Authentication (signIn, signOut, getUser)
    • Member status validation (current, unverified, late)
    • Task CRUD and filtering
    • Project management
    • Member management (role-based access)
    • Payment management (treasurer access)
    • Contact management
    • Knowledge base operations
    • Secrets management
    • Activity logging
    • RLS policy validation
  • __tests__/components.test.tsx - React components (30+ tests)

    • TaskBadge (count display, overflow)
    • TabButton (active states, click handlers)
    • TaskCard (claim, complete, delete actions)
    • StatusBadge (color coding by status)
    • Toast notifications
    • Empty states
    • Loading spinners
    • Task filtering logic
  • __tests__/utils.test.ts - Utility functions (40+ tests)

    • Date formatting and comparison
    • String manipulation (initials, codes, truncation)
    • Number formatting (currency)
    • Array operations (groupBy, sortBy, unique)
    • Validation (email, phone, required fields)
    • URL utilities
    • Status and role checks

Writing Tests

import { describe, it, expect, beforeEach, vi } from 'vitest'

describe('Feature', () => {
  beforeEach(() => {
    // Setup before each test
  })

  it('should do something', () => {
    expect(result).toBe(expected)
  })
})

Key Testing Patterns

Mocking Supabase:

const mockSupabase = {
  from: vi.fn().mockReturnThis(),
  select: vi.fn().mockReturnThis(),
  eq: vi.fn().mockReturnThis(),
  single: vi.fn().mockResolvedValue({ data: { ...} }),
}

Testing Async Functions:

it('should fetch data', async () => {
  const result = await myAsyncFunction()
  expect(result).toBeDefined()
})

E2E Tests (Playwright)

E2E tests are located in e2e/ directory and test complete user flows.

Test Structure

  • e2e/critical-flows.spec.ts - Critical user journeys (40+ tests)

    • Landing & authentication
    • Dashboard loading and navigation
    • Tasks management (tabs, filtering, creation)
    • Operations & knowledge base
    • Members management
    • Payments management
    • Projects management
    • Contacts management
    • Communications
    • Settings
    • Mobile navigation
    • Error handling
    • Performance (load time checks)
    • Accessibility (headings, alt text, focus)
  • e2e/auth.spec.ts - Authentication flows (15+ tests)

    • Login form display and validation
    • Signup flow
    • Session management
    • Protected route access
    • Password reset
    • OAuth (if configured)

Writing E2E Tests

import { test, expect } from '@playwright/test'

test.describe('Feature', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/path')
  })

  test('should do something', async ({ page }) => {
    await page.click('button')
    await expect(page.locator('text=Success')).toBeVisible()
  })
})

Common E2E Patterns

Navigation:

await page.goto('/tasks', { waitUntil: 'networkidle' })

Interaction:

await page.click('button:has-text("Add")')
await page.fill('input[name="title"]', 'New Task')

Assertions:

await expect(page.locator('text=Task created')).toBeVisible()
expect(page.url()).toContain('/tasks')

Coverage

Run tests with coverage:

npm test -- --coverage

Coverage reports are generated in coverage/ directory.

CI/CD Integration

Tests are configured to run in CI environments. Key CI-specific behaviors:

  • E2E tests retry 2x on failure
  • Screenshots/videos saved for failed tests
  • Full parallelization in CI

Debugging

Vitest:

npm test -- --inspect-brk

Playwright:

npm run test:e2e -- --debug

Best Practices

  1. Test Behavior, Not Implementation - Test what the user sees, not how code works
  2. Keep Tests Isolated - Each test should be independent
  3. Use Meaningful Names - Test names should describe what's being tested
  4. Mock External Dependencies - Mock Supabase, APIs, etc.
  5. Test Happy & Sad Paths - Test both success and failure scenarios

Adding New Tests

When adding features:

  1. Add unit tests in __tests__/ for business logic
  2. Add E2E tests in e2e/ for user flows
  3. Run npm test to verify
  4. Check coverage with npm test -- --coverage

Troubleshooting

Tests timing out:

  • Increase timeout: test('...', async () => {...}, { timeout: 10000 })

Playwright can't find elements:

  • Use --debug to step through: npm run test:e2e -- --debug
  • Check selectors with: await page.pause()

Vitest isolation issues:

  • Clear mocks: vi.clearAllMocks() in beforeEach
  • Reset modules: vi.resetModules()