Files
tfm_ainventory/docs/superpowers/specs/2026-04-18-phase-2-frontend-tests-design.md

16 KiB

Phase 2 Frontend Tests Design Specification

Date: 2026-04-18
Status: APPROVED
Target: 80%+ coverage for frontend components, hooks, utilities
Branch: refactor/ai-friendly
Reference: Phase 1 Backend Tests (TDD pattern, subagent-driven execution)


1. Overview

Phase 2 creates a comprehensive Vitest test suite for the aInventory frontend, mirroring the TDD approach and execution patterns from Phase 1 (backend tests). The goal is to establish 80%+ coverage across 9 test files: 4 component suites, 3 utility/hook suites, and 2 integration workflows.

Key Alignment with Phase 1:

  • Test infrastructure first (setup.ts ≈ conftest.py)
  • Balanced unit + integration testing
  • Shared fixtures to avoid duplication
  • Subagent-driven execution (batches of 2-3 files)
  • Git tags for phase completion & rollback

2. Test Architecture & Setup

2.1 File Structure

frontend/tests/
├── setup.ts                           # Vitest config, shared mocks, fixtures
├── components/
│   ├── Scanner.test.tsx               # QR scan + OCR matching
│   ├── AIOnboarding.test.tsx          # AI extraction wizard
│   ├── AdminOverlay.test.tsx          # Admin config UI
│   └── IdentityCheckOverlay.test.tsx  # Login form
├── hooks/
│   └── useAdmin.test.ts               # Admin state hook
├── lib/
│   ├── api.test.ts                    # Axios + retry logic
│   └── labels.test.ts                 # SVG/QR generation
└── integration/
    ├── scanner-workflow.test.tsx      # Scan → match → adjust
    └── inventory-workflow.test.tsx    # View → filter → create → sync

2.2 Setup.ts (Shared Fixtures & Mocks)

Purpose: Centralized Vitest configuration and reusable mock fixtures (analogous to Phase 1's conftest.py)

Contents:

  1. Vitest globals — enable describe, it, expect without imports
  2. vi.mock() calls for:
    • axios — stub GET/POST/PUT with fixed responses
    • dexie — in-memory IndexedDB replacement
    • html5-qrcode — stub camera access (requestPermission, scan)
    • next/router — stub Next.js routing
  3. Shared fixtures:
    • Mock user token (valid + invalid variants)
    • Mock item list response (5 items with various states)
    • Mock AI extraction response (Gemini + Claude formats)
    • Mock offline sync queue
  4. Cleanup: Reset mocks before each test

Philosophy:

  • Same fixtures reused across all 9 test files
  • Test-specific overrides allowed (e.g., vi.spyOn(axios, 'post').mockReturnValue(...))
  • Reduces boilerplate, ensures consistency

2.3 Vitest Configuration (vitest.config.ts)

Setup:

import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: ['./tests/setup.ts'],
    coverage: {
      provider: 'v8',
      reporter: ['text', 'html'],
      all: true,
      lines: 80,
      functions: 80,
      branches: 80,
      statements: 80,
    },
  },
})

Key Settings:

  • environment: 'jsdom' — simulate browser for React components
  • setupFiles — load shared mocks before tests
  • Coverage thresholds: 80%+ across all metrics (lines, functions, branches, statements)

2.4 Package.json Updates

Add dependencies:

{
  "devDependencies": {
    "vitest": "^1.0.0",
    "@vitest/ui": "^1.0.0",
    "@testing-library/react": "^14.0.0",
    "@testing-library/user-event": "^14.0.0",
    "@testing-library/jest-dom": "^6.0.0",
    "@vitejs/plugin-react": "^4.0.0",
    "jsdom": "^23.0.0"
  }
}

Test scripts:

{
  "scripts": {
    "test": "vitest",
    "test:ui": "vitest --ui",
    "test:coverage": "vitest run --coverage"
  }
}

3. Component Tests (4 Files)

3.1 Scanner.test.tsx

What it tests:

  • Viewport rendering (video element, canvas overlay)
  • Zoom controls (1x → 2x → max cycle)
  • OCR matching engine (scoring, threshold logic)
  • Camera permission flows
  • State updates on scan result

