@msw/playwright 0.4.4 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/build/index.d.ts +14 -4
- package/build/index.js +41 -28
- package/package.json +5 -5
- package/src/fixture.ts +67 -35
package/README.md
CHANGED
|
@@ -66,6 +66,10 @@ test('displays the user dashboard', async ({ network, page }) => {
|
|
|
66
66
|
})
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
## Limitations
|
|
70
|
+
|
|
71
|
+
- Since `context.routeWebSocket()` provides no means of knowing which page triggered a WebSocket connection, relative WebSocket URLs in `ws.link(url)` will be resolved against the _latest_ created page in the browser context.
|
|
72
|
+
|
|
69
73
|
## Comparison
|
|
70
74
|
|
|
71
75
|
### `playwright-msw`
|
package/build/index.d.ts
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { LifeCycleEventsMap, RequestHandler, SetupApi, UnhandledRequestStrategy, WebSocketHandler } from "msw";
|
|
2
|
-
import {
|
|
2
|
+
import { BrowserContext, PlaywrightTestArgs, PlaywrightWorkerArgs, TestFixture } from "@playwright/test";
|
|
3
3
|
|
|
4
4
|
//#region src/fixture.d.ts
|
|
5
5
|
interface CreateNetworkFixtureArgs {
|
|
6
|
-
initialHandlers
|
|
6
|
+
initialHandlers?: Array<RequestHandler | WebSocketHandler>;
|
|
7
7
|
onUnhandledRequest?: UnhandledRequestStrategy;
|
|
8
|
+
/**
|
|
9
|
+
* Skip common asset requests (e.g. `*.html`, `*.css`, `*.js`, etc).
|
|
10
|
+
* This improves performance for certian projects.
|
|
11
|
+
* @default true
|
|
12
|
+
*
|
|
13
|
+
* @see https://mswjs.io/docs/api/is-common-asset-request
|
|
14
|
+
*/
|
|
15
|
+
skipAssetRequests?: boolean;
|
|
8
16
|
}
|
|
9
17
|
/**
|
|
10
18
|
* Creates a fixture that controls the network in your tests.
|
|
@@ -37,12 +45,14 @@ declare function createNetworkFixture(args?: CreateNetworkFixtureArgs): [TestFix
|
|
|
37
45
|
|
|
38
46
|
declare class NetworkFixture extends SetupApi<LifeCycleEventsMap> {
|
|
39
47
|
protected args: {
|
|
40
|
-
|
|
48
|
+
context: BrowserContext;
|
|
49
|
+
skipAssetRequests: boolean;
|
|
41
50
|
initialHandlers: Array<RequestHandler | WebSocketHandler>;
|
|
42
51
|
onUnhandledRequest?: UnhandledRequestStrategy;
|
|
43
52
|
};
|
|
44
53
|
constructor(args: {
|
|
45
|
-
|
|
54
|
+
context: BrowserContext;
|
|
55
|
+
skipAssetRequests: boolean;
|
|
46
56
|
initialHandlers: Array<RequestHandler | WebSocketHandler>;
|
|
47
57
|
onUnhandledRequest?: UnhandledRequestStrategy;
|
|
48
58
|
});
|
package/build/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { invariant } from "outvariant";
|
|
2
|
-
import { RequestHandler, SetupApi, WebSocketHandler, handleRequest } from "msw";
|
|
2
|
+
import { RequestHandler, SetupApi, WebSocketHandler, handleRequest, isCommonAssetRequest } from "msw";
|
|
3
3
|
import { CancelableCloseEvent, CancelableMessageEvent } from "@mswjs/interceptors/WebSocket";
|
|
4
4
|
|
|
5
5
|
//#region src/fixture.ts
|
|
@@ -23,9 +23,10 @@ import { CancelableCloseEvent, CancelableMessageEvent } from "@mswjs/interceptor
|
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
25
|
function createNetworkFixture(args) {
|
|
26
|
-
return [async ({
|
|
26
|
+
return [async ({ context }, use) => {
|
|
27
27
|
const worker = new NetworkFixture({
|
|
28
|
-
|
|
28
|
+
context,
|
|
29
|
+
skipAssetRequests: args?.skipAssetRequests ?? true,
|
|
29
30
|
initialHandlers: args?.initialHandlers || [],
|
|
30
31
|
onUnhandledRequest: args?.onUnhandledRequest
|
|
31
32
|
});
|
|
@@ -47,58 +48,70 @@ var NetworkFixture = class extends SetupApi {
|
|
|
47
48
|
this.args = args;
|
|
48
49
|
}
|
|
49
50
|
async start() {
|
|
50
|
-
await this.args.
|
|
51
|
+
await this.args.context.route(INTERNAL_MATCH_ALL_REG_EXP, async (route, request) => {
|
|
51
52
|
const fetchRequest = new Request(request.url(), {
|
|
52
53
|
method: request.method(),
|
|
53
54
|
headers: new Headers(await request.allHeaders()),
|
|
54
55
|
body: request.postDataBuffer()
|
|
55
56
|
});
|
|
57
|
+
/**
|
|
58
|
+
* @note Skip common asset requests (default).
|
|
59
|
+
* Playwright seems to experience performance degradation when routing all
|
|
60
|
+
* requests through the matching logic below.
|
|
61
|
+
* @see https://github.com/mswjs/playwright/issues/13
|
|
62
|
+
*/
|
|
63
|
+
if (this.args.skipAssetRequests && isCommonAssetRequest(fetchRequest)) return route.continue();
|
|
56
64
|
const handlers = this.handlersController.currentHandlers().filter((handler) => {
|
|
57
65
|
return handler instanceof RequestHandler;
|
|
58
66
|
});
|
|
59
|
-
const
|
|
67
|
+
const baseUrl = request.headers().referer ? new URL(request.headers().referer).origin : void 0;
|
|
68
|
+
/**
|
|
69
|
+
* @note Use `handleRequest` instead of `getResponse` so we can pass
|
|
70
|
+
* the `onUnhandledRequest` option as-is and benefit from MSW's default behaviors.
|
|
71
|
+
*/
|
|
72
|
+
const response = await handleRequest(fetchRequest, crypto.randomUUID(), handlers, { onUnhandledRequest: this.args.onUnhandledRequest || "bypass" }, this.emitter, { resolutionContext: {
|
|
60
73
|
quiet: true,
|
|
61
|
-
baseUrl
|
|
74
|
+
baseUrl
|
|
62
75
|
} });
|
|
63
76
|
if (response) {
|
|
64
|
-
if (response.status === 0)
|
|
65
|
-
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
route.fulfill({
|
|
77
|
+
if (response.status === 0) return route.abort();
|
|
78
|
+
return route.fulfill({
|
|
69
79
|
status: response.status,
|
|
70
80
|
headers: Object.fromEntries(response.headers),
|
|
71
81
|
body: response.body ? Buffer.from(await response.arrayBuffer()) : void 0
|
|
72
82
|
});
|
|
73
|
-
return;
|
|
74
83
|
}
|
|
75
|
-
route.continue();
|
|
84
|
+
return route.continue();
|
|
76
85
|
});
|
|
77
|
-
await this.args.
|
|
86
|
+
await this.args.context.routeWebSocket(INTERNAL_MATCH_ALL_REG_EXP, async (route) => {
|
|
78
87
|
const allWebSocketHandlers = this.handlersController.currentHandlers().filter((handler) => {
|
|
79
88
|
return handler instanceof WebSocketHandler;
|
|
80
89
|
});
|
|
81
90
|
if (allWebSocketHandlers.length === 0) {
|
|
82
|
-
|
|
91
|
+
route.connectToServer();
|
|
83
92
|
return;
|
|
84
93
|
}
|
|
85
|
-
const client = new PlaywrightWebSocketClientConnection(
|
|
86
|
-
const server = new PlaywrightWebSocketServerConnection(
|
|
94
|
+
const client = new PlaywrightWebSocketClientConnection(route);
|
|
95
|
+
const server = new PlaywrightWebSocketServerConnection(route);
|
|
96
|
+
const pages = this.args.context.pages();
|
|
97
|
+
const lastPage = pages[pages.length - 1];
|
|
98
|
+
const baseUrl = lastPage ? this.getPageUrl(lastPage) : void 0;
|
|
87
99
|
for (const handler of allWebSocketHandlers) await handler.run({
|
|
88
100
|
client,
|
|
89
101
|
server,
|
|
90
102
|
info: { protocols: [] }
|
|
91
|
-
}, { baseUrl
|
|
103
|
+
}, { baseUrl });
|
|
92
104
|
});
|
|
93
105
|
}
|
|
94
106
|
async stop() {
|
|
95
107
|
super.dispose();
|
|
96
|
-
await this
|
|
97
|
-
await unrouteWebSocket(this
|
|
108
|
+
await this.args.context.unroute(INTERNAL_MATCH_ALL_REG_EXP);
|
|
109
|
+
await unrouteWebSocket(this.args.context, INTERNAL_MATCH_ALL_REG_EXP);
|
|
98
110
|
}
|
|
99
|
-
getPageUrl() {
|
|
100
|
-
const url =
|
|
101
|
-
|
|
111
|
+
getPageUrl(page) {
|
|
112
|
+
const url = page.url();
|
|
113
|
+
if (url === "about:blank") return;
|
|
114
|
+
return decodeURI(new URL(encodeURI(url)).origin);
|
|
102
115
|
}
|
|
103
116
|
};
|
|
104
117
|
var PlaywrightWebSocketClientConnection = class {
|
|
@@ -244,11 +257,11 @@ var PlaywrightWebSocketServerConnection = class {
|
|
|
244
257
|
* Custom implementation of the missing `page.unrouteWebSocket()` to remove
|
|
245
258
|
* WebSocket route handlers from the page. Loosely inspired by `page.unroute()`.
|
|
246
259
|
*/
|
|
247
|
-
async function unrouteWebSocket(
|
|
248
|
-
if (!("_webSocketRoutes" in
|
|
249
|
-
for (let i =
|
|
250
|
-
const route =
|
|
251
|
-
if (route.url === url && (handler != null ? route.handler === handler : true))
|
|
260
|
+
async function unrouteWebSocket(target, url, handler) {
|
|
261
|
+
if (!("_webSocketRoutes" in target && Array.isArray(target._webSocketRoutes))) return;
|
|
262
|
+
for (let i = target._webSocketRoutes.length - 1; i >= 0; i--) {
|
|
263
|
+
const route = target._webSocketRoutes[i];
|
|
264
|
+
if (route.url === url && (handler != null ? route.handler === handler : true)) target._webSocketRoutes.splice(i, 1);
|
|
252
265
|
}
|
|
253
266
|
}
|
|
254
267
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@msw/playwright",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"description": "Mock Service Worker binding for Playwright",
|
|
6
6
|
"main": "./build/index.js",
|
|
7
7
|
"types": "./build/index.d.ts",
|
|
@@ -33,22 +33,22 @@
|
|
|
33
33
|
"node": ">=20.0.0"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"msw": "^2.
|
|
36
|
+
"msw": "^2.12.9"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@epic-web/test-server": "^0.1.6",
|
|
40
40
|
"@ossjs/release": "^0.10.1",
|
|
41
|
-
"@playwright/test": "^1.
|
|
41
|
+
"@playwright/test": "^1.58.1",
|
|
42
42
|
"@types/node": "^22.15.29",
|
|
43
43
|
"@types/sinon": "^21.0.0",
|
|
44
|
-
"msw": "^2.12.
|
|
44
|
+
"msw": "^2.12.9",
|
|
45
45
|
"sinon": "^21.0.1",
|
|
46
46
|
"tsdown": "^0.12.7",
|
|
47
47
|
"typescript": "^5.9.3",
|
|
48
48
|
"vite": "^7.3.1"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@mswjs/interceptors": "^0.
|
|
51
|
+
"@mswjs/interceptors": "^0.41.2",
|
|
52
52
|
"outvariant": "^1.4.3"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
package/src/fixture.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { invariant } from 'outvariant'
|
|
2
2
|
import type {
|
|
3
|
+
BrowserContext,
|
|
3
4
|
Page,
|
|
4
5
|
PlaywrightTestArgs,
|
|
5
6
|
PlaywrightWorkerArgs,
|
|
6
|
-
Request,
|
|
7
|
+
Request as PlaywrightRequest,
|
|
7
8
|
Route,
|
|
8
9
|
TestFixture,
|
|
9
10
|
WebSocketRoute,
|
|
@@ -15,6 +16,7 @@ import {
|
|
|
15
16
|
RequestHandler,
|
|
16
17
|
WebSocketHandler,
|
|
17
18
|
handleRequest,
|
|
19
|
+
isCommonAssetRequest,
|
|
18
20
|
} from 'msw'
|
|
19
21
|
import {
|
|
20
22
|
type WebSocketClientEventMap,
|
|
@@ -29,6 +31,14 @@ import {
|
|
|
29
31
|
export interface CreateNetworkFixtureArgs {
|
|
30
32
|
initialHandlers?: Array<RequestHandler | WebSocketHandler>
|
|
31
33
|
onUnhandledRequest?: UnhandledRequestStrategy
|
|
34
|
+
/**
|
|
35
|
+
* Skip common asset requests (e.g. `*.html`, `*.css`, `*.js`, etc).
|
|
36
|
+
* This improves performance for certian projects.
|
|
37
|
+
* @default true
|
|
38
|
+
*
|
|
39
|
+
* @see https://mswjs.io/docs/api/is-common-asset-request
|
|
40
|
+
*/
|
|
41
|
+
skipAssetRequests?: boolean
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
/**
|
|
@@ -57,9 +67,10 @@ export function createNetworkFixture(
|
|
|
57
67
|
{ auto: boolean },
|
|
58
68
|
] {
|
|
59
69
|
return [
|
|
60
|
-
async ({
|
|
70
|
+
async ({ context }, use) => {
|
|
61
71
|
const worker = new NetworkFixture({
|
|
62
|
-
|
|
72
|
+
context,
|
|
73
|
+
skipAssetRequests: args?.skipAssetRequests ?? true,
|
|
63
74
|
initialHandlers: args?.initialHandlers || [],
|
|
64
75
|
onUnhandledRequest: args?.onUnhandledRequest,
|
|
65
76
|
})
|
|
@@ -83,7 +94,8 @@ export const INTERNAL_MATCH_ALL_REG_EXP = /.+(__MSW_PLAYWRIGHT_PREDICATE__)?/
|
|
|
83
94
|
export class NetworkFixture extends SetupApi<LifeCycleEventsMap> {
|
|
84
95
|
constructor(
|
|
85
96
|
protected args: {
|
|
86
|
-
|
|
97
|
+
context: BrowserContext
|
|
98
|
+
skipAssetRequests: boolean
|
|
87
99
|
initialHandlers: Array<RequestHandler | WebSocketHandler>
|
|
88
100
|
onUnhandledRequest?: UnhandledRequestStrategy
|
|
89
101
|
},
|
|
@@ -93,21 +105,35 @@ export class NetworkFixture extends SetupApi<LifeCycleEventsMap> {
|
|
|
93
105
|
|
|
94
106
|
public async start(): Promise<void> {
|
|
95
107
|
// Handle HTTP requests.
|
|
96
|
-
await this.args.
|
|
108
|
+
await this.args.context.route(
|
|
97
109
|
INTERNAL_MATCH_ALL_REG_EXP,
|
|
98
|
-
async (route: Route, request:
|
|
110
|
+
async (route: Route, request: PlaywrightRequest) => {
|
|
99
111
|
const fetchRequest = new Request(request.url(), {
|
|
100
112
|
method: request.method(),
|
|
101
113
|
headers: new Headers(await request.allHeaders()),
|
|
102
|
-
body: request.postDataBuffer(),
|
|
114
|
+
body: request.postDataBuffer() as ArrayBuffer | null,
|
|
103
115
|
})
|
|
104
116
|
|
|
117
|
+
/**
|
|
118
|
+
* @note Skip common asset requests (default).
|
|
119
|
+
* Playwright seems to experience performance degradation when routing all
|
|
120
|
+
* requests through the matching logic below.
|
|
121
|
+
* @see https://github.com/mswjs/playwright/issues/13
|
|
122
|
+
*/
|
|
123
|
+
if (this.args.skipAssetRequests && isCommonAssetRequest(fetchRequest)) {
|
|
124
|
+
return route.continue()
|
|
125
|
+
}
|
|
126
|
+
|
|
105
127
|
const handlers = this.handlersController
|
|
106
128
|
.currentHandlers()
|
|
107
129
|
.filter((handler) => {
|
|
108
130
|
return handler instanceof RequestHandler
|
|
109
131
|
})
|
|
110
132
|
|
|
133
|
+
const baseUrl = request.headers().referer
|
|
134
|
+
? new URL(request.headers().referer).origin
|
|
135
|
+
: undefined
|
|
136
|
+
|
|
111
137
|
/**
|
|
112
138
|
* @note Use `handleRequest` instead of `getResponse` so we can pass
|
|
113
139
|
* the `onUnhandledRequest` option as-is and benefit from MSW's default behaviors.
|
|
@@ -123,35 +149,33 @@ export class NetworkFixture extends SetupApi<LifeCycleEventsMap> {
|
|
|
123
149
|
{
|
|
124
150
|
resolutionContext: {
|
|
125
151
|
quiet: true,
|
|
126
|
-
baseUrl
|
|
152
|
+
baseUrl,
|
|
127
153
|
},
|
|
128
154
|
},
|
|
129
155
|
)
|
|
130
156
|
|
|
131
157
|
if (response) {
|
|
132
158
|
if (response.status === 0) {
|
|
133
|
-
route.abort()
|
|
134
|
-
return
|
|
159
|
+
return route.abort()
|
|
135
160
|
}
|
|
136
161
|
|
|
137
|
-
route.fulfill({
|
|
162
|
+
return route.fulfill({
|
|
138
163
|
status: response.status,
|
|
139
164
|
headers: Object.fromEntries(response.headers),
|
|
140
165
|
body: response.body
|
|
141
166
|
? Buffer.from(await response.arrayBuffer())
|
|
142
167
|
: undefined,
|
|
143
168
|
})
|
|
144
|
-
return
|
|
145
169
|
}
|
|
146
170
|
|
|
147
|
-
route.continue()
|
|
171
|
+
return route.continue()
|
|
148
172
|
},
|
|
149
173
|
)
|
|
150
174
|
|
|
151
175
|
// Handle WebSocket connections.
|
|
152
|
-
await this.args.
|
|
176
|
+
await this.args.context.routeWebSocket(
|
|
153
177
|
INTERNAL_MATCH_ALL_REG_EXP,
|
|
154
|
-
async (
|
|
178
|
+
async (route) => {
|
|
155
179
|
const allWebSocketHandlers = this.handlersController
|
|
156
180
|
.currentHandlers()
|
|
157
181
|
.filter((handler) => {
|
|
@@ -159,12 +183,16 @@ export class NetworkFixture extends SetupApi<LifeCycleEventsMap> {
|
|
|
159
183
|
})
|
|
160
184
|
|
|
161
185
|
if (allWebSocketHandlers.length === 0) {
|
|
162
|
-
|
|
186
|
+
route.connectToServer()
|
|
163
187
|
return
|
|
164
188
|
}
|
|
165
189
|
|
|
166
|
-
const client = new PlaywrightWebSocketClientConnection(
|
|
167
|
-
const server = new PlaywrightWebSocketServerConnection(
|
|
190
|
+
const client = new PlaywrightWebSocketClientConnection(route)
|
|
191
|
+
const server = new PlaywrightWebSocketServerConnection(route)
|
|
192
|
+
|
|
193
|
+
const pages = this.args.context.pages()
|
|
194
|
+
const lastPage = pages[pages.length - 1]
|
|
195
|
+
const baseUrl = lastPage ? this.getPageUrl(lastPage) : undefined
|
|
168
196
|
|
|
169
197
|
for (const handler of allWebSocketHandlers) {
|
|
170
198
|
await handler.run(
|
|
@@ -174,7 +202,7 @@ export class NetworkFixture extends SetupApi<LifeCycleEventsMap> {
|
|
|
174
202
|
info: { protocols: [] },
|
|
175
203
|
},
|
|
176
204
|
{
|
|
177
|
-
baseUrl
|
|
205
|
+
baseUrl,
|
|
178
206
|
},
|
|
179
207
|
)
|
|
180
208
|
}
|
|
@@ -184,19 +212,23 @@ export class NetworkFixture extends SetupApi<LifeCycleEventsMap> {
|
|
|
184
212
|
|
|
185
213
|
public async stop(): Promise<void> {
|
|
186
214
|
super.dispose()
|
|
187
|
-
await this.args.
|
|
188
|
-
await unrouteWebSocket(this.args.
|
|
215
|
+
await this.args.context.unroute(INTERNAL_MATCH_ALL_REG_EXP)
|
|
216
|
+
await unrouteWebSocket(this.args.context, INTERNAL_MATCH_ALL_REG_EXP)
|
|
189
217
|
}
|
|
190
218
|
|
|
191
|
-
private getPageUrl(): string | undefined {
|
|
192
|
-
const url =
|
|
193
|
-
|
|
219
|
+
private getPageUrl(page: Page): string | undefined {
|
|
220
|
+
const url = page.url()
|
|
221
|
+
|
|
222
|
+
if (url === 'about:blank') {
|
|
223
|
+
return
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Encode/decode to preserve escape characters.
|
|
227
|
+
return decodeURI(new URL(encodeURI(url)).origin)
|
|
194
228
|
}
|
|
195
229
|
}
|
|
196
230
|
|
|
197
|
-
class PlaywrightWebSocketClientConnection
|
|
198
|
-
implements WebSocketClientConnectionProtocol
|
|
199
|
-
{
|
|
231
|
+
class PlaywrightWebSocketClientConnection implements WebSocketClientConnectionProtocol {
|
|
200
232
|
public id: string
|
|
201
233
|
public url: URL
|
|
202
234
|
|
|
@@ -298,9 +330,7 @@ class PlaywrightWebSocketClientConnection
|
|
|
298
330
|
}
|
|
299
331
|
}
|
|
300
332
|
|
|
301
|
-
class PlaywrightWebSocketServerConnection
|
|
302
|
-
implements WebSocketServerConnectionProtocol
|
|
303
|
-
{
|
|
333
|
+
class PlaywrightWebSocketServerConnection implements WebSocketServerConnectionProtocol {
|
|
304
334
|
#server?: WebSocketRoute
|
|
305
335
|
#bufferedEvents: Array<
|
|
306
336
|
Parameters<WebSocketServerConnectionProtocol['addEventListener']>
|
|
@@ -411,22 +441,24 @@ interface InternalWebSocketRoute {
|
|
|
411
441
|
* WebSocket route handlers from the page. Loosely inspired by `page.unroute()`.
|
|
412
442
|
*/
|
|
413
443
|
async function unrouteWebSocket(
|
|
414
|
-
|
|
444
|
+
target: BrowserContext,
|
|
415
445
|
url: InternalWebSocketRoute['url'],
|
|
416
446
|
handler?: InternalWebSocketRoute['handler'],
|
|
417
447
|
): Promise<void> {
|
|
418
|
-
if (
|
|
448
|
+
if (
|
|
449
|
+
!('_webSocketRoutes' in target && Array.isArray(target._webSocketRoutes))
|
|
450
|
+
) {
|
|
419
451
|
return
|
|
420
452
|
}
|
|
421
453
|
|
|
422
|
-
for (let i =
|
|
423
|
-
const route =
|
|
454
|
+
for (let i = target._webSocketRoutes.length - 1; i >= 0; i--) {
|
|
455
|
+
const route = target._webSocketRoutes[i] as InternalWebSocketRoute
|
|
424
456
|
|
|
425
457
|
if (
|
|
426
458
|
route.url === url &&
|
|
427
459
|
(handler != null ? route.handler === handler : true)
|
|
428
460
|
) {
|
|
429
|
-
|
|
461
|
+
target._webSocketRoutes.splice(i, 1)
|
|
430
462
|
}
|
|
431
463
|
}
|
|
432
464
|
}
|