Q42 of 48 · Cypress

How would you test a real-time feature (WebSockets, SSE) in Cypress?

CypressSeniorcypresswebsocketsreal-timesenior

Short answer

Short answer: Cypress can intercept the WebSocket / EventSource handshake and stub server messages by injecting custom code into `onBeforeLoad`. For more control, run a local mock WebSocket server (mock-socket, ws) and point the app at it via env var. Cypress doesn't natively intercept WebSocket frames the way it does HTTP.

Detail

WebSockets and Server-Sent Events sit outside Cypress's HTTP interception layer. Three viable patterns:

1. Stub the WebSocket on the client side. Replace window.WebSocket before the app uses it:

cy.visit('/dashboard', {
  onBeforeLoad(win) {
    class MockWS extends EventTarget {
      readyState = 1;
      send() {}
      close() {}
      simulate(data: object) {
        this.dispatchEvent(new MessageEvent('message', { data: JSON.stringify(data) }));
      }
    }
    const mock = new MockWS();
    win.WebSocket = function() { return mock; } as any;
    (win as any).__mockWs = mock;
  },
});

cy.window().its('__mockWs').invoke('simulate', { type: 'orderUpdate', id: 'o1' });
cy.get('[data-test=order-status]').should('contain', 'Updated');

This is the lightest-touch approach; the app thinks it has a real socket but you control every message.

2. Run a local mock WebSocket server. Start mock-socket or a custom ws server in your test setup. Point WS_URL env var at it; the app connects normally. The advantage is testing the full handshake/reconnect logic.

3. Use cy.intercept for SSE-over-HTTP. Server-Sent Events run over plain HTTP; cy.intercept works:

cy.intercept('GET', '/api/events', (req) => {
  req.reply({
    statusCode: 200,
    headers: { 'content-type': 'text/event-stream' },
    body: 'data: {"type":"orderUpdate","id":"o1"}\n\n',
  });
});

Things to test in any approach:

  • Initial state (empty / loading).
  • Receiving an event updates the UI.
  • Multiple events in sequence preserve order.
  • Reconnect after disconnection.
  • Backpressure / bounded buffer behaviour if the app drops messages under load.

The senior signal: knowing the architectural distinction (Cypress doesn't intercept WS frames natively), naming both client-stub and server-mock approaches, and not pretending it's as clean as HTTP stubbing.

// WHAT INTERVIEWERS LOOK FOR

Knowing Cypress doesn't intercept WS frames, the `onBeforeLoad` client-stub pattern, and the local mock server option for handshake testing.

// COMMON PITFALL

Suggesting `cy.intercept` for WebSockets — it doesn't work for the WS protocol itself, only for the upgrade request.