Test Types:

  • Unit: Zoom logic, matching score calculation, error handling
  • Integration: Real component tree, mocked camera, verify state callbacks

Coverage Targets:

  • Render paths: initial + error states
  • Zoom cycle: all 4 states (1x, 2x, max/2, max)
  • Matching: exact match (500pts), partial (200pts), token (50pts), category (20pts), threshold (40pts)
  • Callbacks: onScanResult, onError

Key Mocks:

  • html5-qrcode — stub camera access, return fixed QR/barcode string
  • Component props — onScanResult callback verification

3.2 AIOnboarding.test.tsx

What it tests:

  • Step progression (image capture → extraction → confirmation)
  • Image preprocessing (validation, resize, crop, filter)
  • AI response formatting (Gemini vs Claude)
  • User validation of extracted data
  • Form submission

Test Types:

  • Unit: Step validation, data transformation, error messages
  • Integration: Full wizard flow, mocked AI response, verify final submit

Coverage Targets:

  • Step transitions: capture → extraction → confirm → done
  • Image validation: size, format, EXIF handling
  • AI response parsing: field mapping, confidence scores
  • User override: edited fields on confirmation step
  • Submit: API call with validated data

Key Mocks:

  • axios.post('/ai/extract') — return mock Gemini/Claude response
  • Canvas API — image preprocessing simulation

3.3 AdminOverlay.test.tsx

What it tests:

  • Tab rendering (Identity, Database, LDAP, AI, Categories)
  • Form field validation (required, format, length)
  • Form submission with mocked API
  • Error message display
  • Loading states

Test Types:

  • Unit: Field validation, error rendering, tab switching
  • Integration: Full form submission, mock API response, state update

Coverage Targets:

  • Tab rendering: all 5 tabs present and switchable
  • Form validation: required fields, format validation, error messages
  • Submission: API call with payload, success/error handling
  • Loading state: button disabled, spinner visible during submission

Key Mocks:

  • axios.put('/admin/config') — mock successful + error responses
  • Form fields — controlled component rendering

3.4 IdentityCheckOverlay.test.tsx

What it tests:

  • Login form rendering (username, password, login button)
  • Form validation (required fields)
  • LDAP authentication flow
  • Local password authentication fallback
  • Token storage and success callback

Test Types:

  • Unit: Form validation, error handling
  • Integration: Login flow, mocked auth endpoint, token storage

Coverage Targets:

  • Form fields: username + password required
  • Validation: empty field errors
  • LDAP login: POST to /auth/login with credentials
  • Success: token stored, onLoginSuccess callback fired
  • Error: error message displayed, form remains editable

Key Mocks:

  • axios.post('/auth/login') — mock LDAP response with JWT token
  • localStorage — in-memory token storage

4. Hook & Utility Tests (3 Files)

4.1 useAdmin.test.ts

What it tests:

  • Hook initialization (load config from API)
  • State updates (identity, DB, LDAP, AI, categories)
  • Validation before submission
  • Error handling and retry logic

Test Types:

  • Unit: State mutations, validation logic
  • Integration: API calls (mocked), state persistence

Coverage Targets:

  • Initialization: load admin config on mount
  • State updates: each config section (identity, LDAP, AI, etc.)
  • Validation: required fields, format checks
  • Submission: API call with validated payload
  • Error states: network failure, validation error, server error

Key Mocks:

  • axios.get('/admin/config') — return mock config object
  • axios.put('/admin/config') — mock success + error responses

4.2 api.test.ts

What it tests:

  • Axios instance configuration (base URL, headers, auth)
  • Request construction (query params, body, headers)
  • Retry logic for network failures
  • Response parsing and error mapping
  • Token refresh on 401

Test Types:

  • Unit: Request building, error mapping, retry logic
  • Integration: Mocked axios, verify request/response flow

Coverage Targets:

  • Auth headers: JWT token in Authorization header
  • Request types: GET, POST, PUT, DELETE
  • Query params: proper URL encoding
  • Retry: exponential backoff on network error
  • Error mapping: HTTP status → human-readable error message
  • Token refresh: 401 triggers new login flow

