diff --git a/packages/server/tests/ws-handler.test.ts b/packages/server/tests/ws-handler.test.ts index 05b5183..e476d06 100644 --- a/packages/server/tests/ws-handler.test.ts +++ b/packages/server/tests/ws-handler.test.ts @@ -21,6 +21,20 @@ function waitForMessage(ws: WebSocket): Promise { }) } +/** Consume messages until one with the given type arrives */ +function waitForMessageType(ws: WebSocket, type: string): Promise { + return new Promise((resolve) => { + function handler(event: MessageEvent) { + const msg = JSON.parse(event.data as string) as { type: string } + if (msg.type === type) { + ws.removeEventListener("message", handler) + resolve(msg) + } + } + ws.addEventListener("message", handler) + }) +} + function waitForOpen(ws: WebSocket): Promise { return new Promise((resolve) => { if (ws.readyState === WebSocket.OPEN) { @@ -75,19 +89,19 @@ describe("WebSocket handler", () => { }) const { data } = (await res.json()) as { data: { code: string; sessionId: string } } - // Connect host + // Connect host — consumes room_state + game_state from onOpen const hostWs = new WebSocket(`ws://localhost:${port}/ws/${data.code}?sessionId=${data.sessionId}`) await waitForOpen(hostWs) - await waitForMessage(hostWs) // room_state + await waitForMessageType(hostWs, "game_state") // drain initial messages - // Connect player (no sessionId) + // Connect player (no sessionId — passive until join_room) const playerWs = new WebSocket(`ws://localhost:${port}/ws/${data.code}`) await waitForOpen(playerWs) - await waitForMessage(playerWs) // initial room_state + await waitForMessageType(playerWs, "game_state") // drain initial messages // Set up listeners BEFORE sending to avoid race conditions - const playerMsgPromise = waitForMessage(playerWs) - const hostMsgPromise = waitForMessage(hostWs) + const playerMsgPromise = waitForMessageType(playerWs, "room_state") + const hostMsgPromise = waitForMessageType(hostWs, "player_joined") // Player sends join_room playerWs.send(JSON.stringify({ type: "join_room", displayName: "Player 1" }))