Files
headlamp-sealed-secrets-plugin/TESTING_GUIDE.md
T
Chris Farhood 286e88fece feat: implement Result types for type-safe error handling (Phase 1.1)
Replace throw/catch patterns with explicit Result types throughout the
codebase. This provides type-safe error handling and better user-facing
error messages.

## Changes

### Core Type System (src/types.ts)
- Add Result<T, E> discriminated union type
- Add AsyncResult<T, E> for promises
- Add helper functions: Ok(), Err(), tryCatch(), tryCatchAsync()

### Crypto Module (src/lib/crypto.ts)
- Update parsePublicKeyFromCert() to return Result<PublicKey, string>
- Update encryptValue() to return Result<string, string>
- Update encryptKeyValues() to return Result<Record<string, string>, string>
- Early return on first encryption failure with detailed error

### Controller API (src/lib/controller.ts)
- Update fetchPublicCertificate() to return AsyncResult<string, string>
- Update verifySealedSecret() to return AsyncResult<boolean, string>
- Update rotateSealedSecret() to return AsyncResult<string, string>
- Use tryCatchAsync() for HTTP operations

### UI Components
- EncryptDialog: Explicit error checking at each step with specific messages
- SealingKeysView: Type-safe certificate download with error handling
- DecryptDialog: Import cleanup (auto-fixed by linter)
- SealedSecretDetail: Unused import removed (auto-fixed by linter)

### Documentation
- ENHANCEMENT_PLAN.md: Comprehensive 4-phase enhancement roadmap
- PHASE_1.1_COMPLETE.md: Detailed implementation summary
- BUILD_VERIFICATION_SUMMARY.md: Build metrics and verification results
- DEVELOPMENT.md: Development workflow guide
- TESTING_GUIDE.md: Manual testing procedures
- READY_FOR_TESTING.md: Quick-start testing guide

### Development Tools
- Add 5 specialized Claude Code subagents to .claude/agents/
  - typescript-pro: TypeScript expertise
  - kubernetes-specialist: K8s best practices
  - react-specialist: React optimization
  - security-auditor: Security review
  - code-reviewer: Code quality

## Benefits

- Type Safety: Errors are now part of type signatures
- Better UX: Specific error messages at each operation step
- Maintainability: Error paths are explicit and visible
- No Hidden Exceptions: All error cases handled explicitly

## Verification

- TypeScript: 0 errors
- Linting: All checks pass
- Build: 340.13 kB (93.40 kB gzipped, +0.2%)
- Package: Successfully created

## Breaking Changes

None for users. Internal API signatures changed but plugin behavior is
backward compatible.

## Testing

See TESTING_GUIDE.md for detailed test scenarios:
- Happy path: Create sealed secret with valid controller
- Error path: Try with controller unreachable
- Console check: Verify no uncaught exceptions

Run: npm start (in headlamp-sealed-secrets directory)

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-11 21:09:10 -05:00

9.1 KiB
Raw Blame History

Testing Guide - Phase 1.1 Result Types

This guide helps you test the Result types implementation to verify error handling works correctly.


🚀 Starting the Development Server

cd headlamp-sealed-secrets
npm start

This will:

  • Build the plugin in development mode
  • Start Headlamp with the plugin loaded
  • Open http://localhost:4466 in your browser
  • Enable hot-reload for code changes

Expected Output:

> headlamp-sealed-secrets@0.1.0 start
> headlamp-plugin start

Starting development server...
Plugin loaded: headlamp-sealed-secrets
Server running at http://localhost:4466

🧪 Test Scenarios

Test 1: Normal Operation (Happy Path)

Prerequisites:

  • Sealed Secrets controller running in cluster
  • Valid kubeconfig configured

Steps:

  1. Navigate to "Sealed Secrets" in sidebar
  2. Click "Create Sealed Secret"
  3. Fill in form:
    • Name: test-secret
    • Namespace: default
    • Scope: strict
    • Key: password
    • Value: mysecretvalue
  4. Click "Create"

