Skip to content

Commit 18ce9e4

Browse files
committed
Merge branch 'main' into feat/yet-another-socket-interceptor
2 parents 7ab764e + e822e14 commit 18ce9e4

File tree

6 files changed

+92
-6
lines changed

6 files changed

+92
-6
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,11 @@ intereceptor.on('connection', ({ client }) => {
339339

340340
The `connection` event exposes the following arguments:
341341

342-
| Name | Type | Description |
343-
| -------- | --------------------------------------------------------- | ---------------------------------------------------------------- |
344-
| `client` | [`WebSocketClientConnection`](#websocketclientconnection) | An object representing a connected WebSocket client instance. |
345-
| `server` | [`WebSocketServerConnection`](#websocketserverconnection) | An object representing the original WebSocket server connection. |
342+
| Name | Type | Description |
343+
| -------- | --------------------------------------------------------- | ----------------------------------------------------------------------------------- |
344+
| `client` | [`WebSocketClientConnection`](#websocketclientconnection) | An object representing a connected WebSocket client instance. |
345+
| `server` | [`WebSocketServerConnection`](#websocketserverconnection) | An object representing the original WebSocket server connection. |
346+
| `info` | `object` | Additional WebSocket connection information (like the original client `protocols`). |
346347

347348
### `WebSocketClientConnection`
348349

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@mswjs/interceptors",
33
"description": "Low-level HTTP/HTTPS/XHR/fetch request interception library.",
4-
"version": "0.29.1",
4+
"version": "0.30.0",
55
"main": "./lib/node/index.js",
66
"module": "./lib/node/index.mjs",
77
"types": "./lib/node/index.d.ts",

src/interceptors/WebSocket/WebSocketOverride.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@ export class WebSocketOverride extends EventTarget implements WebSocket {
5151
Reflect.set(this, 'readyState', this.CONNECTING)
5252
queueMicrotask(() => {
5353
Reflect.set(this, 'readyState', this.OPEN)
54-
this.protocol = protocols ? protocols[0] : 'ws'
54+
this.protocol =
55+
typeof protocols === 'string'
56+
? protocols
57+
: Array.isArray(protocols) && protocols.length > 0
58+
? protocols[0]
59+
: ''
5560

5661
this.dispatchEvent(bindEvent(this, new Event('open')))
5762
})

src/interceptors/WebSocket/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ export type WebSocketConnectionData = {
2828
* The original WebSocket server connection.
2929
*/
3030
server: WebSocketServerConnection
31+
32+
/**
33+
* The connection information.
34+
*/
35+
info: {
36+
/**
37+
* The protocols supported by the WebSocket client.
38+
*/
39+
protocols: string | Array<string> | undefined
40+
}
3141
}
3242

3343
/**
@@ -82,6 +92,9 @@ export class WebSocketInterceptor extends Interceptor<WebSocketEventMap> {
8292
transport,
8393
createConnection
8494
),
95+
info: {
96+
protocols,
97+
},
8598
})
8699
})
87100

test/modules/WebSocket/compliance/websocket.connection.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ it('emits the correct "connection" event on the interceptor', async () => {
5757
addEventListener: expect.any(Function),
5858
removeEventListener: expect.any(Function),
5959
}),
60+
info: {
61+
protocols: undefined,
62+
},
6063
})
6164
)
6265
})
@@ -74,3 +77,22 @@ it('does not connect to the actual WebSocket server by default', async () => {
7477
expect(connectionListener).toHaveBeenCalledTimes(1)
7578
expect(realConnectionListener).not.toHaveBeenCalled()
7679
})
80+
81+
it('includes connection information in the "connection" event payload', async () => {
82+
const connectionListener = vi.fn()
83+
interceptor.once('connection', connectionListener)
84+
85+
new WebSocket('wss://example.com', ['protocol1', 'protocol2'])
86+
await waitForNextTick()
87+
88+
expect(connectionListener).toHaveBeenCalledTimes(1)
89+
expect(connectionListener).toHaveBeenNthCalledWith(
90+
1,
91+
expect.objectContaining({
92+
info: {
93+
// Preserves the client protocols as-is.
94+
protocols: ['protocol1', 'protocol2'],
95+
},
96+
})
97+
)
98+
})
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* @vitest-environment node-with-websocket
3+
* @see https://websockets.spec.whatwg.org/#dom-websocket-close
4+
*/
5+
import { it, expect, beforeAll, afterAll } from 'vitest'
6+
import { WebSocketInterceptor } from '../../../../src/interceptors/WebSocket'
7+
import { waitForWebSocketEvent } from '../utils/waitForWebSocketEvent'
8+
9+
const interceptor = new WebSocketInterceptor()
10+
11+
beforeAll(() => {
12+
interceptor.apply()
13+
})
14+
15+
afterAll(() => {
16+
interceptor.dispose()
17+
})
18+
19+
it('returns an empty string if no protocol was provided', async () => {
20+
const ws = new WebSocket('wss://example.com')
21+
expect(ws.protocol).toBe('')
22+
23+
await waitForWebSocketEvent('open', ws)
24+
expect(ws.protocol).toBe('')
25+
})
26+
27+
it('returns the protocol if a single protocol was provided', async () => {
28+
const ws = new WebSocket('wss://example.com', 'chat')
29+
30+
// The protocol is empty on the first tick.
31+
// This is where the client is waiting for the "server"
32+
// to report back what protocol was chosen.
33+
expect(ws.protocol).toBe('')
34+
35+
await waitForWebSocketEvent('open', ws)
36+
expect(ws.protocol).toBe('chat')
37+
})
38+
39+
it('returns the first protocol if an array of protocols was provided', async () => {
40+
const ws = new WebSocket('wss://example.com', ['superchat', 'chat'])
41+
expect(ws.protocol).toBe('')
42+
43+
await waitForWebSocketEvent('open', ws)
44+
expect(ws.protocol).toBe('superchat')
45+
})

0 commit comments

Comments
 (0)