Files
broswer-automation/test-multi-user-complete.js

238 lines
7.6 KiB
JavaScript

/**
* Complete Multi-User System Test
* Tests the full flow: Chrome Extension → Remote Server → LiveKit Agent → Voice Commands → Chrome Extension
*/
import WebSocket from 'ws';
const SERVER_URL = 'ws://localhost:3001/chrome';
const NUM_USERS = 2;
class TestChromeUser {
constructor(userId) {
this.userId = userId;
this.ws = null;
this.sessionInfo = null;
this.connected = false;
this.liveKitAgentStarted = false;
this.receivedMessages = [];
}
async connect() {
return new Promise((resolve, reject) => {
console.log(`\n🔌 [User ${this.userId}] Connecting Chrome extension...`);
this.ws = new WebSocket(SERVER_URL);
this.ws.on('open', () => {
console.log(`✅ [User ${this.userId}] Chrome extension connected`);
this.connected = true;
// Generate unique user ID for this Chrome extension
const chromeUserId = `user_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
// Send connection info with user ID (simulating Chrome extension)
const connectionInfo = {
type: 'connection_info',
userId: chromeUserId, // Chrome extension provides its own user ID
userAgent: `TestChromeUser-${this.userId}`,
timestamp: Date.now(),
extensionId: `test-extension-${this.userId}`
};
console.log(`📤 [User ${this.userId}] Sending connection info with user ID: ${chromeUserId}`);
this.ws.send(JSON.stringify(connectionInfo));
});
this.ws.on('message', (data) => {
try {
const message = JSON.parse(data.toString());
this.receivedMessages.push(message);
console.log(`📨 [User ${this.userId}] Received message:`, message);
if (message.type === 'session_info') {
this.sessionInfo = message.sessionInfo;
console.log(`🎯 [User ${this.userId}] Session established:`, this.sessionInfo);
// Check if LiveKit agent should be started
setTimeout(() => {
this.checkLiveKitAgent();
}, 2000);
resolve();
}
// Handle tool calls from LiveKit agent
if (message.action === 'callTool') {
console.log(`🔧 [User ${this.userId}] Received tool call from LiveKit agent:`, message.params);
// Simulate Chrome extension response
const response = {
id: message.id,
success: true,
result: `Tool ${message.params.name} executed successfully for user ${this.userId}`,
timestamp: Date.now()
};
console.log(`📤 [User ${this.userId}] Sending tool response:`, response);
this.ws.send(JSON.stringify(response));
}
} catch (error) {
console.error(`❌ [User ${this.userId}] Error parsing message:`, error);
}
});
this.ws.on('close', () => {
console.log(`🔌 [User ${this.userId}] Chrome extension disconnected`);
this.connected = false;
});
this.ws.on('error', (error) => {
console.error(`❌ [User ${this.userId}] WebSocket error:`, error);
reject(error);
});
// Timeout after 10 seconds
setTimeout(() => {
if (!this.sessionInfo) {
reject(new Error(`[User ${this.userId}] Timeout waiting for session info`));
}
}, 10000);
});
}
checkLiveKitAgent() {
if (this.sessionInfo) {
console.log(`🤖 [User ${this.userId}] LiveKit agent should be running for room: mcp-chrome-user-${this.sessionInfo.userId}`);
this.liveKitAgentStarted = true;
}
}
async sendTestVoiceCommand() {
if (!this.connected || !this.ws) {
throw new Error(`[User ${this.userId}] Not connected`);
}
// Simulate a voice command that would come from LiveKit agent
const voiceCommand = {
action: 'callTool',
params: {
name: 'chrome_navigate',
arguments: {
url: `https://example.com?user=${this.userId}&test=voice_command`,
userContext: this.sessionInfo?.userId
}
},
id: `voice_${this.userId}_${Date.now()}`,
source: 'livekit_agent'
};
console.log(`🎤 [User ${this.userId}] Simulating voice command:`, voiceCommand);
this.ws.send(JSON.stringify(voiceCommand));
}
getStatus() {
return {
userId: this.userId,
connected: this.connected,
sessionInfo: this.sessionInfo,
liveKitAgentStarted: this.liveKitAgentStarted,
messagesReceived: this.receivedMessages.length
};
}
disconnect() {
if (this.ws) {
console.log(`👋 [User ${this.userId}] Disconnecting Chrome extension`);
this.ws.close();
}
}
}
async function testCompleteMultiUserSystem() {
console.log('🚀 Starting Complete Multi-User System Test...\n');
console.log('This test verifies:');
console.log('1. Chrome Extension User ID Generation');
console.log('2. Remote Server Session Management');
console.log('3. Automatic LiveKit Agent Spawning');
console.log('4. User ID Consistency Across Components');
console.log('5. Voice Command Routing\n');
const users = [];
try {
// Step 1: Connect multiple Chrome extension users
console.log('📋 STEP 1: Connecting Chrome Extension Users');
console.log('=' .repeat(50));
for (let i = 1; i <= NUM_USERS; i++) {
const user = new TestChromeUser(i);
users.push(user);
console.log(`\n🔄 Connecting User ${i}...`);
await user.connect();
console.log(`✅ User ${i} connected successfully`);
// Wait a bit between connections
await new Promise(resolve => setTimeout(resolve, 1000));
}
// Step 2: Verify session isolation
console.log('\n📋 STEP 2: Verifying Session Isolation');
console.log('=' .repeat(50));
users.forEach(user => {
const status = user.getStatus();
console.log(`👤 User ${status.userId}:`);
console.log(` Session ID: ${status.sessionInfo?.sessionId}`);
console.log(` User ID: ${status.sessionInfo?.userId}`);
console.log(` LiveKit Agent: ${status.liveKitAgentStarted ? '✅ Started' : '❌ Not Started'}`);
});
// Step 3: Test voice command routing
console.log('\n📋 STEP 3: Testing Voice Command Routing');
console.log('=' .repeat(50));
for (const user of users) {
console.log(`\n🎤 Testing voice command for User ${user.userId}...`);
await user.sendTestVoiceCommand();
// Wait for response
await new Promise(resolve => setTimeout(resolve, 2000));
}
// Step 4: Verify user isolation
console.log('\n📋 STEP 4: Verifying User Isolation');
console.log('=' .repeat(50));
users.forEach(user => {
const status = user.getStatus();
console.log(`👤 User ${status.userId}: Received ${status.messagesReceived} messages`);
});
console.log('\n✅ Multi-User System Test Completed Successfully!');
console.log('\n📊 SUMMARY:');
console.log(` Total Users: ${users.length}`);
console.log(` All Connected: ${users.every(u => u.connected)}`);
console.log(` All Have Sessions: ${users.every(u => u.sessionInfo)}`);
console.log(` All Have LiveKit Agents: ${users.every(u => u.liveKitAgentStarted)}`);
} catch (error) {
console.error('❌ Test failed:', error);
} finally {
// Cleanup
console.log('\n🧹 Cleaning up connections...');
users.forEach(user => user.disconnect());
setTimeout(() => {
console.log('✅ Test cleanup completed');
process.exit(0);
}, 2000);
}
}
// Run the test
testCompleteMultiUserSystem().catch(console.error);