File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 11import { invariant } from 'outvariant'
2- import { FetchResponse } from '@mswjs/interceptors'
2+ import { FetchResponse , resolveWebSocketUrl } from '@mswjs/interceptors'
33import type {
44 WebSocketData ,
55 WebSocketClientConnectionProtocol ,
@@ -115,7 +115,7 @@ function createWebSocketLinkHandler(url: Path): WebSocketLink {
115115 const upgradeHandler = http . get ( ( { request } ) => {
116116 return (
117117 request . headers . get ( 'upgrade' ) ?. toLowerCase ( ) === 'websocket' &&
118- matchRequestUrl ( new URL ( request . url ) , url ) . matches
118+ matchRequestUrl ( new URL ( resolveWebSocketUrl ( request . url ) ) , url ) . matches
119119 )
120120 } , ws . onUpgrade )
121121
@@ -197,6 +197,8 @@ export const ws: WebSocketNamespace = {
197197 const digest = await crypto . subtle . digest ( 'SHA-1' , keyBytes )
198198 const acceptValue = btoa ( String . fromCharCode ( ...new Uint8Array ( digest ) ) )
199199
200+ new WebSocket ( resolveWebSocketUrl ( request . url ) )
201+
200202 return new FetchResponse ( null , {
201203 status : 101 ,
202204 headers : {
Original file line number Diff line number Diff line change 1+ import type { ws } from 'msw'
2+ import type { setupWorker } from 'msw/browser'
3+ import { test , expect } from '../playwright.extend'
4+
5+ declare global {
6+ interface Window {
7+ msw : {
8+ ws : typeof ws
9+ setupWorker : typeof setupWorker
10+ }
11+ }
12+ }
13+
14+ test ( '' , async ( { loadExample, page } ) => {
15+ await loadExample ( new URL ( './ws.runtime.js' , import . meta. url ) , {
16+ skipActivation : true ,
17+ } )
18+
19+ await page . evaluate ( async ( ) => {
20+ const { setupWorker, ws } = window . msw
21+ const service = ws . link ( 'wss://localhost/ws' )
22+
23+ const worker = setupWorker (
24+ service . addEventListener ( 'connection' , ( { client } ) => {
25+ console . log ( 'CONNECTION CALLED!' )
26+ client . send ( 'hello world' )
27+ } ) ,
28+ )
29+ await worker . start ( )
30+ } )
31+
32+ await page . evaluate ( async ( ) => {
33+ await fetch ( 'https://localhost/ws' , {
34+ headers : {
35+ upgrade : 'websocket' ,
36+ } ,
37+ } )
38+
39+ // const socket = new WebSocket('wss://example.com')
40+ // return new Promise<string>((resolve, reject) => {
41+ // socket.onmessage = (event) => resolve(event.data)
42+ // socket.onerror = () => reject(new Error('WebSocket error'))
43+ // }).finally(() => socket.close())
44+ } )
45+ } )
Original file line number Diff line number Diff line change 1+ // @vitest -environment node
2+ import { ws } from 'msw'
3+ import { setupServer } from 'msw/node'
4+
5+ const server = setupServer ( )
6+
7+ beforeAll ( ( ) => {
8+ server . listen ( )
9+ } )
10+
11+ afterEach ( ( ) => {
12+ server . resetHandlers ( )
13+ } )
14+
15+ afterAll ( ( ) => {
16+ server . close ( )
17+ } )
18+
19+ it ( 'intercepts a WebSocket connection via an HTTP request upgrade' , async ( ) => {
20+ const api = ws . link ( 'wss://localhost/ws' )
21+
22+ const connectionListener = vi . fn ( )
23+ server . use ( api . addEventListener ( 'connection' , connectionListener ) )
24+
25+ const upgradeResponse = await fetch ( 'https://localhost/ws' , {
26+ headers : {
27+ upgrade : 'websocket' ,
28+ connection : 'upgrade' ,
29+ 'sec-websocket-key' : 'abc-123' ,
30+ } ,
31+ } )
32+
33+ expect . soft ( upgradeResponse . status ) . toBe ( 101 )
34+ expect . soft ( upgradeResponse . headers . get ( 'upgrade' ) ) . toBe ( 'websocket' )
35+ expect . soft ( upgradeResponse . headers . get ( 'connection' ) ) . toBe ( 'upgrade' )
36+ expect
37+ . soft ( upgradeResponse . headers . get ( 'sec-websocket-accept' ) )
38+ . toBe ( 'apA7rfK383HiPlWh1+EOR3vC9ww=' )
39+
40+ await expect
41+ . poll ( ( ) => connectionListener )
42+ . toHaveBeenCalledExactlyOnceWith (
43+ expect . objectContaining ( {
44+ client : expect . objectContaining ( {
45+ socket : expect . objectContaining ( {
46+ url : 'wss://localhost/ws' ,
47+ } ) ,
48+ } ) ,
49+ } ) ,
50+ )
51+ } )
You can’t perform that action at this time.
0 commit comments