Key Mocks:

  • axios — intercept requests, mock responses

4.3 labels.test.ts

What it tests:

  • SVG Code 128 barcode generation
  • SVG QR code generation (no external library)
  • Canvas-to-PNG rasterization (browser export)
  • Label dimension validation (62mm x 29mm)

Test Types:

  • Unit: SVG encoding, QR structure validation
  • Integration: Canvas API, image export

Coverage Targets:

  • Code 128 encoding: valid barcode structure
  • QR generation: valid QR format
  • SVG output: valid XML structure, correct dimensions
  • Canvas export: PNG blob generation
  • Error handling: invalid input, encoding errors

Key Mocks:

  • Canvas API — stub createImageData, getContext

5. Integration Tests (2 Files)

5.1 scanner-workflow.test.tsx

What it tests:

  • End-to-end: Scan QR/barcode → OCR match → select item → stock adjustment
  • Real component tree: Scanner + ItemList + StockAdjustmentForm
  • Mocked: html5-qrcode, axios (item API, stock update API)

User Journey:

  1. Scanner displays, user clicks "Scan"
  2. html5-qrcode stub returns barcode string
  3. Matching engine finds item (exact or partial match)
  4. Item details displayed in form
  5. User adjusts quantity, clicks "Check In"
  6. API updates stock, success message shown

Coverage Targets:

  • Scan trigger → match → form population
  • User interaction: quantity adjustment, submission
  • API integration: stock update call
  • Error handling: no match found, network error

Key Mocks:

  • html5-qrcode — return fixed barcode on scan
  • axios.get('/items') — return mock item list
  • axios.post('/operations/checkin') — mock success response

5.2 inventory-workflow.test.tsx

What it tests:

  • End-to-end: View inventory → filter/sort → create new item → offline sync
  • Real component tree: Dashboard + ItemTable + CreateItemModal + SyncStatus
  • Mocked: axios (all API calls), Dexie (IndexedDB for offline queue)

User Journey:

  1. Dashboard loads, displays item list from API
  2. User filters by category, sorts by quantity
  3. User clicks "Create Item", fills form, submits
  4. Network goes offline (axios fails)
  5. Item queued in IndexedDB (offline sync)
  6. Network comes back online
  7. Sync button triggers, offline items sent to backend
  8. Item list updates

Coverage Targets:

  • Data loading: initial list from API
  • Filter/sort: UI updates, no API call
  • Create item: form submission, success message
  • Offline queue: Dexie stores pending items
  • Sync: batch API call for offline items, success/error handling

Key Mocks:

  • axios.get('/items') — return mock inventory
  • axios.post('/items') — handle create + batch sync
  • Dexie.table('pending_operations') — in-memory queue

6. Execution Plan (Subagent-Driven)

6.1 Batch 1: Scanner Foundation (Tests 1-2)

Files: setup.ts, Scanner.test.tsx

Tasks:

  1. Create frontend/tests/setup.ts with Vitest config, shared mocks (axios, html5-qrcode, Dexie, next/router)
  2. Create frontend/tests/components/Scanner.test.tsx with unit + integration tests
  3. Run npm test -- --coverage and verify 80%+ on Scanner module

Roles:

  • Implementer: Write setup + Scanner tests
  • Reviewer 1: Validate mock fixtures align with Phase 1 patterns
  • Reviewer 2: Verify test coverage (render, zoom, matching, callbacks)

Success Criteria:

  • setup.ts exports fixtures and vi.mock() setup
  • Scanner tests cover all paths (unit + integration)
  • npm test -- --coverage shows 80%+ on Scanner module
  • All tests passing, no console errors

Commit: test: setup vitest and create Scanner test suite


6.2 Batch 2: AIOnboarding & Hooks (Tests 3-5)

Files: AIOnboarding.test.tsx, useAdmin.test.ts, api.test.ts

Tasks:

  1. Create frontend/tests/components/AIOnboarding.test.tsx — step progression, AI response parsing
  2. Create frontend/tests/hooks/useAdmin.test.ts — state management, form submission
  3. Create frontend/tests/lib/api.test.ts — request building, retry logic, error mapping

