## TL;DR

Never `sleep` and hope the websocket message arrived. Instead, subscribe to the socket in your test, wait on a promise that resolves when a matching message arrives (with a real timeout), and assert on the message payload. Both Playwright and Cypress let you hook page-level websocket frames or expose the app's socket client to the test. Deterministic waits make these tests fast and stable instead of flaky.

## The query

```text
how to write a test that waits for websockets properly
```

## Use this when

- Tests assert on UI that updates via websockets.
- Websocket tests are flaky because of fixed sleeps.

## Not for

- Load or soak testing of the socket server.
- Polling-based UIs; plain waits work there.

## Steps

1. Expose the app's socket client (or use the framework's websocket event hooks) so the test can observe frames. Expected output: the test can see messages the app receives.
2. Write a helper that returns a promise resolving on the first message matching a predicate, with a timeout (e.g. 5s). Expected output: a reusable waitForSocketMessage helper.
3. Trigger the action, then await the helper before asserting. Expected output: assertions run only after the message arrived.
4. Assert on the message payload and the resulting UI state. Expected output: both the wire data and the UI are verified.
5. On timeout, fail with the messages actually received to make debugging easy. Expected output: failure logs show what arrived instead.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst__8FSoHJCgVS1_KcyF60oQQ
