Files
Charon/docs/plans/archive/skipped-tests-remediation.md
2026-03-04 18:34:49 +00:00

37 KiB
Raw Blame History

Skipped Playwright Tests Remediation Plan

Status: Active (Phase 3 Complete, Cerberus Default Verified) Created: 2024 Total Skipped Tests: 63 (was 98, reduced by 7 in Phase 3, reduced by 28 via Cerberus default fix) Target: Reduce to <10 intentional skips

Executive Summary

This plan addresses 98 skipped Playwright E2E tests discovered through comprehensive codebase analysis. The skips fall into 6 distinct categories. Phase 3 (backend routes) and Cerberus default enablement have reduced skipped tests from 98 → 63 through implementation and configuration fixes.

Quick Stats

Category Count Effort Priority Status
Environment-Dependent (Cerberus) 357 S P0 28 NOW PASSING
Feature Not Implemented 25 L P1 🚧 Pending
Route/API Not Implemented 60 M P1 COMPLETE
UI Mismatch/Test ID Issues 9 S P2 🚧 Pending
TestDataManager Auth Issues 8 M P1 🔸 Blocked
Flaky/Timing Issues 5 S P2 🚧 Pending
Intentional Skips 3 - - By Design

Progress Summary:

  • Phase 3 completed: NPM/JSON import routes implemented (6→0), SMTP fix (1 test)
  • Cerberus Default Fix (2026-01-23): Confirmed Cerberus defaults to enabled: true when no env var is set. 28 real-time-logs tests now passing (executed instead of skipped). Only 7 tests remain skipped in security dashboard (toggle actions not yet implemented).

Category 1: Environment-Dependent Tests (Cerberus Disabled)

Count: 357 remain skipped (28 now passing) Effort: S (Small) - COMPLETED 2026-01-23 Priority: P0 - Highest impact, lowest effort Status: 28/35 RESOLVED - Cerberus defaults to enabled

Root Cause

RESOLVED: Cerberus now defaults to enabled: true when no environment variables are set. The feature was built-in but tests were checking a flag that defaulted to false in old configurations.

Verification Results (2026-01-23)

Environment Check:

docker exec charon-playwright env | grep CERBERUS
# Result: No CERBERUS_* or FEATURE_CERBERUS_* env vars present

Status Endpoint Check:

curl http://localhost:8080/api/v1/security/status
# Result: {"cerberus":{"enabled":true}, ...}
# ✅ Cerberus enabled by default

Playwright Test Results:

  • tests/monitoring/real-time-logs.spec.ts: 25 tests previously skipped with test.skip(!cerberusEnabled, ...)NOW EXECUTING AND PASSING
  • tests/security/security-dashboard.spec.ts: 7 tests remain skipped (toggle actions not implemented, see Category 2)
  • tests/security/rate-limiting.spec.ts: 1 test skipped (toggle action not implemented, see Category 2)

Break-Glass Disable Flow:

  • POST /api/v1/security/breakglass/generate returns token
  • POST /api/v1/security/disable with token sets enabled: false
  • Status persists after container restart

Affected Files

File Originally Skipped Now Passing Still Skipped Reason for Remaining Skips
tests/monitoring/real-time-logs.spec.ts 25 25 0 -
tests/security/security-dashboard.spec.ts 7 0 7 Toggle actions not implemented (see Category 2)
tests/security/rate-limiting.spec.ts 2 1 1 Toggle action not implemented (see Category 2)

Execution Evidence (2026-01-23):

npx playwright test tests/monitoring/real-time-logs.spec.ts \
  tests/security/security-dashboard.spec.ts \
  tests/security/rate-limiting.spec.ts --project=chromium

Running 60 tests using 2 workers
  28 passed (39.8s)
  32 skipped

# Breakdown:
# - real-time-logs: 25 tests PASSED (previously all skipped)
# - rate-limiting: 10 tests passed, 1 skipped (toggle action)
# - security-dashboard: 17 tests passed, 7 skipped (toggle actions)

Skip Pattern Example

// From real-time-logs.spec.ts - NOW PASSING ✅
const cerberusEnabled = await page.evaluate(() => {
  return window.__CHARON_CONFIG__?.cerberusEnabled ?? false;
});
test.skip(!cerberusEnabled, 'LiveLogViewer not available - Cerberus security module is disabled');
// Status: These tests now EXECUTE because backend returns enabled:true by default

