feat: implement semantic install dialog for CodexLens with GPU mode selection feat: add radio group component for GPU mode selection feat: update navigation and localization for API settings and semantic install
E2E Test Suite for CCW
End-to-end tests for the Claude Code Workflow (CCW) project, implementing comprehensive test scenarios based on Gemini's analysis.
Test Files
1. session-lifecycle.e2e.test.ts
Priority: HIGH - Tests the complete session lifecycle (Golden Path)
Scenarios Covered:
- ✅ Session initialization → Add tasks → Update status → Archive
- ✅ Dual parameter format support (legacy/new)
- ✅ Boundary conditions:
- Invalid JSON in task files
- Non-existent session references
- Path traversal prevention
- Concurrent task updates
- ✅ Data preservation during archiving
- ✅ Multi-location session listing
Key Test Cases:
// Golden path: Full lifecycle
init → write tasks → update status → archive
// Boundary tests
- Invalid JSON handling
- Path traversal attempts: '../../../etc/passwd'
- Concurrent updates without data loss
- Complex nested data preservation
2. dashboard-websocket.e2e.test.ts
Priority: HIGH - Tests Dashboard real-time updates via WebSocket
Scenarios Covered:
- ✅ WebSocket connection and event dispatch
- ✅ Fire-and-forget notification behavior
- ✅ Event types:
SESSION_CREATEDSESSION_UPDATEDTASK_UPDATEDSESSION_ARCHIVED
- ✅ Multiple concurrent WebSocket clients
- ✅ Network failure resilience
- ✅ Event payload validation
- ✅ Client reconnection handling
Key Test Cases:
// Real-time updates
CLI command → HTTP hook → WebSocket broadcast → Dashboard update
// Fire-and-forget verification
Request duration < 1000ms, no blocking
// Multi-client broadcast
3 concurrent clients receive same event
3. mcp-tools.e2e.test.ts
Priority: HIGH - Tests MCP JSON-RPC tool execution
Scenarios Covered:
- ✅ Tool discovery (
tools/list) - ✅ Tool execution (
tools/call) - ✅ Parameter validation
- ✅ Error handling:
- Missing required parameters
- Invalid parameter values
- Non-existent tools
- ✅ Security validation (path traversal prevention)
- ✅ Concurrent tool calls
- ✅ Tool schema completeness
Key Test Cases:
// JSON-RPC protocol
tools/list → Returns tool schemas
tools/call → Executes with parameters
// Security
Path traversal attempt: '../../../etc/passwd' → Rejected
// Concurrency
3 parallel tool calls → No interference
Running Tests
Run All E2E Tests
npm test ccw/tests/e2e/*.test.ts
Run Individual Test Suite
# Session lifecycle tests
node --experimental-strip-types --test ccw/tests/e2e/session-lifecycle.e2e.test.ts
# WebSocket tests
node --experimental-strip-types --test ccw/tests/e2e/dashboard-websocket.e2e.test.ts
# MCP tools tests
node --experimental-strip-types --test ccw/tests/e2e/mcp-tools.e2e.test.ts
Run with Verbose Output
node --experimental-strip-types --test --test-reporter=spec ccw/tests/e2e/*.test.ts
Test Architecture
Mock Strategy
Following Gemini's recommendations:
-
executeToolMocking (Avoided)- Tests use real
session_managertool for authenticity - Temporary directories isolate test environments
- Tests use real
-
memfsMocking (Not needed)- Tests use real filesystem with
mkdtempSync - Automatic cleanup with
afterEachhooks
- Tests use real filesystem with
-
http.requestMocking (WebSocket tests)- Custom
WebSocketClientclass for real protocol testing - Fire-and-forget behavior verified via timing measurements
- Custom
Test Fixtures
Session Lifecycle
projectRoot = mkdtempSync('/tmp/ccw-e2e-session-lifecycle-')
sessionPath = projectRoot/.workflow/active/WFS-xxx
Dashboard WebSocket
server = startServer(projectRoot, randomPort)
wsClient = new WebSocketClient()
wsClient.connect(port)
MCP Tools
mcpClient = new McpClient()
mcpClient.start() // Spawns ccw-mcp.js
mcpClient.call('tools/list', {})
Test Patterns
Arrangement-Act-Assert (AAA)
it('test description', async () => {
// Arrange
const sessionId = 'WFS-test-001';
await sessionManager.handler({ operation: 'init', ... });
// Act
const result = await sessionManager.handler({ operation: 'read', ... });
// Assert
assert.equal(result.success, true);
assert.equal(result.result.session_id, sessionId);
});
Setup and Teardown
before(async () => {
projectRoot = mkdtempSync('/tmp/ccw-test-');
process.chdir(projectRoot);
});
afterEach(() => {
rmSync(workflowPath(projectRoot), { recursive: true, force: true });
});
after(() => {
process.chdir(originalCwd);
rmSync(projectRoot, { recursive: true, force: true });
});
Error Assertion
// Verify error handling
const result = await handler({ invalid: 'params' });
assert.equal(result.success, false);
assert.ok(result.error.includes('expected error message'));
Boundary Conditions Tested
Invalid Input
- ❌ Malformed JSON in files
- ❌ Missing required parameters
- ❌ Invalid parameter types
- ❌ Non-existent resources
Security
- 🔒 Path traversal attempts:
../../../etc/passwd - 🔒 Invalid session ID formats:
bad/session/id - 🔒 Directory escape in task IDs
Concurrency
- 🔄 Multiple simultaneous task updates
- 🔄 Concurrent WebSocket clients (3+)
- 🔄 Parallel MCP tool calls
Network Failures
- 🌐 Dashboard server unreachable
- 🌐 WebSocket disconnect/reconnect
- 🌐 Fire-and-forget behavior (no blocking)
Integration with Existing Tests
These E2E tests complement existing integration tests:
ccw/tests/
├── integration/
│ ├── session-lifecycle.test.ts (Unit-level session ops)
│ ├── session-routes.test.ts (HTTP API routes)
│ └── ...
└── e2e/
├── session-lifecycle.e2e.test.ts (Full workflow golden path)
├── dashboard-websocket.e2e.test.ts (Real-time updates)
└── mcp-tools.e2e.test.ts (JSON-RPC protocol)
Difference:
- Integration tests: Test individual components in isolation
- E2E tests: Test complete user workflows across components
Coverage Goals
Based on Gemini's analysis:
- ✅ Session Lifecycle: 100% golden path coverage
- ✅ WebSocket Events: All event types (
SESSION_*,TASK_*) - ✅ MCP Tools: Core tools (
session_manager,smart_search,write_file,edit_file) - ✅ Boundary Conditions: 8+ edge cases per test suite
- ✅ Error Handling: Consistent error format validation
Known Limitations
-
File System Mock: Tests use real filesystem (not
memfs)- Reason: Ensures compatibility with actual file operations
- Trade-off: Slightly slower than in-memory tests
-
Process Spawning: MCP tests spawn real Node processes
- Reason: Verifies JSON-RPC stdio protocol accurately
- Trade-off: Platform-dependent (requires Node.js)
-
Network Timing: WebSocket tests may be flaky on slow systems
- Mitigation: Timeout values set to 5000ms (generous)
Future Enhancements
-
Performance Benchmarks
- Measure session operations latency
- WebSocket event dispatch time
- MCP tool execution overhead
-
Load Testing
- 100+ concurrent WebSocket clients
- Bulk session creation (1000+ sessions)
- High-frequency task updates
-
Visual Testing (Playwright)
- Dashboard UI interaction
- Real-time chart updates
- Task queue drag-and-drop
References
- Gemini Analysis: Based on comprehensive test analysis report
- Node.js Test Runner: Native test framework (no external dependencies)
- MCP Protocol: Model Context Protocol JSON-RPC specification
- WebSocket Protocol: RFC 6455 compliance
Contributing
When adding new E2E tests:
- Follow AAA pattern (Arrange-Act-Assert)
- Use descriptive test names:
it('completes full session lifecycle: init → add tasks → update status → archive') - Test both happy path and boundary conditions
- Clean up resources in
afterEachhooks - Mock console output to reduce noise:
mock.method(console, 'error', () => {}) - Add test documentation to this README
License
MIT - Same as CCW project