Files
broswer-automation/test-direct-connection.js

244 lines
7.3 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Test script to validate the new direct connection architecture
* This script tests:
* 1. Remote server startup
* 2. Chrome extension direct connection
* 3. Tool call routing without native server
*/
import fetch from 'node-fetch';
import WebSocket from 'ws';
const REMOTE_SERVER_URL = 'http://localhost:3001';
const CHROME_WS_URL = 'ws://localhost:3001/chrome';
const MCP_HTTP_URL = 'http://localhost:3001/mcp';
console.log('🧪 Testing Direct Connection Architecture');
console.log('==========================================');
// Test 1: Check if remote server is running
async function testRemoteServerHealth() {
console.log('\n1⃣ Testing Remote Server Health...');
try {
const response = await fetch(`${REMOTE_SERVER_URL}/health`);
if (response.ok) {
const data = await response.json();
console.log('✅ Remote server is running:', data);
return true;
} else {
console.log('❌ Remote server health check failed:', response.status);
return false;
}
} catch (error) {
console.log('❌ Remote server is not accessible:', error.message);
return false;
}
}
// Test 2: Test MCP tools list via Streamable HTTP
async function testMCPToolsList() {
console.log('\n2⃣ Testing MCP Tools List (Streamable HTTP)...');
try {
// Step 1: Initialize session
const initResponse = await fetch(MCP_HTTP_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json, text/event-stream'
},
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'initialize',
params: {
protocolVersion: '2024-11-05',
capabilities: {},
clientInfo: { name: 'test-client', version: '1.0.0' }
}
})
});
if (!initResponse.ok) {
throw new Error(`Init failed: ${initResponse.status}`);
}
const sessionId = initResponse.headers.get('mcp-session-id');
console.log('✅ MCP session initialized:', sessionId);
// Step 2: List tools
const toolsResponse = await fetch(MCP_HTTP_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json, text/event-stream',
'MCP-Session-ID': sessionId
},
body: JSON.stringify({
jsonrpc: '2.0',
id: 2,
method: 'tools/list',
params: {}
})
});
if (!toolsResponse.ok) {
throw new Error(`Tools list failed: ${toolsResponse.status}`);
}
const toolsData = await toolsResponse.text();
console.log('✅ MCP tools list retrieved successfully');
console.log('📋 Available tools count:', (toolsData.match(/chrome_/g) || []).length);
return true;
} catch (error) {
console.log('❌ MCP tools list test failed:', error.message);
return false;
}
}
// Test 3: Test Chrome extension WebSocket connection
async function testChromeExtensionConnection() {
console.log('\n3⃣ Testing Chrome Extension WebSocket Connection...');
return new Promise((resolve) => {
try {
const ws = new WebSocket(CHROME_WS_URL);
let connected = false;
const timeout = setTimeout(() => {
if (!connected) {
console.log('❌ Chrome extension WebSocket connection timeout');
ws.close();
resolve(false);
}
}, 10000);
ws.on('open', () => {
connected = true;
clearTimeout(timeout);
console.log('✅ Chrome extension WebSocket connected successfully');
// Test sending a message
ws.send(JSON.stringify({
id: 'test-123',
action: 'ping',
params: {}
}));
setTimeout(() => {
ws.close();
resolve(true);
}, 1000);
});
ws.on('message', (data) => {
console.log('📨 Received message from Chrome extension:', data.toString());
});
ws.on('error', (error) => {
clearTimeout(timeout);
console.log('❌ Chrome extension WebSocket error:', error.message);
resolve(false);
});
ws.on('close', () => {
console.log('🔌 Chrome extension WebSocket connection closed');
});
} catch (error) {
console.log('❌ Chrome extension WebSocket test failed:', error.message);
resolve(false);
}
});
}
// Test 4: Test tool call via MCP (simulating Cherry Studio)
async function testToolCallViaMCP() {
console.log('\n4⃣ Testing Tool Call via MCP (Cherry Studio simulation)...');
try {
// Initialize session
const initResponse = await fetch(MCP_HTTP_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json, text/event-stream'
},
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'initialize',
params: {
protocolVersion: '2024-11-05',
capabilities: {},
clientInfo: { name: 'test-client', version: '1.0.0' }
}
})
});
const sessionId = initResponse.headers.get('mcp-session-id');
// Call a simple tool (get_windows_and_tabs)
const toolCallResponse = await fetch(MCP_HTTP_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json, text/event-stream',
'MCP-Session-ID': sessionId
},
body: JSON.stringify({
jsonrpc: '2.0',
id: 3,
method: 'tools/call',
params: {
name: 'get_windows_and_tabs',
arguments: {}
}
})
});
if (toolCallResponse.ok) {
const result = await toolCallResponse.text();
console.log('✅ Tool call executed successfully');
console.log('📊 Tool call result preview:', result.substring(0, 200) + '...');
return true;
} else {
console.log('❌ Tool call failed:', toolCallResponse.status);
return false;
}
} catch (error) {
console.log('❌ Tool call test failed:', error.message);
return false;
}
}
// Run all tests
async function runAllTests() {
console.log('🚀 Starting Direct Connection Architecture Tests...\n');
const results = {
serverHealth: await testRemoteServerHealth(),
mcpToolsList: await testMCPToolsList(),
chromeConnection: await testChromeExtensionConnection(),
toolCall: await testToolCallViaMCP()
};
console.log('\n📊 Test Results Summary:');
console.log('========================');
console.log(`Remote Server Health: ${results.serverHealth ? '✅ PASS' : '❌ FAIL'}`);
console.log(`MCP Tools List: ${results.mcpToolsList ? '✅ PASS' : '❌ FAIL'}`);
console.log(`Chrome Extension Connection: ${results.chromeConnection ? '✅ PASS' : '❌ FAIL'}`);
console.log(`Tool Call Execution: ${results.toolCall ? '✅ PASS' : '❌ FAIL'}`);
const passCount = Object.values(results).filter(Boolean).length;
const totalCount = Object.keys(results).length;
console.log(`\n🎯 Overall: ${passCount}/${totalCount} tests passed`);
if (passCount === totalCount) {
console.log('🎉 All tests passed! Direct connection architecture is working correctly.');
} else {
console.log('⚠️ Some tests failed. Please check the remote server and Chrome extension setup.');
}
}
// Run the tests
runAllTests().catch(console.error);