const WebSocket = require('ws') const base = (room) => `ws://127.0.0.1:3000/ws?room=${room}` function connect(name, room) { return new Promise((resolve, reject) => { const ws = new WebSocket(base(room)) const messages = [] ws.on('open', () => resolve({ ws, messages })) ws.on('message', (data) => messages.push(JSON.parse(data.toString()))) ws.on('error', reject) }) } function waitFor(messages, pred, timeout = 10000) { const start = Date.now() return new Promise((resolve, reject) => { const check = () => { if (pred()) return resolve(undefined) if (Date.now() - start > timeout) return reject(new Error('timeout')) setTimeout(check, 50) } check() }) } ;(async () => { const room = 'ROOMFULL' + Math.floor(Math.random() * 1000) const p1 = await connect('p1', room) const p2 = await connect('p2', room) await waitFor(p1.messages, () => p1.messages.some(m => m.type === 'game_state'), 5000) const p3 = await connect('p3', room) await waitFor(p3.messages, () => p3.messages.some(m => m.type === 'error'), 2000) const p3error = p3.messages.some(m => m.type === 'error' && m.message.includes('Room is full')) const p1error = p1.messages.some(m => m.type === 'error' && m.message.includes('Room is full')) const p2error = p2.messages.some(m => m.type === 'error' && m.message.includes('Room is full')) console.log({ p3error, p1error, p2error }) if (!p3error) throw new Error('p3 should get room full error') if (p1error || p2error) throw new Error('existing players should not see room-full error') p1.ws.close() p2.ws.close() p3.ws.close() process.exit(0) })().catch((e) => { console.error(e) process.exit(1) })