11 KiB
Executable File
Frontend Coverage Gap Analysis and Test Plan
Date: 2026-01-25 Goal: Achieve 85.5%+ frontend test coverage (CI-safe buffer over 85% threshold) Current Status: 85.06% (local) / 84.99% (CI)
Executive Summary
Coverage Gap: 0.44% below target (85.5%) Required: ~50-75 additional lines of coverage Strategy: Target 4 high-impact files with strategic test additions Timeline: 2-3 hours for implementation Risk: LOW - Clear test patterns established, straightforward implementations
Coverage Analysis
Current Metrics (v8 Coverage Provider)
| Metric | Percentage | Status |
|---|---|---|
| Lines | 85.75% | ✅ Pass (85% threshold) |
| Statements | 85.06% | ✅ Pass |
| Branches | 78.23% | ⚠️ Below ideal (80%+) |
| Functions | 79.25% | ⚠️ Below ideal (80%+) |
CI Variance Analysis
- Local: 85.06% statements
- CI: 84.99% statements
- Variance: -0.07% (7 basis points)
- Root Cause: Timing/concurrency differences in CI environment
- Mitigation: Target 85.5% (50bp buffer) to ensure CI passes consistently
Target Files (Ranked by Impact)
1. Plugins.tsx - HIGHEST PRIORITY ⚡
Current Coverage: 58.18% lines (lowest in codebase) File Size: 391 lines Uncovered Lines: ~163 lines Potential Gain: +1.2% total coverage
Why Target This File:
- Lowest coverage in entire codebase (58%)
- Well-structured, testable component
- Clear user flows and state management
- Existing patterns for similar pages (ProxyHosts.tsx @ 94.46%)
Uncovered Code Paths:
- ✘ Plugin toggle logic (enable/disable)
- ✘ Reload plugins flow
- ✘ Error handling branches
- ✘ Metadata modal open/close
- ✘ Status badge rendering logic (switch cases)
- ✘ Built-in vs external plugin separation
- ✘ Empty state rendering
- ✘ Plugin grouping and filtering
- ✘ Documentation URL handling
- ✘ Modal metadata display
Testing Complexity: MEDIUM Expected Coverage After Tests: 85-90%
2. Tabs.tsx - QUICK WIN 🎯
Current Coverage: 70% lines, 0% branches (!) File Size: 59 lines Uncovered Lines: ~18 lines Potential Gain: +0.15% total coverage
Why Target This File:
- CRITICAL: 0% branch coverage despite being a UI primitive
- Small file = fast implementation
- Simple component with clear test patterns
- Used throughout app (high importance)
- Low-hanging fruit for immediate gains
Uncovered Code Paths:
- ✘ TabsList rendering and className merging
- ✘ TabsTrigger active/inactive states
- ✘ TabsContent mount/unmount
- ✘ Keyboard navigation (focus-visible states)
- ✘ Disabled state handling
- ✘ Custom className application
Testing Complexity: LOW Expected Coverage After Tests: 95-100%
3. Uptime.tsx - HIGH IMPACT 📊
Current Coverage: 65.04% lines File Size: 575 lines Uncovered Lines: ~201 lines Potential Gain: +1.5% total coverage
Why Target This File:
- Second-lowest page coverage
- Complex component with multiple sub-components
- Heavy mutation/query usage (good test patterns exist)
- Critical monitoring feature
Uncovered Code Paths:
- ✘ MonitorCard status badge logic
- ✘ Menu dropdown interactions
- ✘ Monitor editing flow
- ✘ Monitor deletion with confirmation
- ✘ Health check trigger
- ✘ Monitor creation form submission
- ✘ History chart rendering
- ✘ Empty state handling
- ✘ Sync monitors flow
- ✘ Error states and toast notifications
Testing Complexity: HIGH (multiple mutations, nested components) Expected Coverage After Tests: 80-85%
4. SecurityHeaders.tsx - MEDIUM IMPACT 🛡️
Current Coverage: 64.61% lines File Size: 339 lines Uncovered Lines: ~120 lines Potential Gain: +0.9% total coverage
Why Target This File:
- Third-lowest page coverage
- Critical security feature
- Complex CRUD operations
- Good reference: AuditLogs.tsx @ 84.37%
Uncovered Code Paths:
- ✘ Profile creation form
- ✘ Profile update flow
- ✘ Delete with backup
- ✘ Clone profile logic
- ✘ Preset tooltip rendering
- ✘ Profile grouping (custom vs presets)
- ✘ Empty state for custom profiles
- ✘ Built-in preset rendering loops
- ✘ Dialog state management
Testing Complexity: MEDIUM Expected Coverage After Tests: 78-82%
Implementation Strategy
Phase 1: Quick Wins (Target: +0.2%)
Priority: IMMEDIATE Files: Tabs.tsx Estimated Time: 30 minutes Expected Gain: 0.15-0.2%
Test File: frontend/src/components/ui/__tests__/Tabs.test.tsx
Test Cases:
- ✅ Tabs renders with default props
- ✅ TabsList applies custom className
- ✅ TabsTrigger renders active state
- ✅ TabsTrigger renders inactive state
- ✅ TabsTrigger handles disabled state
- ✅ TabsContent shows when tab is active
- ✅ TabsContent hides when tab is inactive
- ✅ Focus states work correctly
- ✅ Keyboard navigation (Tab, Arrow keys)
- ✅ Custom props pass through
Phase 2: High Impact (Target: +1.5%)
Priority: HIGH Files: Plugins.tsx Estimated Time: 1.5 hours Expected Gain: 1.2-1.5%
Test File: frontend/src/pages/__tests__/Plugins.test.tsx
Test Suites:
Suite 1: Component Rendering (10 tests)
- ✅ Renders loading state with skeletons
- ✅ Renders empty state when no plugins
- ✅ Renders built-in plugins section
- ✅ Renders external plugins section
- ✅ Displays plugin metadata correctly
- ✅ Shows status badges (loaded, error, pending, disabled)
- ✅ Renders header with reload button
- ✅ Displays info alert
- ✅ Groups plugins by type (built-in vs external)
- ✅ Renders documentation links when available
Suite 2: Plugin Toggle Logic (8 tests)
- ✅ Enables disabled plugin
- ✅ Disables enabled plugin
- ✅ Prevents toggling built-in plugins
- ✅ Shows error toast for built-in toggle attempt
- ✅ Shows success toast on enable
- ✅ Shows success toast on disable
- ✅ Shows error toast on toggle failure
- ✅ Refetches plugins after toggle
Suite 3: Reload Plugins (5 tests)
- ✅ Triggers reload mutation
- ✅ Shows loading state during reload
- ✅ Shows success toast with count
- ✅ Shows error toast on failure
- ✅ Refetches plugins after reload
Suite 4: Metadata Modal (7 tests)
- ✅ Opens metadata modal on "Details" click
- ✅ Closes metadata modal on close button
- ✅ Displays all plugin metadata fields
- ✅ Shows version when available
- ✅ Shows author when available
- ✅ Renders documentation link in modal
- ✅ Shows error details when plugin has errors
Suite 5: Status Badge Rendering (4 tests)
- ✅ Shows "Disabled" badge for disabled plugins
- ✅ Shows "Loaded" badge for loaded plugins
- ✅ Shows "Error" badge for error state
- ✅ Shows "Pending" badge for pending state
Phase 3: Additional Coverage (Target: +1.0%)
Priority: MEDIUM Files: SecurityHeaders.tsx Estimated Time: 1 hour Expected Gain: 0.8-1.0%
Test File: frontend/src/pages/__tests__/SecurityHeaders.test.tsx
Test Cases (15 critical paths):
- ✅ Renders loading state
- ✅ Renders preset profiles
- ✅ Renders custom profiles
- ✅ Opens create profile dialog
- ✅ Creates new profile
- ✅ Opens edit dialog
- ✅ Updates existing profile
- ✅ Opens delete confirmation
- ✅ Deletes profile with backup
- ✅ Clones profile with "(Copy)" suffix
- ✅ Displays security scores
- ✅ Shows preset tooltips
- ✅ Groups profiles correctly
- ✅ Error handling for mutations
- ✅ Empty state rendering
Test Implementation Guide
Technology Stack
- Test Runner: Vitest
- Testing Library: React Testing Library
- Mocking: Vitest vi.mock
- Query Client: @tanstack/react-query (with test wrapper)
- Assertions: @testing-library/jest-dom matchers
Example Test Patterns
See the plan document for full code examples of:
- Component Test Setup (Tabs.tsx example)
- Page Component Test Setup (Plugins.tsx example)
- Testing Hooks (Reference pattern)
Expected Outcomes & Validation
Coverage Targets Post-Implementation
| Phase | Files Tested | Expected Line Coverage | Expected Gain | Cumulative |
|---|---|---|---|---|
| Baseline | - | 85.06% | - | 85.06% |
| Phase 1 | Tabs.tsx | 95-100% | +0.15% | 85.21% |
| Phase 2 | Plugins.tsx | 85-90% | +1.2% | 86.41% |
| Phase 3 | SecurityHeaders.tsx | 78-82% | +0.5% | 86.91% |
| TOTAL | 3 files | - | +1.85% | ~86.9% |
Success Criteria
✅ Primary Goal: CI Coverage ≥ 85.0% ✅ Stretch Goal: CI Coverage ≥ 85.5% (buffer for variance) ✅ Quality Goal: All new tests follow established patterns ✅ Maintenance Goal: Tests are maintainable and descriptive
CI Validation Process
-
Local Verification:
cd frontend && npm run test:coverage # Verify: "All files" line shows ≥ 85.5% -
Pre-Push Check:
cd frontend && npm test # All tests must pass -
CI Pipeline:
- Frontend unit tests run automatically
- Codecov reports coverage delta
- CI fails if coverage drops below 85%
Implementation Timeline
Day 1: Quick Wins + Setup (2 hours)
Morning (1 hour):
- Implement Tabs.tsx tests (all 10 test cases)
- Run coverage locally:
npm run test:coverage - Verify Phase 1 gain: +0.15-0.2%
- Commit: "test: add comprehensive tests for Tabs component"
Afternoon (1 hour):
- Set up Plugins.tsx test file structure
- Implement Suite 1: Component Rendering (10 tests)
- Implement Suite 2: Plugin Toggle Logic (8 tests)
- Verify tests pass:
npm test Plugins.test.tsx
Day 2: High Impact Files (3 hours)
Morning (1.5 hours):
- Complete Plugins.tsx remaining suites:
- Suite 3: Reload Plugins (5 tests)
- Suite 4: Metadata Modal (7 tests)
- Suite 5: Status Badge Rendering (4 tests)
- Run coverage: should be ~86.2%
- Commit: "test: add comprehensive tests for Plugins page"
Afternoon (1.5 hours):
- Implement SecurityHeaders.tsx tests (15 test cases)
- Focus on CRUD operations and state management
- Final coverage check: target 86.5-87%
- Commit: "test: add tests for SecurityHeaders page"
Conclusion
This plan provides a systematic approach to closing the 0.44% coverage gap and establishing a solid 50bp buffer above the 85% threshold. By focusing on Tabs.tsx (quick win), Plugins.tsx (highest impact), and SecurityHeaders.tsx (medium impact), we can efficiently achieve 86.5-87% coverage with well-structured, maintainable tests.
Next Step: Begin Phase 1 implementation with Tabs.tsx tests.
Plan Status: ✅ COMPLETE Approved By: Automated Analysis Implementation ETA: 2-3 hours Expected Result: 86.5-87% coverage (CI-safe)