const WebSocket = require('ws') const room = 'QA' + Math.floor(Math.random() * 1000) const base = 'ws://127.0.0.1:3000/ws?room=' + room function connect(name) { return new Promise((resolve, reject) => { const ws = new WebSocket(base) const messages = [] ws.on('message', (data) => { const msg = JSON.parse(data.toString()) messages.push(msg) console.log(`[${name}]`, msg.type, msg.type === 'game_state' ? ` turn=${msg.turn_team}` : '') if (msg.type === 'joined') { resolve({ ws, messages, team: msg.team }) } }) ws.on('open', () => console.log(`[${name}] open`)) ws.on('error', (e) => { console.error(`[${name}] error`, e.message); reject(e) }) ws.on('close', (code) => console.log(`[${name}] close`, code)) }) } async function waitFor(condFn, timeout = 5000) { const start = Date.now() while (!condFn()) { if (Date.now() - start > timeout) throw new Error('Timeout waiting') await new Promise(r => setTimeout(r, 50)) } } ;(async () => { const p1 = await connect('p1') await waitFor(() => p1.messages.some(m => m.type === 'waiting')) const p2 = await connect('p2') await waitFor(() => p2.messages.some(m => m.type === 'joined')) await waitFor(() => p1.messages.some(m => m.type === 'game_state')) const state = p1.messages.find(m => m.type === 'game_state') console.log('Game state', state) const turn = state.turn_team const turnPlayer = turn === p1.team ? p1 : p2 turnPlayer.ws.send(JSON.stringify({ type: 'throw', broom_x: 0.5, broom_y: 39, weight: 7, curl: 1, friction: 1.0 })) await waitFor(() => p1.messages.some(m => m.type === 'trajectory'), 15000) await waitFor(() => p1.messages.slice(-1)[0]?.type === 'game_state', 15000) console.log('Final state after throw:', p1.messages.slice(-1)[0]) p1.ws.close() p2.ws.close() process.exit(0) })().catch(err => { console.error(err) process.exit(1) })