Roles:

  • Implementer: Reuse Batch 1 fixtures, write 3 test files
  • Reviewer 1: Ensure consistent mock usage across files
  • Reviewer 2: Verify 80%+ coverage on all 3 modules

Success Criteria:

  • All 3 test files created
  • Reuse setup.ts fixtures (no duplication)
  • npm test -- --coverage shows 80%+ on AIOnboarding, useAdmin, api
  • All tests passing

Commit: test: add AIOnboarding, useAdmin, api test suites


6.3 Batch 3: Admin & Utilities (Tests 6-7)

Files: AdminOverlay.test.tsx, labels.test.ts

Tasks:

  1. Create frontend/tests/components/AdminOverlay.test.tsx — tab rendering, form validation, submission
  2. Create frontend/tests/lib/labels.test.ts — barcode/QR generation, canvas export

Roles:

  • Implementer: Write 2 test files
  • Reviewer 1: Validate form field coverage (5 tabs, validation logic)
  • Reviewer 2: Verify SVG/canvas test patterns

Success Criteria:

  • Both test files created
  • AdminOverlay covers all 5 tabs + form submission
  • labels.ts covers Code 128, QR, canvas export
  • npm test -- --coverage shows 80%+ on both modules

Commit: test: add AdminOverlay and labels test suites


6.4 Batch 4: Identity & Integration (Tests 8-9)

Files: IdentityCheckOverlay.test.tsx, scanner-workflow.test.tsx, inventory-workflow.test.tsx

Tasks:

  1. Create frontend/tests/components/IdentityCheckOverlay.test.tsx — login form, LDAP flow, token storage
  2. Create frontend/tests/integration/scanner-workflow.test.tsx — scan → match → adjust
  3. Create frontend/tests/integration/inventory-workflow.test.tsx — view → filter → create → sync

Roles:

  • Implementer: Write 3 test files
  • Reviewer 1: Validate login flow coverage (LDAP, error states)
  • Reviewer 2: Verify integration test patterns (real component tree, mocked API)

Success Criteria:

  • All 3 test files created
  • IdentityCheckOverlay covers login + error states
  • scanner-workflow covers end-to-end scan flow
  • inventory-workflow covers CRUD + offline sync
  • npm test -- --coverage shows 80%+ on all modules

Commit: test: add IdentityCheckOverlay and integration test suites


6.5 Phase Completion

Tasks:

  1. Run full test suite: npm test -- --coverage
  2. Verify 80%+ coverage across all files
  3. Create git tag: phase-2-complete
  4. Update SESSION_STATE.md with Phase 2 status
  5. Update REFACTORING_PROGRESS.md (mark Phase 2 )

Success Criteria:

  • All 9 test files created and passing
  • Coverage report: 80%+ on all metrics (lines, functions, branches, statements)
  • No console errors or warnings
  • Git tag phase-2-complete created

Commit: docs: mark phase 2 complete - frontend test suite at 80%+ coverage


7. Success Metrics

Metric Target Status
Test files created 9
Total test cases 100+
Coverage (lines) 80%+
Coverage (functions) 80%+
Coverage (branches) 80%+
All tests passing Yes
No console errors Yes
Git tag phase-2-complete Yes

8. Dependencies & Pre-requisites

  • Phase 1 (Backend Tests) COMPLETE
  • Vitest installed (v1.0.0+)
  • @testing-library/react installed
  • jsdom (React component testing environment)
  • Git tag phase-1-complete available for rollback

9. Rollback Plan

If Phase 2 encounters critical issues:

# Rollback to Phase 1 completion
git reset --hard phase-1-complete

# Delete Phase 2 tags
git tag -d phase-2-complete

# Resume when ready
git checkout refactor/ai-friendly

10. Next Phase (Phase 3)

After Phase 2 completion:

  • Create docs/superpowers/plans/2026-04-18-phase-3-e2e-tests.md
  • Add Playwright E2E tests for critical workflows (login, scan, create item, offline sync, admin settings)
  • Target: 5+ workflows automated, <30 min runtime