/** * WebSocket Testing and Monitoring Utilities * Provides tools for testing WebSocket functionality and monitoring performance */ interface WebSocketTestResult { success: boolean; message: string; latency?: number; error?: string; } interface WebSocketPerformanceMetrics { connectionTime: number; averageLatency: number; messagesSent: number; messagesReceived: number; reconnections: number; errors: number; } export class WebSocketTester { private metrics: WebSocketPerformanceMetrics = { connectionTime: 0, averageLatency: 0, messagesSent: 0, messagesReceived: 0, reconnections: 0, errors: 0 }; private latencies: number[] = []; private connectionStartTime: number = 0; /** * Test basic WebSocket connection */ async testConnection(token: string): Promise { return new Promise((resolve) => { try { const { io } = require('socket.io-client'); this.connectionStartTime = Date.now(); const socket = io('http://localhost:5137', { auth: { token }, transports: ['websocket'], timeout: 5000 }); const timeout = setTimeout(() => { socket.close(); resolve({ success: false, message: 'Connection timeout (5s)', error: 'Timeout' }); }, 5000); socket.on('connect', () => { clearTimeout(timeout); const connectionTime = Date.now() - this.connectionStartTime; this.metrics.connectionTime = connectionTime; socket.close(); resolve({ success: true, message: 'Connection successful', latency: connectionTime }); }); socket.on('connect_error', (error: any) => { clearTimeout(timeout); this.metrics.errors++; resolve({ success: false, message: 'Connection failed', error: error.message }); }); } catch (error: any) { resolve({ success: false, message: 'Test setup failed', error: error.message }); } }); } /** * Test message round-trip latency */ async testMessageLatency(token: string, focusGroupId: string): Promise { return new Promise((resolve) => { try { const { io } = require('socket.io-client'); const startTime = Date.now(); const socket = io('http://localhost:5137', { auth: { token }, transports: ['websocket'], timeout: 5000 }); const timeout = setTimeout(() => { socket.close(); resolve({ success: false, message: 'Message test timeout', error: 'Timeout' }); }, 10000); socket.on('connect', () => { // Join focus group room socket.emit('join_focus_group', { focus_group_id: focusGroupId }); }); socket.on('joined_focus_group', () => { // Send a test event and measure response time const messageStartTime = Date.now(); socket.emit('test_message', { timestamp: messageStartTime }); }); socket.on('test_response', () => { clearTimeout(timeout); const latency = Date.now() - startTime; this.latencies.push(latency); this.updateLatencyMetrics(); socket.close(); resolve({ success: true, message: 'Message test successful', latency }); }); socket.on('error', (error: any) => { clearTimeout(timeout); this.metrics.errors++; socket.close(); resolve({ success: false, message: 'Message test failed', error: error.message }); }); } catch (error: any) { resolve({ success: false, message: 'Message test setup failed', error: error.message }); } }); } /** * Run comprehensive WebSocket test suite */ async runTestSuite(token: string, focusGroupId: string): Promise<{ connectionTest: WebSocketTestResult; messageTest: WebSocketTestResult; metrics: WebSocketPerformanceMetrics; }> { console.log('๐Ÿงช Starting WebSocket test suite...'); const connectionTest = await this.testConnection(token); let messageTest: WebSocketTestResult = { success: false, message: 'Skipped due to connection failure' }; if (connectionTest.success) { messageTest = await this.testMessageLatency(token, focusGroupId); } return { connectionTest, messageTest, metrics: { ...this.metrics } }; } /** * Update latency metrics */ private updateLatencyMetrics(): void { if (this.latencies.length > 0) { this.metrics.averageLatency = this.latencies.reduce((sum, lat) => sum + lat, 0) / this.latencies.length; } } /** * Start performance monitoring */ startMonitoring(websocketHook: any): () => void { const interval = setInterval(() => { if (websocketHook.isConnected) { this.logPerformanceMetrics(); } }, 30000); // Log every 30 seconds return () => clearInterval(interval); } /** * Log performance metrics */ private logPerformanceMetrics(): void { console.log('๐Ÿ“Š WebSocket Performance Metrics:', { averageLatency: `${this.metrics.averageLatency.toFixed(2)}ms`, connectionTime: `${this.metrics.connectionTime}ms`, messagesSent: this.metrics.messagesSent, messagesReceived: this.metrics.messagesReceived, reconnections: this.metrics.reconnections, errors: this.metrics.errors, uptime: this.connectionStartTime ? `${Math.round((Date.now() - this.connectionStartTime) / 1000)}s` : '0s' }); } /** * Increment message counters */ incrementMessagesSent(): void { this.metrics.messagesSent++; } incrementMessagesReceived(): void { this.metrics.messagesReceived++; } incrementReconnections(): void { this.metrics.reconnections++; } incrementErrors(): void { this.metrics.errors++; } /** * Get current metrics */ getMetrics(): WebSocketPerformanceMetrics { return { ...this.metrics }; } /** * Reset metrics */ resetMetrics(): void { this.metrics = { connectionTime: 0, averageLatency: 0, messagesSent: 0, messagesReceived: 0, reconnections: 0, errors: 0 }; this.latencies = []; } } // Global tester instance export const websocketTester = new WebSocketTester(); // Development-only testing function export async function runWebSocketDiagnostics(token: string, focusGroupId: string) { if (process.env.NODE_ENV !== 'development') { console.warn('WebSocket diagnostics only available in development mode'); return; } console.log('๐Ÿ”ง Running WebSocket diagnostics...'); const results = await websocketTester.runTestSuite(token, focusGroupId); console.log('๐Ÿ“‹ WebSocket Test Results:', { connection: results.connectionTest.success ? 'โœ… PASS' : 'โŒ FAIL', message: results.messageTest.success ? 'โœ… PASS' : 'โŒ FAIL', connectionLatency: results.connectionTest.latency ? `${results.connectionTest.latency}ms` : 'N/A', messageLatency: results.messageTest.latency ? `${results.messageTest.latency}ms` : 'N/A' }); if (!results.connectionTest.success) { console.error('โŒ Connection Error:', results.connectionTest.error); } if (!results.messageTest.success) { console.error('โŒ Message Error:', results.messageTest.error); } return results; }