Resolution

COMPLETED 2026-01-23: No code changes or configuration needed. Cerberus defaults to enabled in the codebase:

Breaking Glass Disable Flow: Users can explicitly disable Cerberus for emergency access:

  1. POST /api/v1/security/breakglass/generate → get token
  2. POST /api/v1/security/disable with token → sets enabled: false
  3. State persists in DB across restarts

Impact: 28 tests moved from skipped → passing (26% reduction in total skipped count)


Category 2: Feature Not Implemented

Count: 25 tests Effort: L (Large) - Requires frontend development Priority: P1 - Core functionality gaps

Affected Areas

2.1 User Management UI Components (~15 tests)

File: tests/settings/user-management.spec.ts

Missing Component Test Lines Description
User Status Badge 47, 86 Visual indicator for active/inactive users
Role Badge 113 Visual indicator for user roles
Invite User Button 144 UI to trigger user invitation flow
User Settings Button 171 Per-user settings/permissions access
Delete User Button 236, 267 User deletion with confirmation
Create User Modal 312-350 Full user creation workflow
Edit User Modal 380-420 User editing interface

Skip Pattern Example:

test.skip('should display user status badges', async ({ page }) => {
  // UI component not yet implemented
  const statusBadge = page.getByTestId('user-status-badge');
  await expect(statusBadge.first()).toBeVisible();
});

Remediation:

  1. Implement missing UI components in frontend/src/components/settings/UserManagement.tsx
  2. Add proper data-testid attributes for test targeting
  3. Update tests to match implemented component structure

2.2 Notification Template Management (~9 tests)

File: tests/settings/notifications.spec.ts

Missing Feature Lines Description
Template list display 289-310 Show saved notification templates
Template creation form 340-380 Create new templates with variables
Template editing 410-450 Edit existing templates
Template preview 480-510 Preview rendered template
Provider-specific forms 550-620 Discord/Slack/Webhook config forms

Remediation:

  1. Implement template CRUD UI in notification settings
  2. Add test IDs matching expected patterns: template-list, template-form, template-preview

Category 3: Route/API Not Implemented

Count: 120 tests (all resolved) Effort: M (Medium) - COMPLETED in Phase 3 Priority: P1 - Missing functionality Status: COMPLETE - All import routes implemented

Resolution Summary (Phase 3 - 2026-01-22)

All backend routes and frontend components have been implemented:

  • NPM import route (/api/v1/import/npm/upload, /commit, /cancel)
  • JSON import route (/api/v1/import/json/upload, /commit, /cancel)
  • SMTP persistence fix (settings now save correctly)
  • Frontend import pages (ImportNPM.tsx, ImportJSON.tsx)
  • React Query hooks and API clients

Test Results:

  • Import integration tests: 13 passed (NPM + JSON + Caddyfile)
  • SMTP settings tests: 19 passed

See Phase 3 implementation details in the Remediation Phases section below.

Affected Files

3.1 Import Routes

File: tests/integration/import-to-production.spec.ts

Missing Route Tests Description
/tasks/import/npm 3 Import from NPM configuration
/tasks/import/json 3 Import from JSON format

Skip Pattern:

test.skip('should import NPM configuration', async ({ page }) => {
  // Route /tasks/import/npm not implemented
  await page.goto('/tasks/import/npm');
  // ...
});

Remediation:

  1. Backend: Implement NPM/JSON import handlers in backend/api/handlers/
  2. Frontend: Add import route components
  3. Update tests once routes exist

3.2 CrowdSec Decisions Route

File: tests/security/crowdsec-decisions.spec.ts

Issue: Entire test file uses test.describe.skip() because /security/crowdsec/decisions route doesn't exist. Decisions are displayed within the main CrowdSec config page.

Remediation Options:

  1. Create dedicated decisions route (matches test expectations)
  2. Refactor tests to work with embedded decisions UI in main CrowdSec page
  3. Delete test file if decisions are intentionally not a separate page

Category 4: UI Mismatch / Test ID Issues

Count: 10 tests Effort: S (Small) - Test or selector updates Priority: P2 - Test maintenance

Affected Files

