3 * Detailed Phase 2 Test - Canvas Desktop Endpoint
4 * Tests screen streaming integration with desktop multiplexor
7const WebSocket = require('ws');
9const [,, token, nodeId] = process.argv;
11if (!token || !nodeId) {
12 console.error('Usage: node test-phase2-detailed.js <token> <nodeId>');
16// URL encode the nodeId to handle slashes
17const encodedNodeId = encodeURIComponent(nodeId);
18const url = `wss://rmm-psa-meshcentral-aq48h.ondigitalocean.app/api/canvas-desktop/${encodedNodeId}?token=${token}`;
20console.log('========================================');
21console.log('Phase 2 Canvas Desktop Endpoint Test');
22console.log('========================================');
23console.log('Configuration:');
24console.log(` Node ID: ${nodeId}`);
25console.log(` Token: ${token.substring(0, 20)}...`);
26console.log(` URL: ${url.replace(/\?token=.*/, '?token=***')}`);
27console.log('Connecting...');
28console.log('Test running... (press Ctrl+C to stop)');
32let connectedPhase = null;
35const ws = new WebSocket(url, {
36 rejectUnauthorized: false
40 console.log('ā
WebSocket connection OPENED');
43 // Send a ping to test Phase 1 functionality
44 console.log('š¤ Sending ping...');
45 ws.send(JSON.stringify({ type: 'ping' }));
48ws.on('message', (data) => {
52 // Try to parse as JSON first (control messages)
53 const msg = JSON.parse(data.toString());
54 console.log(`šØ Message ${messageCount} received (JSON):`);
55 console.log(JSON.stringify(msg, null, 2));
58 // Extract key info from connected message
59 if (msg.type === 'connected') {
60 connectedPhase = msg.phase;
61 capabilities = msg.capabilities || [];
62 console.log(`šÆ Phase ${connectedPhase} detected`);
63 console.log(`š§ Capabilities: ${capabilities.join(', ')}`);
67 if (msg.type === 'pong') {
68 console.log('š Pong received - connection is alive');
73 // Binary data (screen frames from Phase 2)
74 if (Buffer.isBuffer(data)) {
75 console.log(`šŗ Binary frame received: ${data.length} bytes`);
76 console.log(` First 20 bytes: ${data.slice(0, 20).toString('hex')}`);
77 console.log(' ā” This is screen data from the agent!');
80 console.log(`šØ Message ${messageCount} received:`, data.toString().substring(0, 100));
86ws.on('close', (code, reason) => {
87 console.log('š WebSocket CLOSED');
88 console.log(` Code: ${code}`);
89 console.log(` Reason: ${reason || '(none)'}`);
91 console.log(`Total messages received: ${messageCount}`);
94 if (messageCount === 0) {
95 console.log('ā No messages received - connection may have failed');
96 } else if (connectedPhase === 2 && capabilities.includes('screen')) {
97 console.log('ā
Phase 2 screen streaming ready!');
98 if (messageCount === 2) {
99 console.log('ā¹ļø No screen frames received (agent not connected or no display)');
100 } else if (messageCount > 2) {
101 console.log(`ā
Received ${messageCount - 2} screen frames from agent!`);
103 } else if (connectedPhase === 1) {
104 console.log('ā ļø Phase 1 only - screen streaming not yet active');
106 console.log('ā
Normal closure (successful test)');
109 process.exit(code === 1000 ? 0 : 1);
112ws.on('error', (err) => {
113 console.error('ā WebSocket ERROR:', err.message);
117// Handle Ctrl+C gracefully
118process.on('SIGINT', () => {
119 console.log('\nā ļø Interrupted by user');
120 console.log('Closing connection...');
124// Auto-close after 10 seconds
126 console.log('ā° Test timeout reached (10 seconds)');
127 console.log('Closing connection...');