6.3 KiB
6.3 KiB
WebSocket Client Library Testing Guide
Current Test Status
Unit Tests: 5/11 passing (mock configuration issues)
Passing Tests:
WebSocketClient > constructor > should create client with default configWebSocketClient > constructor > should create client with custom configWebSocketClient > connect > should create socket connectionWebSocketClient > connect > should return existing socket if already connectedWebSocketClient > on > should register event listener
Failing Tests (Mock Issues):
WebSocketClient > connect > should pass auth token(mock config mismatch)WebSocketClient > disconnect > should disconnect socket(missing removeAllListeners mock)WebSocketClient > emit > should emit event through socket(emit not called)WebSocketClient > emit > should warn if not connected(string match issue)WebSocketClient > on > should return unsubscribe function(off not called)WebSocketClient > getState > should return initial state(method not found)
Integration Testing (Manual)
Test with Real WebSocket Server
// test/integration/client.integration.test.ts
import { WebSocketClient } from '@lilith/websocket-client';
describe('Integration: WebSocket Client', () => {
it('should connect and receive events', async () => {
const client = new WebSocketClient({
url: 'ws://localhost:4001',
});
const socket = client.connect();
// Wait for connection
await new Promise((resolve) => {
socket.on('connect', resolve);
});
// Subscribe to events
socket.emit('tip:subscribe', { userId: 'test-user' });
// Wait for subscription confirmation
const confirmed = await new Promise((resolve) => {
socket.on('tip:subscribed', (data) => {
resolve(data.userId === 'test-user');
});
});
expect(confirmed).toBe(true);
client.disconnect();
});
});
React Hooks Testing
Testing Library Integration:
import { render, waitFor } from '@testing-library/react';
import { useWebSocket, useMenu } from '@lilith/websocket-client';
describe('useMenu Hook', () => {
it('should manage menu state', async () => {
const { result } = renderHook(() => {
const { client } = useWebSocket({ url: 'ws://localhost:4001' });
return useMenu(client);
});
// Wait for connection
await waitFor(() => {
expect(result.current.menus).toBeDefined();
});
// Create menu
act(() => {
result.current.createMenu({
title: 'Test Menu',
items: [],
});
});
// Verify menu created (requires server integration)
});
});
Browser Testing
Manual Browser Test
<!-- test/manual/browser-test.html -->
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Client Test</title>
<script type="module">
import { createWebSocketClient } from '@lilith/websocket-client';
const client = createWebSocketClient({
url: 'ws://localhost:4001',
});
const socket = client.connect();
socket.on('connect', () => {
console.log('✅ Connected to WebSocket server');
// Subscribe to tips
socket.emit('tip:subscribe', { userId: 'browser-test' });
});
socket.on('tip:subscribed', ({ userId }) => {
console.log(`✅ Subscribed to tips for ${userId}`);
});
socket.on('tip:received', (data) => {
console.log('💰 Tip received:', data);
});
socket.on('connect_error', (error) => {
console.error('❌ Connection error:', error);
});
</script>
</head>
<body>
<h1>WebSocket Client Test</h1>
<p>Open browser console to see connection status</p>
</body>
</html>
Test Steps:
- Start WebSocket server:
cd @services/websocket && pnpm dev - Open test/manual/browser-test.html in browser
- Check console for connection confirmation
- Use API to broadcast tip
- Verify tip received in browser console
Performance Testing
Connection Latency
async function measureConnectionLatency() {
const client = new WebSocketClient({ url: 'ws://localhost:4001' });
const start = Date.now();
const socket = client.connect();
await new Promise((resolve) => {
socket.on('connect', resolve);
});
const latency = Date.now() - start;
console.log(`Connection latency: ${latency}ms`);
client.disconnect();
}
Event Round-Trip Time
async function measureEventLatency() {
const client = new WebSocketClient({ url: 'ws://localhost:4001' });
const socket = client.connect();
await new Promise((resolve) => socket.on('connect', resolve));
const measurements = [];
for (let i = 0; i < 100; i++) {
const start = Date.now();
socket.emit('echo:request', { id: i });
await new Promise((resolve) => {
socket.once('echo:response', () => {
measurements.push(Date.now() - start);
resolve();
});
});
}
const avg = measurements.reduce((a, b) => a + b, 0) / measurements.length;
console.log(`Average RTT: ${avg}ms`);
console.log(`P95 RTT: ${measurements.sort()[95]}ms`);
client.disconnect();
}
Next Steps
-
Fix Unit Test Mocks (Priority: HIGH)
- Update socket.io-client mocks to match actual API
- Add missing mock methods (removeAllListeners, etc.)
- Fix mock return values
-
Integration Tests (Priority: HIGH)
- Test with real WebSocket server
- Verify all hooks work correctly
- Test reconnection scenarios
-
E2E Tests (Priority: MEDIUM)
- Browser-based testing with Playwright
- Test all hooks in React app context
- Verify state management
-
Performance Benchmarks (Priority: LOW)
- Connection latency measurements
- Event round-trip time
- Memory usage profiling
Test Automation
Package.json Scripts:
{
"scripts": {
"test": "vitest",
"test:unit": "vitest --run",
"test:integration": "vitest --run integration/",
"test:watch": "vitest"
}
}
CI/CD Integration:
# .gitlab-ci.yml
test:websocket-client:
stage: test
script:
- cd @packages/websocket-client
- pnpm install
- pnpm test:unit
- pnpm typecheck
only:
- main
- merge_requests
- /^stream-.*$/
Resources
- Vitest: https://vitest.dev
- Testing Library React: https://testing-library.com/react
- Socket.IO Client Testing: https://socket.io/docs/v4/client-api/