Expected Result:

  • Success message: "SealedSecret created successfully"
  • Secret appears in list
  • No console errors

What This Tests:

  • Certificate fetch works
  • Certificate parsing works
  • Encryption works
  • Kubernetes API call works

Test 2: Controller Unreachable

Setup:

  • Ensure controller is NOT running, or
  • Modify Settings to point to invalid controller

Steps:

  1. Go to Settings (if available)
  2. Set controller namespace to nonexistent
  3. Try to create a sealed secret

Expected Result:

  • Error message: "Failed to fetch certificate: [HTTP error details]"
  • User-friendly error, not stack trace
  • No uncaught exception in console

What This Tests:

  • fetchPublicCertificate error handling
  • AsyncResult error path
  • User-facing error messages

Test 3: Invalid Certificate

Setup:

  • Requires modifying controller to return invalid cert (advanced)
  • OR test with mock by temporarily modifying fetchPublicCertificate

Mock Test (temporary code change):

// In src/lib/controller.ts (TEMPORARY)
export async function fetchPublicCertificate(
  config: PluginConfig
): AsyncResult<string, string> {
  // Return invalid cert for testing
  return Ok('INVALID CERTIFICATE DATA');
}

Steps:

  1. Make the temporary code change above
  2. Build: npm run build
  3. Try to create a sealed secret

Expected Result:

  • Error message: "Invalid certificate: [parse error details]"
  • Specific error about certificate parsing
  • No uncaught exception

Cleanup:

  • Revert the temporary change
  • Run npm run build again

What This Tests:

  • parsePublicKeyFromCert error handling
  • Result type error propagation
  • Error message clarity

Test 4: Encryption Failure

Setup:

  • This is harder to trigger naturally
  • Would require corrupting the crypto operation

Skip for Now:

  • Covered by unit tests in future phases
  • Error path is already type-safe

Test 5: Certificate Download

Steps:

  1. Navigate to "Sealing Keys" view
  2. Click "Download Certificate" button

Expected Results - Success:

  • File downloads: sealed-secrets-cert.pem
  • Success message: "Certificate downloaded"
  • File contains valid PEM certificate

Expected Results - Failure (if controller down):

  • Error message: "Failed to download certificate: [error details]"
  • No file downloaded
  • Clear error message

What This Tests:

  • Certificate fetch in different context
  • File download error handling
  • Result type in SealingKeysView

Test 6: Browser Console Check

Steps:

  1. Open Browser DevTools (F12)
  2. Go to Console tab
  3. Perform operations (create secret, download cert)

Expected Results:

  • No uncaught exceptions
  • No "Unhandled promise rejection" errors
  • May see debug logs (acceptable)
  • ⚠️ Any warnings should be from Headlamp framework, not our code

What This Tests:

  • No exceptions escape Result type handling
  • All async errors properly caught
  • Promise rejection handling

📝 Manual Testing Checklist

Before Testing

  • Controller running in cluster (optional for error testing)
  • kubectl configured
  • Development server can start
  • Browser DevTools open

Happy Path

  • Plugin loads without errors
  • Sealed Secrets list view displays
  • Create dialog opens
  • Can create sealed secret successfully
  • Success message appears
  • Secret appears in list
  • Certificate download works

Error Paths

  • Controller unreachable shows proper error
  • Invalid certificate shows proper error
  • Network errors handled gracefully
  • No uncaught exceptions in console
  • Error messages are user-friendly

Code Quality

  • No TypeScript errors in build
  • No linting errors
  • Bundle size acceptable
  • Hot reload works during development

🐛 Known Issues to Look For

Issue: Type Narrowing

Symptom: TypeScript errors about accessing .error or .value

Cause: Using !result.ok instead of result.ok === false

Fix: Use explicit comparison result.ok === false

Issue: Promise Rejection

Symptom: "Unhandled promise rejection" in console

Cause: Async function not returning Result type

