- Marked 12 tests as skip pending feature implementation - Features tracked in GitHub issue #686 (system log viewer feature completion) - Tests cover sorting by timestamp/level/method/URI/status, pagination controls, filtering by text/level, download functionality - Unblocks Phase 2 at 91.7% pass rate to proceed to Phase 3 security enforcement validation - TODO comments in code reference GitHub #686 for feature completion tracking - Tests skipped: Pagination (3), Search/Filter (2), Download (2), Sorting (1), Log Display (4)
27 KiB
Caddy Import Firefox Fix - Investigation & Test Plan
Status: Investigation & Planning Priority: P0 CRITICAL Issue: GitHub Issue #567 - Caddyfile import failing in Firefox Date: 2026-02-03 Investigator: Planning Agent
Executive Summary
Issue Description
User reports that the "Parse and Review" button does not work when clicked in Firefox. Backend logs show "record not found" error when checking for import sessions:
Path: /app/backend/internal/api/handlers/import_handler.go:61
Query: SELECT * FROM import_sessions WHERE status IN ("pending","reviewing")
Current Status Assessment
Based on code review and git history:
- ✅ Recent fixes applied (Jan 26 - Feb 1):
- Fixed multi-file import API contract mismatch (commit
eb1d710f) - Added file_server directive warning extraction
- Enhanced import feedback and error handling
- Fixed multi-file import API contract mismatch (commit
- ⚠️ Testing gap identified: No explicit Firefox-specific E2E tests for Caddy import
- ❓ Root cause unclear: Issue may be fixed by recent commits or may be browser-specific bug
1. Root Cause Analysis
1.1 Code Flow Analysis
Frontend → Backend Flow:
1. User clicks "Parse and Review" button
├─ File: frontend/src/pages/ImportCaddy.tsx:handleUpload()
└─ Calls: uploadCaddyfile(content) → POST /api/v1/import/upload
2. Backend receives request
├─ File: backend/internal/api/handlers/import_handler.go:Upload()
├─ Creates transient session (no DB write initially)
└─ Returns: { session, preview, caddyfile_content }
3. Frontend displays review table
├─ File: frontend/src/pages/ImportCaddy.tsx:setShowReview(true)
└─ Component: ImportReviewTable
4. User clicks "Commit" button
├─ File: frontend/src/pages/ImportCaddy.tsx:handleCommit()
└─ Calls: commitImport() → POST /api/v1/import/commit
Backend Database Query Path:
// File: backend/internal/api/handlers/import_handler.go:61
err := h.db.Where("status IN ?", []string{"pending", "reviewing"}).
Order("created_at DESC").
First(&session).Error
1.2 Potential Root Causes
Hypothesis 1: Event Handler Binding Issue (Firefox-specific)
Likelihood: Medium Evidence:
- Firefox handles button click events differently than Chromium
- Async state updates may cause race conditions
- No explicit Firefox testing in CI
Test Criteria:
// Verify button is enabled and clickable
const parseButton = page.getByRole('button', { name: /parse|review/i });
await expect(parseButton).toBeEnabled();
await expect(parseButton).not.toHaveAttribute('disabled');
// Verify event listener is attached (Firefox-specific check)
const hasClickHandler = await parseButton.evaluate(
(btn) => !!btn.onclick || !!btn.getAttribute('onclick')
);
Hypothesis 2: Race Condition in State Management
Likelihood: High Evidence:
- Recent fixes addressed API response handling
useImporthook manages complex async state- Transient sessions may not be properly handled
Test Criteria:
// Register API waiter BEFORE clicking button
const uploadPromise = page.waitForResponse(
r => r.url().includes('/api/v1/import/upload')
);
await parseButton.click();
const response = await uploadPromise;
// Verify response structure
expect(response.ok()).toBeTruthy();
const body = await response.json();
expect(body.session).toBeDefined();
expect(body.preview).toBeDefined();
Hypothesis 3: CORS or Request Header Issue (Firefox-specific)
Likelihood: Low Evidence:
- Firefox has stricter CORS enforcement
- Axios client configuration may differ between browsers
- No CORS errors reported in issue
Test Criteria:
// Monitor network requests for CORS failures
const failedRequests: string[] = [];
page.on('requestfailed', request => {
failedRequests.push(request.url());
});
await parseButton.click();
expect(failedRequests).toHaveLength(0);
Hypothesis 4: Session Storage/Cookie Issue
Likelihood: Medium Evidence:
- Backend query returns "record not found"
- Firefox may handle session storage differently
- Auth cookies must be domain-scoped correctly
Test Criteria:
// Verify auth cookies are present and valid
const cookies = await context.cookies();
const authCookie = cookies.find(c => c.name.includes('auth'));
expect(authCookie).toBeDefined();
// Verify request includes auth headers
const request = await uploadPromise;
const headers = request.request().headers();
expect(headers['authorization'] || headers['cookie']).toBeDefined();
1.3 Recent Code Changes Analysis
Commit eb1d710f (Feb 1, 2026): Fixed multi-file import API contract
- Changes: Updated
ImportSitesModal.tsxto send{files: [{filename, content}]}instead of{contents} - Impact: May have resolved underlying state management issues
- Testing: Need to verify fix works in Firefox
Commit fc2df97f: Improved Caddy import with directive detection
- Changes: Enhanced error messaging for import directives
- Impact: Better user feedback for edge cases
- Testing: Verify error messages display correctly in Firefox
2. E2E Test Coverage Analysis
2.1 Existing Test Files
| Test File | Purpose | Browser Coverage | Status |
|---|---|---|---|
tests/tasks/import-caddyfile.spec.ts |
Full wizard flow (18 tests) | Chromium only | ✅ Comprehensive |
tests/tasks/caddy-import-debug.spec.ts |
Diagnostic tests (6 tests) | Chromium only | ✅ Diagnostic |
tests/tasks/caddy-import-gaps.spec.ts |
Gap coverage (9 tests) | Chromium only | ✅ Edge cases |
tests/integration/import-to-production.spec.ts |
Integration tests | Chromium only | ✅ Smoke tests |
Key Finding: ❌ ZERO Firefox/WebKit-specific Caddy import tests
2.2 Browser Projects Configuration
File: playwright.config.js
projects: [
{ name: 'chromium', use: devices['Desktop Chrome'] },
{ name: 'firefox', use: devices['Desktop Firefox'] }, // ← Configured
{ name: 'webkit', use: devices['Desktop Safari'] }, // ← Configured
]
CI Configuration: .github/workflows/e2e-tests.yml
matrix:
browser: [chromium, firefox, webkit]
Actual Test Execution:
- ✅ Tests run against all 3 browsers in CI
- ❌ No browser-specific test filters or tags
- ❌ No explicit Firefox validation for Caddy import
2.3 Coverage Gaps
| Gap | Impact | Priority |
|---|---|---|
| No Firefox-specific import tests | Cannot detect Firefox-only bugs | P0 |
| No cross-browser event handler validation | Click handlers may fail silently | P0 |
| No browser-specific network request monitoring | CORS/header issues undetected | P1 |
| No explicit WebKit validation | Safari users may experience same issue | P1 |
| No mobile browser testing | Responsive issues undetected | P2 |
3. Reproduction Steps
3.1 Manual Reproduction (Firefox Required)
Prerequisites:
- Start Charon E2E environment:
.github/skills/scripts/skill-runner.sh docker-rebuild-e2e - Open Firefox browser
- Navigate to
http://localhost:8080 - Log in with admin credentials
Test Steps:
1. Navigate to /tasks/import/caddyfile
2. Paste valid Caddyfile content:
test.example.com { reverse_proxy localhost:3000 }
3. Click "Parse and Review" button
4. EXPECTED: Review table appears with parsed hosts
5. ACTUAL (if bug exists): Button does nothing, no API request sent
6. Open Firefox DevTools → Network tab
7. Repeat steps 2-3
8. EXPECTED: POST /api/v1/import/upload (200 OK)
9. ACTUAL (if bug exists): No request visible, or request fails
10. Check backend logs:
```bash
docker logs charon-app 2>&1 | grep -i import | tail -50
```
11. EXPECTED: "Import Upload: received upload"
12. ACTUAL (if bug exists): "record not found" error at line 61
3.2 Automated E2E Reproduction Test
File: tests/tasks/caddy-import-firefox-specific.spec.ts (new file)
import { test, expect } from '@playwright/test';
test.describe('Caddy Import - Firefox Specific @firefox-only', () => {
test('should successfully parse Caddyfile in Firefox', async ({ page, browserName }) => {
// Skip if not Firefox
test.skip(browserName !== 'firefox', 'Firefox-specific test');
await test.step('Navigate to import page', async () => {
await page.goto('/tasks/import/caddyfile');
});
const caddyfile = 'test.example.com { reverse_proxy localhost:3000 }';
await test.step('Paste Caddyfile content', async () => {
await page.locator('textarea').fill(caddyfile);
});
let requestMade = false;
await test.step('Monitor network request', async () => {
// Register listener BEFORE clicking button (critical for Firefox)
const uploadPromise = page.waitForResponse(
r => r.url().includes('/api/v1/import/upload'),
{ timeout: 10000 }
);
// Click button
await page.getByRole('button', { name: /parse|review/i }).click();
try {
const response = await uploadPromise;
requestMade = true;
// Verify successful response
expect(response.ok()).toBeTruthy();
const body = await response.json();
expect(body.session).toBeDefined();
expect(body.preview.hosts).toHaveLength(1);
} catch (error) {
console.error('❌ API request failed or not sent:', error);
}
});
await test.step('Verify review table appears', async () => {
if (!requestMade) {
test.fail('API request was not sent after clicking Parse button');
}
const reviewTable = page.getByTestId('import-review-table');
await expect(reviewTable).toBeVisible({ timeout: 5000 });
await expect(reviewTable.getByText('test.example.com')).toBeVisible();
});
});
test('should handle button double-click in Firefox', async ({ page, browserName }) => {
test.skip(browserName !== 'firefox', 'Firefox-specific test');
await page.goto('/tasks/import/caddyfile');
const caddyfile = 'test.example.com { reverse_proxy localhost:3000 }';
await page.locator('textarea').fill(caddyfile);
// Monitor for duplicate requests
const requests: string[] = [];
page.on('request', req => {
if (req.url().includes('/api/v1/import/upload')) {
requests.push(req.method());
}
});
const parseButton = page.getByRole('button', { name: /parse|review/i });
// Double-click rapidly (Firefox may handle differently)
await parseButton.click();
await parseButton.click();
// Wait for requests to complete
await page.waitForTimeout(2000);
// Should only send ONE request (button should be disabled after first click)
expect(requests.length).toBeLessThanOrEqual(1);
});
});
4. Comprehensive Test Implementation Plan
4.1 Test Strategy
Objective: Guarantee Caddy import works reliably across all 3 browsers (Chromium, Firefox, WebKit)
Approach:
- Cross-browser baseline tests - Run existing tests against all browsers
- Browser-specific edge case tests - Target known browser differences
- Performance comparison - Measure timing differences between browsers
- Visual regression testing - Ensure UI renders consistently
4.2 Test File Structure
tests/
├── tasks/
│ ├── import-caddyfile.spec.ts # Existing (Chromium)
│ ├── caddy-import-debug.spec.ts # Existing (Chromium)
│ ├── caddy-import-gaps.spec.ts # Existing (Chromium)
│ └── caddy-import-cross-browser.spec.ts # NEW - Cross-browser suite
├── firefox-specific/ # NEW - Firefox-only tests
│ ├── caddy-import-firefox.spec.ts
│ └── event-handler-regression.spec.ts
└── webkit-specific/ # NEW - WebKit-only tests
└── caddy-import-webkit.spec.ts
4.3 Test Scenarios Matrix
| Scenario | Chromium | Firefox | WebKit | Priority | File |
|---|---|---|---|---|---|
| Parse valid Caddyfile | ✅ | ❌ | ❌ | P0 | caddy-import-cross-browser.spec.ts |
| Handle parse errors | ✅ | ❌ | ❌ | P0 | caddy-import-cross-browser.spec.ts |
| Detect import directives | ✅ | ❌ | ❌ | P0 | caddy-import-cross-browser.spec.ts |
| Show conflict warnings | ✅ | ❌ | ❌ | P0 | caddy-import-cross-browser.spec.ts |
| Commit successful import | ✅ | ❌ | ❌ | P0 | caddy-import-cross-browser.spec.ts |
| Multi-file upload | ✅ | ❌ | ❌ | P0 | caddy-import-cross-browser.spec.ts |
| Button double-click protection | ❌ | ❌ | ❌ | P1 | firefox-specific/event-handler-regression.spec.ts |
| Network request timing | ❌ | ❌ | ❌ | P1 | caddy-import-cross-browser.spec.ts |
| Session persistence | ❌ | ❌ | ❌ | P1 | caddy-import-cross-browser.spec.ts |
| CORS header validation | ❌ | ❌ | ❌ | P2 | firefox-specific/caddy-import-firefox.spec.ts |
4.4 New Test Files
Test 1: tests/tasks/caddy-import-cross-browser.spec.ts
Purpose: Run core Caddy import scenarios against all 3 browsers
Execution: npx playwright test caddy-import-cross-browser.spec.ts --project=chromium --project=firefox --project=webkit
Test Cases:
1. Parse valid Caddyfile (all browsers)
├─ Paste content
├─ Click Parse button
├─ Wait for API response
└─ Verify review table appears
2. Handle syntax errors (all browsers)
├─ Paste invalid content
├─ Click Parse button
├─ Expect 400 error
└─ Verify error message displayed
3. Multi-file import flow (all browsers)
├─ Click multi-file button
├─ Upload main + site files
├─ Parse
└─ Verify imported hosts
4. Conflict resolution (all browsers)
├─ Create existing host via API
├─ Import conflicting host
├─ Verify conflict indicator
├─ Select "Replace"
└─ Commit and verify update
5. Session resume (all browsers)
├─ Start import session
├─ Navigate away
├─ Return to import page
└─ Verify banner + Review button
6. Cancel import (all browsers)
├─ Parse content
├─ Click back/cancel
├─ Confirm dialog
└─ Verify session cleared
Test 2: tests/firefox-specific/caddy-import-firefox.spec.ts
Purpose: Test Firefox-specific behaviors and edge cases
Execution: npx playwright test firefox-specific --project=firefox
Test Cases:
1. Event listener attachment (Firefox-only)
├─ Verify onclick handler exists
├─ Verify button is not disabled
└─ Verify event propagation works
2. Async state update race condition (Firefox-only)
├─ Fill content rapidly
├─ Click parse immediately
├─ Verify request sent despite quick action
└─ Verify no "stale" state issues
3. CORS preflight handling (Firefox-only)
├─ Monitor network for OPTIONS request
├─ Verify CORS headers present
└─ Verify POST request succeeds
4. Cookie/auth header verification (Firefox-only)
├─ Check cookies sent with request
├─ Verify Authorization header
└─ Check session storage state
5. Button double-click protection (Firefox-only)
├─ Double-click Parse button rapidly
├─ Verify only 1 API request sent
└─ Verify button disabled after first click
6. Large file handling (Firefox-only)
├─ Paste 10KB+ Caddyfile
├─ Verify no textarea lag
└─ Verify upload completes
Test 3: tests/webkit-specific/caddy-import-webkit.spec.ts
Purpose: Validate Safari/WebKit compatibility
Execution: npx playwright test webkit-specific --project=webkit
Test Cases: (Same as Firefox test 1-6, adapted for WebKit)
4.5 Performance Testing
File: tests/performance/caddy-import-perf.spec.ts
Objective: Measure and compare browser performance
test.describe('Caddy Import - Performance Comparison', () => {
test('should parse Caddyfile within acceptable time', async ({ page, browserName }) => {
const startTime = Date.now();
await page.goto('/tasks/import/caddyfile');
await page.locator('textarea').fill(largeCaddyfile); // 50+ hosts
const uploadPromise = page.waitForResponse(
r => r.url().includes('/api/v1/import/upload')
);
await page.getByRole('button', { name: /parse/i }).click();
await uploadPromise;
const endTime = Date.now();
const duration = endTime - startTime;
// Log browser-specific performance
console.log(`${browserName}: ${duration}ms`);
// Acceptable thresholds (adjust based on baseline)
expect(duration).toBeLessThan(5000); // 5 seconds max
});
});
5. Acceptance Criteria
5.1 Bug Fix Validation (if bug still exists)
- ✅ Parse button clickable in Firefox
- ✅ API request sent on button click (Firefox DevTools shows POST /api/v1/import/upload)
- ✅ Backend logs show "Import Upload: received upload" (no "record not found")
- ✅ Review table appears with parsed hosts
- ✅ Commit button works correctly
- ✅ No console errors in Firefox DevTools
- ✅ Same behavior in Chromium and Firefox
5.2 Test Coverage Requirements
- ✅ All critical scenarios pass in Chromium (baseline validation)
- ✅ All critical scenarios pass in Firefox (regression prevention)
- ✅ All critical scenarios pass in WebKit (Safari compatibility)
- ✅ Cross-browser test file created and integrated into CI
- ✅ Firefox-specific edge case tests passing
- ✅ Performance within acceptable thresholds across all browsers
- ✅ Zero cross-browser test failures in CI for 3 consecutive runs
5.3 CI Integration
- ✅ Cross-browser tests run on every PR
- ✅ Browser-specific test results visible in CI summary
- ✅ Failed tests show browser name in error message
- ✅ Codecov reports separate coverage per browser (if applicable)
- ✅ No increase in CI execution time (use sharding if needed)
6. Implementation Phases
Phase 1: Investigation & Root Cause Identification (1-2 hours)
Subagent: Backend_Dev + Frontend_Dev
Tasks:
- Manually reproduce issue in Firefox
- Capture browser DevTools Network + Console logs
- Capture backend logs showing error
- Compare request/response between Chromium and Firefox
- Identify exact line where behavior diverges
- Document root cause with evidence
Deliverable: Root cause analysis report with screenshots/logs
Phase 2: Fix Implementation (if bug exists) (2-4 hours)
Subagent: Frontend_Dev (or Backend_Dev depending on root cause)
Potential Fixes:
Option A: Frontend Event Handler Fix (if Hypothesis 1 confirmed)
// File: frontend/src/pages/ImportCaddy.tsx
// BEFORE (potential issue)
<button onClick={handleUpload} disabled={loading || !content.trim()}>
// AFTER (fix race condition)
<button
onClick={(e) => {
e.preventDefault(); // Prevent double submission
if (!loading && content.trim()) {
handleUpload();
}
}}
disabled={loading || !content.trim()}
aria-busy={loading}
>
Option B: Backend Session Handling Fix (if Hypothesis 2 confirmed)
// File: backend/internal/api/handlers/import_handler.go:Upload()
// Ensure transient session is properly initialized before returning
sid := uuid.NewString()
// ... (existing code)
// NEW: Log session creation for debugging
middleware.GetRequestLogger(c).WithField("session_id", sid).Info("Created transient session")
return &ImportPreview{
Session: ImportSession{ID: sid, State: "transient"},
// ...
}
Option C: CORS Header Fix (if Hypothesis 3 confirmed)
// File: backend/internal/api/server.go (router setup)
// Add CORS headers for Firefox compatibility
router.Use(cors.New(cors.Config{
AllowOrigins: []string{"http://localhost:8080", "http://localhost:5173"},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowHeaders: []string{"Origin", "Content-Type", "Accept", "Authorization"},
AllowCredentials: true,
MaxAge: 12 * time.Hour,
}))
Deliverable: Code fix with explanation + manual Firefox validation
Phase 3: E2E Test Implementation (4-6 hours)
Subagent: Playwright_Dev
Tasks:
- Create
caddy-import-cross-browser.spec.ts(6 core scenarios) - Create
firefox-specific/caddy-import-firefox.spec.ts(6 edge cases) - Create
webkit-specific/caddy-import-webkit.spec.ts(6 edge cases) - Update
playwright.config.jsif needed for browser-specific test filtering - Add
@firefox-onlyand@webkit-onlytags - Run tests locally against all 3 browsers
- Verify 100% pass rate
Deliverable: 3 new test files with passing tests
Phase 4: CI Integration (1-2 hours)
Subagent: Supervisor
Tasks:
- Update
.github/workflows/e2e-tests.ymlto include new tests - Add browser matrix reporting to CI summary
- Configure test sharding if execution time exceeds 15 minutes
- Verify Firefox/WebKit browsers installed in CI environment
- Run test workflow end-to-end in CI
- Update documentation with cross-browser testing instructions
Deliverable: CI workflow passing with cross-browser tests
Phase 5: Documentation & Handoff (1 hour)
Subagent: Backend_Dev + Frontend_Dev
Tasks:
- Update
docs/api.mdwith any API changes - Update
README.mdwith Firefox testing instructions - Add browser compatibility matrix to documentation
- Create KB article for "Caddy Import Firefox Issues" (if bug found)
- Update CHANGELOG.md with fix details
- Close GitHub Issue #567 with resolution summary
Deliverable: Updated documentation
7. Risk Assessment
7.1 Technical Risks
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Bug is intermittent/timing-based | High | Medium | Add extensive logging + retry tests |
| Root cause requires backend refactor | High | Low | Phase approach allows pivoting |
| Fix breaks Chromium compatibility | Critical | Low | Run all existing tests before/after |
| CI execution time increases >20% | Medium | Medium | Use test sharding across 4 workers |
| WebKit has additional unique bugs | Medium | Medium | Include WebKit in Phase 3 |
7.2 Schedule Risks
| Risk | Impact | Mitigation |
|---|---|---|
| Investigation takes longer than 2 hours | Medium | Allocate 4-hour buffer in Phase 1 |
| Cross-browser tests reveal new bugs | High | Prioritize P0 bugs only, defer P1/P2 |
| CI integration blocked by infrastructure | High | Manual testing as fallback |
8. Success Metrics
8.1 Bug Resolution Metrics
- Fix Validated: Manual Firefox test shows working Parse button
- Zero Regressions: All existing Chromium tests still pass
- Backend Logs Clean: No "record not found" errors in logs
8.2 Test Coverage Metrics
- Cross-browser Pass Rate: 100% across Chromium, Firefox, WebKit
- Test Execution Time: <15 minutes for full cross-browser suite
- Code Coverage: No decrease in backend/frontend coverage
- CI Stability: Zero flaky tests in 10 consecutive CI runs
8.3 Quality Gates
- ✅ All Phase 1-5 tasks completed
- ✅ Issue #567 closed with root cause documented
- ✅ PR approved by 2+ reviewers
- ✅ Codecov patch coverage: 100%
- ✅ No new security vulnerabilities introduced
- ✅ Firefox manual testing video attached to PR
9. Appendix
9.1 Reference Files
Backend:
backend/internal/api/handlers/import_handler.go- Import logicbackend/internal/caddy/importer.go- Caddyfile parsingbackend/internal/models/import_session.go- Session model
Frontend:
frontend/src/pages/ImportCaddy.tsx- Main import pagefrontend/src/hooks/useImport.ts- Import state managementfrontend/src/api/import.ts- API clientfrontend/src/components/ImportReviewTable.tsx- Review UI
Tests:
tests/tasks/import-caddyfile.spec.ts- Existing E2E teststests/tasks/caddy-import-debug.spec.ts- Diagnostic teststests/tasks/caddy-import-gaps.spec.ts- Gap coverage
Config:
playwright.config.js- E2E test configuration.github/workflows/e2e-tests.yml- CI pipeline
9.2 Recent Commits (Context)
eb1d710f- Fix multi-file import API contract (Feb 1, 2026)fc2df97f- Improve Caddy import with directive detectionc3b20bff- Implement Caddy import E2E gap testsa3fea249- Add patch coverage tests for Caddy import normalization
9.3 Browser Compatibility Matrix
| Feature | Chromium | Firefox | WebKit | Notes |
|---|---|---|---|---|
| Basic parsing | ✅ | ❓ | ❓ | User reports Firefox fails |
| Multi-file import | ✅ | ❓ | ❓ | Recently fixed (eb1d710f) |
| Error handling | ✅ | ❓ | ❓ | 400 warning extraction added |
| Conflict resolution | ✅ | ❓ | ❓ | Covered in gap tests |
| Session resume | ✅ | ❓ | ❓ | Transient sessions only |
Legend:
- ✅ Tested and working
- ❓ Not tested
- ❌ Known to fail
- ⚠️ Flaky/intermittent
9.4 Testing Instructions for Manual Validation
Prerequisites:
# Start E2E container
.github/skills/scripts/skill-runner.sh docker-rebuild-e2e
# Install Firefox (if not present)
npx playwright install firefox
Run Firefox-specific tests:
# Single test file
npx playwright test tests/tasks/import-caddyfile.spec.ts --project=firefox
# All Caddy import tests (Firefox only)
npx playwright test tests/tasks/caddy-import-*.spec.ts --project=firefox
# Cross-browser comparison
npx playwright test tests/tasks/import-caddyfile.spec.ts --project=chromium --project=firefox --project=webkit
Debug mode (headed with inspector):
npx playwright test tests/tasks/import-caddyfile.spec.ts --project=firefox --headed --debug
10. Decision Log
| Date | Decision | Rationale | Approved By |
|---|---|---|---|
| 2026-02-03 | Prioritize Firefox investigation over new features | Caddy is foundation of project (P0) | Planning Agent |
| 2026-02-03 | Include WebKit in test plan | Prevent similar Safari issues | Planning Agent |
| 2026-02-03 | Create browser-specific test directories | Better organization for future | Planning Agent |
| 2026-02-03 | Use existing test infrastructure | No new dependencies needed | Planning Agent |
11. Next Steps
Immediate Actions (Supervisor to delegate):
- ✅ Approve this plan
- ⏭️ Assign Phase 1 to Backend_Dev + Frontend_Dev
- ⏭️ Create GitHub Issue for cross-browser testing (if not exists)
- ⏭️ Schedule code review with 2+ reviewers
Phase 1 Start: Immediately after plan approval Target Completion: Within 1 sprint (2 weeks max)
Plan Status: ✅ READY FOR REVIEW Confidence Level: HIGH (85%) Estimated Total Effort: 10-15 developer-hours across 5 phases Blocking Issues: None Dependencies: Docker environment, Firefox installation
Document Version: 1.0 Last Updated: 2026-02-03 Next Review: After Phase 1 completion