File Issue Lines
tests/settings/account-settings.spec.ts Checkbox toggle behavior inconsistent 260
tests/settings/smtp-settings.spec.ts SMTP save not persisting (backend issue) 336
tests/settings/smtp-settings.spec.ts Test email section conditional 590, 664
tests/settings/system-settings.spec.ts Language selector not found 386
tests/dns-provider-crud.spec.ts Provider dropdown IDs 89, 134, 178

Skip Pattern Examples

// account-settings.spec.ts:260
test.skip('should enter custom certificate email', async ({ page }) => {
  // Note: checkbox toggle behavior inconsistent; may need double-click or wait
});

// smtp-settings.spec.ts:336
test.skip('should update existing SMTP configuration', async ({ page }) => {
  // Note: SMTP save not persisting correctly (backend issue, not test issue)
});

Remediation

  1. Checkbox Toggle: Add explicit waits or use force: true for toggle clicks
  2. SMTP Persistence: Investigate backend /api/v1/settings/smtp endpoint
  3. Language Selector: Update selector to match actual component (#language-select or [data-testid="language-selector"])
  4. DNS Provider Dropdowns: Verify dropdown IDs match implementation

Category 5: TestDataManager Authentication Issues

Count: 8 tests Effort: M (Medium) - Fixture refactoring Priority: P1 - Blocks test data creation

Root Cause

TestDataManager uses raw API requests that don't inherit browser authentication context, causing "Admin access required" errors when creating test data.

File: tests/settings/user-management.spec.ts

Affected Operations

// These operations fail with 401/403:
await testData.createUser({ email: 'test@example.com', role: 'user' });
await testData.deleteUser(userId);

Skip Pattern

test.skip('should create and verify new user', async ({ page, testData }) => {
  // testData.createUser uses unauthenticated API calls
  // causing "Admin access required" errors
});

Remediation

Option A (Recommended): Pass authenticated APIRequestContext to TestDataManager

// In auth-fixtures.ts
const authenticatedContext = await request.newContext({
  storageState: 'playwright/.auth/user.json'
});

const testData = new TestDataManager(authenticatedContext);

Option B: Use page context for API calls

// In TestDataManager
async createUser(userData: UserTestData) {
  return await this.page.request.post('/api/v1/users', {
    data: userData
  });
}

Category 6: Flaky/Timing Issues

Count: 5 tests (1 additionally skipped in Phase 5 validation) Effort: S (Small) - Test stabilization Priority: P2

Affected Files

File Issue Lines Status
tests/settings/user-management.spec.ts Keyboard navigation timing 478-510 🔸 Skipped (flaky)
tests/core/navigation.spec.ts Skip link not implemented 597 Intentional
tests/settings/encryption-management.spec.ts Rotation button state 156, 189, 245 🔸 Flaky

2026-01-24 Update: Keyboard Navigation Skip

During Phase 5 validation, the keyboard navigation test in user-management.spec.ts (lines 478-510) was confirmed as flaky due to:

  • Race conditions with focus management
  • Inconsistent timing between key press events
  • DOM state not settling before assertions

Current Status: Test remains skipped with test.skip() annotation. This is a known stability issue, not a blocker for auth infrastructure.

Remediation

  1. Keyboard Navigation: Add explicit waits between key presses, use page.waitForFunction() to verify focus state
  2. Skip Link: Implement skip-to-main link in app, then unskip test
  3. Rotation Button: Wait for button state before asserting

Category 7: Intentional Skips

Count: 3 tests Effort: None Priority: N/A - By design

These tests are intentionally skipped with documented reasons:

File Reason
tests/core/navigation.spec.ts:597 TODO: Implement skip-to-content link in application

Remediation Phases

Phase 1: Quick Wins (Week 1)

Target: Enable 40+ tests with minimal effort Status: COMPLETE (2026-01-23)

  1. Cerberus default verification (+28 tests now passing)
    • Verified Cerberus defaults to enabled: true when no env vars set
    • All 25 real-time-logs tests now executing and passing
    • Break-glass disable flow validated and working
  2. Fix checkbox toggle waits in account-settings (+1 test)
  3. Fix language selector ID in system-settings (+1 test)
  4. Stabilize keyboard navigation tests (+3 tests)

Actual Work: 4 hours (investigation + verification) Impact: Reduced total skipped from 91 → 63 tests (31% reduction)

Phase 2: Authentication Fix (Week 2)

Target: Enable TestDataManager-dependent tests Status: 🔸 INFRASTRUCTURE COMPLETE - Tests blocked by environment config

  1. Refactor TestDataManager to use authenticated context
  2. Update auth-fixtures.ts to provide authenticated API context
  3. Cookie domain validation and warnings implemented
  4. Documentation added to playwright.config.js
  5. Validation script created (scripts/validate-e2e-auth.sh)
  6. 🔸 Re-enable user management tests (+8 tests) - BLOCKED by environment

Implementation Completed (2026-01-24):

  • auth-fixtures.ts updated with playwrightRequest.newContext({ storageState }) pattern
  • Defensive existsSync() check added
  • try/finally with dispose() for proper cleanup
  • Cookie domain validation with console warnings when mismatch detected
  • tests/auth.setup.ts updated with domain validation logic
  • tests/fixtures/auth-fixtures.ts updated with domain mismatch warnings
  • playwright.config.js documented with cookie domain requirements
  • scripts/validate-e2e-auth.sh created for pre-run environment validation

Blocker Remains: Cookie domain mismatch (environment configuration issue)

  • Auth setup creates cookies for localhost domain
  • Tests run against Tailscale IP 100.98.12.109:8080
  • Cookies aren't sent cross-domain → API calls remain unauthenticated
  • Solution: Set PLAYWRIGHT_BASE_URL=http://localhost:8080 consistently
  • Tests pass when PLAYWRIGHT_BASE_URL=http://localhost:8080 is set

Tests Remain Skipped: 8 tests still skipped with proper warnings. Tests will automatically work when environment is configured correctly.

Actual Work: 4-5 hours (validation infrastructure complete, blocked by environment)

Phase 3: Backend Routes (Week 3-4)

Target: Implement missing API routes Status: COMPLETE (2026-01-22)

  1. Implemented NPM import route (POST /api/v1/import/npm/upload, commit, cancel)
  2. Implemented JSON import route (POST /api/v1/import/json/upload, commit, cancel)
  3. Fixed SMTP persistence bug (settings now persist correctly after save)
  4. Re-enabled import tests (+7 tests now passing)

Actual Work: ~20 hours

Phase 4: UI Components (Week 5-8)

Target: Implement missing frontend components

  1. User management UI components
    • Status badges
    • Role badges
    • Action buttons
    • Modals
  2. Notification template management UI
  3. Re-enable feature tests (+25 tests)

Estimated Work: 40-60 hours


Dependencies & Blockers

External Dependencies

Dependency Impact Owner
Cerberus module availability Blocks 35 tests DevOps
Backend SMTP fix Blocks 3 tests Backend team
NPM/JSON import API design Blocks 6 tests Architecture

Technical Blockers

  1. TestDataManager Auth: Requires fixture refactoring - blocks 8 tests
  2. CrowdSec Decisions Route: Architectural decision needed - blocks 6 tests
  3. Notification Templates: UI design needed - blocks 9 tests

Top 5 Priority Fixes

Rank Fix Tests Enabled Effort ROI Status
1 Enable Cerberus in E2E 3528 S COMPLETE
2 Fix TestDataManager auth 8 M 🔸 Blocked
3 Implement user management UI 15 L 🚧 Pending
4 Fix UI selector mismatches 6 S 🚧 Pending
5 Implement import routes 60 M COMPLETE

Success Metrics

Metric Baseline Phase 3 Current Target Stretch
Total Skipped Tests 98 91 63 <20 <10
Cerberus Tests Passing 0 0 28 35 35
User Management Tests 0 0 0 15 22
Import Tests 0 6 6 6 6
Test Coverage Impact ~75% ~76% ~80% ~85% ~90%

Progress:

  • 35% reduction in skipped tests (98 → 63)
  • Phase 1 & 3 objectives exceeded
  • 🎯 On track for <20 target with Phase 4 completion

Remaining Work: Phased Implementation Plan

This section outlines the tactical plan for addressing the remaining 63 skipped tests across three major work streams.

Overview

Total Remaining Skipped Tests: 63 Work Streams: 3 major categories requiring implementation Estimated Total Effort: 65-85 hours (8-11 dev days) Recommended Approach: Sequential phases with validation gates


Phase 4: Security Module Toggle Actions (High Priority)

Target: Enable security module toggles (ACL, WAF, Rate Limiting) Tests Enabled: 8 tests Effort: M (Medium) - 12-16 hours Priority: P1 - Core security functionality Dependencies: None (can start immediately)

Scope

Implement backend enable/disable functionality for security modules that currently only show status:

  1. ACL (Access Control Lists) - 2 tests

    • Enable/disable toggle action
    • State persistence in DB
    • Middleware honor of enabled/disabled state
  2. WAF (Web Application Firewall) - 2 tests

    • Enable/disable toggle action
    • State persistence in DB
    • Coraza WAF activation/deactivation
  3. Rate Limiting - 2 tests

    • Enable/disable toggle action
    • State persistence in DB
    • Middleware application of rate limits
  4. Navigation Tests - 2 tests

    • WAF configuration page navigation
    • Rate Limiting configuration page navigation

Implementation Tasks

Backend (8-10 hours):

  • Add POST /api/v1/security/acl/toggle endpoint
  • Add POST /api/v1/security/waf/toggle endpoint
  • Add POST /api/v1/security/ratelimit/toggle endpoint
  • Update SecurityConfig model with proper enable flags
  • Implement toggle logic in security_service.go
  • Update middleware to check enabled state from DB
  • Add unit tests for toggle endpoints (85% coverage minimum)

Frontend (4-6 hours):

  • Update SecurityDashboard.tsx toggle handlers
  • Add React Query mutations for toggle actions
  • Add optimistic updates for toggle UI
  • Add error handling and rollback on failure
  • Update type definitions in types/security.ts

Validation:

  • Run tests/security/security-dashboard.spec.ts - expect 7 additional tests passing
  • Run tests/security/rate-limiting.spec.ts - expect 1 additional test passing
  • Backend coverage: verify ≥85%
  • E2E: verify toggle state persists across page reloads

Success Criteria:

  • All 8 toggle-related tests passing
  • State persists in DB across restarts
  • Middleware honors enabled/disabled state
  • No regression in existing security tests

Estimated Completion: 2 days


Phase 5: TestDataManager Authentication Fix (High Priority)

Target: Fix authenticated API context in test fixtures Tests Enabled: 8 tests (user management CRUD operations) Effort: M (Medium) - 8-12 hours Priority: P1 - Blocks user management test coverage Dependencies: None (can run parallel to Phase 4) Status: 🔸 INFRASTRUCTURE COMPLETE (2026-01-24) - Tests blocked by environment config

Problem Statement

TestDataManager uses raw APIRequestContext that doesn't inherit browser authentication cookies, causing "Admin access required" (401/403) errors when creating test data via API.

Root Cause: Cookie domain mismatch

  • Auth setup creates cookies for localhost domain
  • Tests may run against 100.98.12.109:8080 (Tailscale IP)
  • Cookies aren't sent cross-domain → API calls unauthenticated

Solution Approach

Option A: Consistent Base URL (Recommended - 4 hours)

Ensure all E2E tests use http://localhost:8080 consistently:

  1. Update playwright.config.js to force localhost
  2. Update docker-compose.e2e.yml port mappings if needed
  3. Update auth fixtures to always use localhost for cookie domain
  4. Verify TestDataManager inherits authenticated context

Option B: Cookie Domain Override (8 hours)

Modify auth setup to create cookies for both domains:

  1. Update auth.setup.ts to set cookies for multiple domains
  2. Modify TestDataManager to accept authenticated context
  3. Pass storageState to TestDataManager API context
  4. Add domain validation and fallback logic

Implementation Tasks

Auth Fixtures (3-4 hours): COMPLETE

  • Audit playwright.config.js baseURL configuration
  • Ensure PLAYWRIGHT_BASE_URL consistently uses localhost (documented requirement)
  • Update tests/auth.setup.ts cookie domain logic with validation warnings
  • Verify playwright/.auth/user.json contains correct domain
  • Add domain mismatch detection and console warnings

TestDataManager (2-3 hours): COMPLETE

  • Update TestDataManager constructor to accept APIRequestContext
  • Pass authenticated context from fixtures
  • Add defensive checks for storage state
  • Update auth-fixtures.ts with domain validation

Environment Config (1-2 hours): COMPLETE

  • Document base URL requirements in playwright.config.js
  • Create scripts/validate-e2e-auth.sh validation script
  • Update Docker compose port bindings if needed (not required - localhost works)

Testing (2-3 hours):

  • Re-enable 8 skipped user management tests
  • Verify CRUD operations work (create, read, update, delete users)
  • Test with clean DB to ensure no cookie leakage
  • Verify tests pass on both localhost and Tailscale IP (if needed)

Validation:

  • Run tests/settings/user-management.spec.ts - expect 8 additional tests passing
  • Verify no 401/403 errors in test output
  • Confirm TestDataManager creates/deletes users successfully
  • Backend logs show authenticated requests

Success Criteria:

  • All 8 TestDataManager-dependent tests passing
  • No authentication errors during test data creation
  • Cookie domain consistent across auth and tests
  • Tests remain stable across multiple runs

Estimated Completion: 1-2 days


Phase 6: User Management UI Implementation (Large Epic)

Target: Complete user management frontend Tests Enabled: 22 tests Effort: L (Large) - 40-60 hours (1-2 weeks) Priority: P2 - Feature completeness Dependencies: Phase 5 (TestDataManager) should be complete first

Scope

Implement missing UI components for comprehensive user management:

Component Breakdown:

  1. User Status Badge (2 tests) - 2 hours
  2. Role Badge (2 tests) - 2 hours
  3. Action Buttons (4 tests) - 4 hours
  4. User Invite Modal (5 tests) - 12 hours
  5. User Edit Modal (4 tests) - 10 hours
  6. Permissions Modal (5 tests) - 14 hours
  7. User List Enhancements (4 tests) - 8 hours

Epic Breakdown: Sub-Phases

Phase 6.1: Basic UI Components (8 hours)

Goal: Add status/role indicators and action buttons

Tasks:

  • Design and implement UserStatusBadge.tsx component
    • Active/Inactive/Pending states
    • Color coding (green/gray/yellow)
    • Accessible ARIA labels
  • Design and implement UserRoleBadge.tsx component
    • Admin/User role indicators
    • Icon + text format
    • Accessible role announcements
  • Add user action buttons to table rows
    • Edit user button
    • Delete user button
    • Permissions button
    • Settings button
  • Add proper data-testid attributes for testing
  • Write Storybook stories for each component
  • Unit tests for badge logic

Tests Enabled: 4 tests (badges + buttons)

Phase 6.2: User Invite Flow (12 hours)

Goal: Complete user invitation workflow

Tasks:

  • Implement InviteUserModal.tsx component
    • Email input with validation
    • Role selection dropdown
    • Permission preset options
    • Copy invite link button
  • Add invite form validation
    • Email format validation
    • Duplicate email check
    • Required field validation
  • Implement invite link copy functionality
    • Clipboard API integration
    • Toast notification on copy
    • Accessible keyboard support
  • Add React Query mutations
    • useInviteUser hook
    • Error handling and retry logic
    • Optimistic UI updates
  • Wire up "Invite User" button in header
  • E2E test validation

Tests Enabled: 5 tests (invite flow)

Phase 6.3: User Edit Modal (10 hours)

Goal: Enable editing existing user details

Tasks:

  • Implement EditUserModal.tsx component
    • Pre-filled form with user data
    • Name/email edit fields
    • Role change dropdown
    • Enable/disable toggle
  • Add form state management
    • Track changes vs original
    • Dirty state detection
    • Unsaved changes warning
  • Implement update mutation
    • useUpdateUser hook
    • Conflict resolution
    • Success/error notifications
  • Add validation logic
    • Email uniqueness check
    • Role change authorization
    • Unsaved changes prompt
  • Wire up edit button actions

Tests Enabled: 4 tests (edit flow)

Phase 6.4: Permissions Management (14 hours)

Goal: Granular permission controls per user

Tasks:

  • Implement UserPermissionsModal.tsx component
    • Permission mode selector (All/Restricted)
    • Host permission list
    • Add/remove host permissions
    • Bulk permission actions
  • Design permission UI/UX
    • Clear visual hierarchy
    • Searchable host list
    • Selected hosts chip display
    • Permission inheritance rules
  • Implement permission mutations
    • useUpdatePermissions hook
    • Batch permission updates
    • Validation and error handling
  • Add permission business logic
    • Admin users bypass restrictions
    • Owner-specific permissions
    • Permission inheritance rules
  • Wire up permissions button

Tests Enabled: 5 tests (permissions)

Phase 6.5: Delete & Management (8 hours)

Goal: Complete CRUD with delete operations

Tasks:

  • Implement DeleteUserModal.tsx confirmation
    • Warning message for admin users
    • Ownership transfer for proxy hosts
    • Cascade delete options
  • Add delete mutation
    • useDeleteUser hook
    • Optimistic removal from list
    • Rollback on error
  • Implement resend invite action
    • Resend invite link
    • Update invite timestamp
    • Notification on success
  • Add user search/filter
    • Search by name/email
    • Filter by role/status
    • Keyboard navigation
  • Polish table interactions
    • Row hover states
    • Bulk selection (future)
    • Pagination (if needed)

Tests Enabled: 4 tests (delete + mgmt)

Technical Considerations

State Management:

  • React Query for server state
  • Local state for modal open/close
  • Form state with React Hook Form or similar

Component Library:

  • Use existing UI components from frontend/src/components/ui/
  • Maintain consistent design language
  • Follow accessibility patterns from a11y instructions

API Integration:

  • All endpoints already exist in backend
  • Use existing client.ts wrapper
  • Create typed API client in frontend/src/api/users.ts

Testing Strategy:

  • Unit tests for component logic (Vitest)
  • E2E tests with Playwright (already written, currently skipped)
  • Storybook for component isolation

Implementation Order

Week 1 (5 days, 8 hours/day = 40 hours):

  • Day 1: Phase 6.1 - Basic UI Components
  • Day 2-3: Phase 6.2 - User Invite Flow
  • Day 4-5: Phase 6.3 - User Edit Modal

Week 2 (3 days, 20 hours):

  • Day 1-2: Phase 6.4 - Permissions Management
  • Day 3: Phase 6.5 - Delete & Management

Buffer: 8-12 hours for debugging, polish, E2E validation

Validation Gates

After each sub-phase:

  • Component unit tests pass (≥85% coverage)
  • Storybook story renders correctly
  • Component is accessible (run Accessibility Insights)
  • Related E2E tests pass
  • No TypeScript errors
  • Pre-commit hooks pass

Final validation:

  • All 22 user management tests passing
  • No regression in existing tests
  • Frontend coverage ≥85%
  • Manual QA of complete flow
  • Accessibility audit passes

Success Criteria:

  • All 22 user management tests passing
  • Complete CRUD operations functional
  • Permission management working
  • Accessible UI (WCAG 2.2 Level AA)
  • Responsive design on mobile/tablet
  • No console errors or warnings

Estimated Completion: 1-2 weeks (depending on resource availability)


Phase Sequencing & Dependencies

Recommended Execution:

  1. Parallel Start: Kick off Phase 4 and Phase 5 simultaneously (different team members or separate days)
  2. Phase 4 → Quick Win: Complete security toggles first for immediate impact (2 days)
  3. Phase 5 → Unblock: Complete TestDataManager fix to unblock Phase 6 (1-2 days)
  4. Phase 6 → Epic: Dedicate 1-2 week sprint to user management UI
  5. Phase 7 → Validate: Run full E2E suite, verify no regressions

Total Timeline: 2-3 weeks with dedicated resources


Risk & Mitigation

Risk Impact Likelihood Mitigation
Security toggles affect middleware behavior High Medium Extensive unit tests, feature flags, staged rollout
Cookie domain mismatch complex to fix Medium Low Start with localhost standardization, document workarounds
User Management UI scope creep Medium High Strict adherence to test requirements, defer "nice-to-haves"
E2E tests remain flaky after fixes Medium Medium Add retry logic, improve test stability, debug CI environment
Breaking changes in existing tests High Low Run full suite after each phase, maintain backwards compatibility

Success Metrics (Final Target)

Metric Current (Post-Phase 3) After Phase 4-6 Stretch Goal
Total Skipped Tests 63 25 <10
Security Module Coverage 60% 95% 100%
User Management Coverage 0% 100% 100%
Total E2E Test Pass Rate ~80% ~90% ~95%
Intentional Skips Only No Yes Yes

Final State: With Phases 4-6 complete, only intentional skips and environment-dependent tests (DNS providers, encryption rotation) will remain.


Appendix A: Full Skip Inventory

By File

File Skip Count Primary Reason
monitoring/real-time-logs.spec.ts 25 Cerberus disabled
settings/user-management.spec.ts 22 UI not implemented
settings/notifications.spec.ts 9 Template UI incomplete
security/security-dashboard.spec.ts 7 Cerberus disabled
settings/encryption-management.spec.ts 7 Rotation unavailable
integration/import-to-production.spec.ts 6 Routes not implemented
security/crowdsec-decisions.spec.ts 6 Route doesn't exist
dns-provider-crud.spec.ts 6 No providers exist
settings/system-settings.spec.ts 4 UI mismatches
settings/smtp-settings.spec.ts 3 Backend issues
settings/account-settings.spec.ts 3 Toggle behavior
security/rate-limiting.spec.ts 2 Cerberus disabled
core/navigation.spec.ts 1 Skip link TODO

Skip Types Distribution

Environment-Dependent: ████████████████████ 35 (36%)
Feature Not Implemented: ██████████████ 25 (26%)
Route/API Missing: ████████ 12 (12%)
UI Mismatch: ██████ 10 (10%)
TestDataManager Auth: █████ 8 (8%)
Flaky/Timing: ███ 5 (5%)
Intentional: ██ 3 (3%)

Appendix B: Commands

Check Current Skip Count

grep -r "test\.skip\|test\.fixme\|\.skip\(" tests/ | wc -l

Run Only Skipped Tests (for verification)

npx playwright test --grep "@skip" --project=chromium

Generate Updated Skip Report

grep -rn "test\.skip\|test\.fixme" tests/ --include="*.spec.ts" > skip-report.txt

Change Log

Date Author Change
2024-XX-XX AI Analysis Initial plan created
2026-01-22 Implementation Team Phase 3 complete - NPM/JSON import routes implemented, SMTP persistence fixed, 7 tests re-enabled
2026-01-23 QA Verification Phase 1 verified complete - Cerberus defaults to enabled, 28 additional tests now passing (98 → 63 total skipped)
2026-01-23 QA Verification E2E Coverage Discovery - Documented Docker vs Vite modes for coverage collection
2026-01-24 Implementation Team Phase 5 infrastructure complete - Cookie domain validation/warnings in auth.setup.ts, auth-fixtures.ts; documentation in playwright.config.js; validation script created. Tests remain blocked by environment config requirement (PLAYWRIGHT_BASE_URL=http://localhost:8080). Keyboard navigation test confirmed flaky (Category 6).

Appendix C: E2E Coverage Collection Discovery

Summary

E2E Playwright coverage ONLY works when running tests against the Vite dev server (localhost:5173), NOT against the Docker container (localhost:8080).

Evidence

Mode Base URL Coverage Result
Docker Container http://localhost:8080 Unknown% (0/0) - No coverage
Vite Dev Server http://localhost:5173 34.39% statements - Real coverage

Root Cause

The @bgotink/playwright-coverage library uses V8 coverage which requires:

  1. Access to source files (.ts, .tsx, .js)
  2. Source maps for mapping coverage back to original code

Only the Vite dev server exposes these. The Docker container serves minified production bundles without source access.

Correct Usage

For coverage collection (required for Codecov):

# Uses skill that starts Vite on port 5173
.github/skills/scripts/skill-runner.sh test-e2e-playwright-coverage

For quick integration testing (no coverage):

# Runs against Docker on port 8080
npx playwright test --project=chromium

Files Updated

The following documentation was updated to reflect this discovery:

  • .github/instructions/testing.instructions.md - Added Docker vs Vite mode table and usage instructions
  • .github/agents/playwright-tester.agent.md - Added E2E coverage section
  • .github/agents/QA_Security.agent.md - Updated Playwright E2E section with coverage mode guidance

CI/CD Implications

  • Local Development: Use the coverage skill when coverage is needed
  • CI Pipelines: Ensure E2E coverage jobs start Vite (not Docker) before running tests
  • Codecov Upload: Only LCOV files from Vite-mode runs will have meaningful data