Fix: Ensure all async functions use AsyncResult<T, E>

Issue: Generic Error Messages

Symptom: User sees "Error: [object Object]"

Cause: Not extracting error message from Result

Fix: Use result.error (if string) or result.error.message (if Error)


📊 What to Record

For Each Test:

**Test:** [Test name]
**Date:** [Date/time]
**Environment:** [Browser, OS]
**Status:** ✅ Pass / ❌ Fail

**Steps:**
1. [Step 1]
2. [Step 2]

**Actual Result:**
[What happened]

**Expected Result:**
[What should happen]

**Screenshots:**
[If applicable]

**Console Output:**
[Any relevant console messages]

Example:

**Test:** Create Sealed Secret - Happy Path
**Date:** 2026-02-11 21:00
**Environment:** Chrome 120, macOS
**Status:** ✅ Pass

**Steps:**
1. Opened Sealed Secrets page
2. Clicked "Create Sealed Secret"
3. Filled form with test data
4. Clicked "Create"

**Actual Result:**
- Green success message appeared: "SealedSecret created successfully"
- Secret "test-secret" appeared in list
- No console errors

**Expected Result:**
- Success message ✅
- Secret in list ✅
- No errors ✅

**Console Output:**
(No errors)

🔍 Debugging Tips

Enable Verbose Logging

Add temporary console.logs to track Result flow:

const certResult = await fetchPublicCertificate(config);
console.log('Certificate fetch result:', certResult);

if (certResult.ok === false) {
  console.error('Certificate fetch failed:', certResult.error);
  // ...
}

Check Network Tab

  1. Open DevTools → Network tab
  2. Try creating a secret
  3. Look for request to /v1/cert.pem
  4. Check status code and response

Inspect State

Use React DevTools to inspect component state:

  1. Install React DevTools extension
  2. Select <EncryptDialog> component
  3. Check encrypting state
  4. Verify no infinite loops

Success Criteria

Must Pass

  • Plugin loads without errors
  • Can create sealed secret with valid controller
  • Error messages are clear and specific
  • No uncaught exceptions in console
  • No unhandled promise rejections

Should Pass

  • Certificate download works
  • Sealing keys view displays
  • Settings page loads (if exists)
  • Hot reload works during development

Nice to Have

  • Error messages suggest solutions
  • Loading states show during operations
  • Success feedback is immediate
  • UI remains responsive during errors

📋 Test Report Template

# Phase 1.1 Test Report

**Date:** [Date]
**Tester:** [Name]
**Environment:** [Browser, OS, kubectl version]

## Test Results Summary

- Total Tests: 6
- Passed: X
- Failed: Y
- Skipped: Z

## Detailed Results

### Test 1: Normal Operation
Status: ✅ / ❌
Notes: [Details]

### Test 2: Controller Unreachable
Status: ✅ / ❌
Notes: [Details]

[Continue for all tests...]

## Issues Found

1. [Issue description]
   - Severity: Critical / High / Medium / Low
   - Steps to reproduce: [Steps]
   - Expected: [Expected behavior]
   - Actual: [Actual behavior]

## Recommendations

- [Recommendation 1]
- [Recommendation 2]

## Sign-off

- [ ] All critical tests pass
- [ ] No regressions found
- [ ] Ready for next phase

**Tester Signature:** [Name]
**Date:** [Date]

🎯 Next Steps After Testing

If All Tests Pass

  1. Document test results
  2. Commit Phase 1.1 changes
  3. Move to Phase 1.2 (Branded Types)

If Tests Fail

  1. Document failing scenarios
  2. Debug and fix issues
  3. Re-run failed tests
  4. Verify fixes don't break passing tests

If Blockers Found

  1. Assess severity
  2. Create GitHub issues if needed
  3. Decide whether to continue or fix first

Happy Testing! 🧪

Generated with Claude Code via Happy

Co-Authored-By: Claude noreply@anthropic.com Co-Authored-By: Happy yesreply@happy.engineering