ws

Intercept WebSocket connections.

The ws namespace helps you create event handlers to intercept WebSocket connections.

Call signature

The ws namespace only exposes a single method called link(). The link() method creates an event handler that intercepts the WebSocket connection to the specified URL.

ws.link(url: string | URL | RegExp)

ws.ts

Source code for the `ws` namespace.

Event handler

The object returned from the ws.link() call is referred to as event handler. The event handler object has the following properties and methods:

.on(event, listener)

Adds a connection listener for the outgoing WebSocket client connections.

.clients

  • Set<WebSocketClientConnection>

The set of all active WebSocket clients.

.broadcast(data)

  • data: string | Blob | ArrayBuffer

Sends the given data to all active WebSocket clients.

const api = ws.link('wss://*')
api.broadcast('hello, everyone')

.broadcastExcept(clients, data)

  • clients: WebSocketClientConnection | Array<WebSocketClientConnection>
  • data: string | Blob | ArrayBuffer

Sends the given data to all active WebSocket clients except the given clients.

const api = ws.link('wss://*')
 
api.on('connection', ({ client }) => {
  api.broadcastExcept(client, 'all except this')
})

You can also provide an array of WebSocket client connections as the argument to clients:

const ignoredClients = Array.from(api.clients).filter((client) => {
  return client.url.includes('abc')
})
 
api.broadcastExcept(ignoredClients, 'hello')

Connection listener

ArgumentTypeDescription
clientobjectOutgoing WebSocket client connection object.
serverobjectActual WebSocket server connection object.
paramsobjectPath parameters extracted from the connection url.

The connection listener is called on every outgoing WebSocket client connection.

import { ws } from 'msw'
import { setupWorker } from 'msw/browser'
 
const api = ws.link('wss://chat.example.com')
 
const worker = setupWorker(
  api.on('connection', () => {
    console.log('client connected!')
  })
)
 
await worker.start()
 
const socket = new WebSocket('wss://chat.example.com')
socket.onopen = () => {
  console.log('connection established!')
}

In this example, the WebSocket connection to wss://chat.example.com emits the "connection" event on the api event handler because the endpoint matches the one provided to the ws.link() call. Since the connection is successful, the "open" event is also dispatched on the socket instance.

WebSocketClientConnection

The WebSocketClientConnection object represents an intercepted WebSocket client connection.

.addEventListener(event, listener, options)

.removeEventListener(event, listener, options)

.send(data)

  • data: string | Blob | ArrayBuffer

Sends data to the WebSocket client. This is equivalent to the client receiving that data from the server.

api.on('connection', ({ client }) => {
  client.send('hello')
  client.send(new Blob(['hello']))
  client.send(new TextEncoder().encode('hello'))
})

.close(code, reason)

  • code: number | undefined, default: 1000
  • reason: string | undefined

Closes the active WebSocket client connection.

api.on('connection', ({ client }) => {
  client.close()
})

Unlike the WebSocket.prototype.close() method, the client.close() method accepts non-configurable close codes. This allows you to emulate client close scenarios based on server-side errors.

api.on('connection', ({ client }) => {
  client.addEventListener('message', (event) => {
    client.close(1003, 'Invalid data')
  })
})

You can also implement custom close code and reason:

api.on('connection', ({ client }) => {
  client.close(4000, 'Custom close reason')
})

WebSocketServerConnection

The WebSocketServerConnection object represents the actual WebSocket server connection.

.connect()

Establishes connection to the actual WebSocket server.

api.on('connection', ({ server }) => {
  server.connect()
})

.addEventListener(event, listener, options)

.removeEventListener(event, listener, options)

.send(data)

  • data: string | Blob | ArrayBuffer

Sends data to the actual WebSocket server. This is equivalent to the client sending this data to the server.

api.on('connection', ({ server }) => {
  server.connect()
 
  server.addEventListener('message', (event) => {
    if (event.data === 'hello from server') {
      server.send('hello from client')
    }
  })
})