Skip to content

Commit d9d07df

Browse files
committed
fix: await pushed frames
1 parent f973c69 commit d9d07df

File tree

9 files changed

+53
-53
lines changed

9 files changed

+53
-53
lines changed

src/browser/service-worker-source.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ Please consider using a custom "serviceWorker.url" option to point to the actual
177177
return registartion
178178
}
179179

180-
#onRequest(event: RequestEvent): void {
180+
async #onRequest(event: RequestEvent): Promise<void> {
181181
// Passthrough any requests performed after the interception was stopped.
182182
if (this.#stoppedAt && event.data.interceptedAt > this.#stoppedAt) {
183183
return event.postMessage('PASSTHROUGH')
@@ -197,7 +197,7 @@ Please consider using a custom "serviceWorker.url" option to point to the actual
197197
})
198198
this.#framesMap.set(event.data.id, frame)
199199

200-
this.push(frame)
200+
await this.push(frame)
201201
}
202202

203203
async #onResponse(event: ResponseEvent) {

src/browser/setup-worker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
UnhandledFrameStrategy,
1111
} from '~/core/new/on-unhandled-frame'
1212
import { UnhandledRequestCallback } from '~/core/utils/request/onUnhandledRequest'
13-
import { NetworkSource } from '~/core/new/sources'
13+
import { NetworkSource } from '~/core/new/sources/index'
1414
import { ServiceWorkerSource } from './service-worker-source'
1515
import { SetupWorkerFallbackSource } from './setup-worker-fallback-source'
1616
import { supportsServiceWorker } from './utils/supports'

src/core/new/resolve-network-frame.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ async function resolveHttpNetworkFrame(
4747
frame: HttpNetworkFrame,
4848
handlers: Array<AnyHandler>,
4949
): Promise<boolean> {
50-
const { request } = frame.data
51-
const requestId = createRequestId()
50+
const request = frame.data.request.clone()
5251
const requestCloneForLogs = request.clone()
52+
const requestId = createRequestId()
5353

5454
frame.events.emit('request:start', { request, requestId })
5555

@@ -117,6 +117,11 @@ async function resolveHttpNetworkFrame(
117117

118118
frame.events.emit('request:end', { request, requestId })
119119

120+
/**
121+
* @fixme This doesn't belong here. Different network APIs might choose
122+
* to handle logging differently (e.g. `setupServer` doesn't log at all).
123+
* This likely belongs in an abstract method on `defineNetwork()` or something.
124+
*/
120125
// Log mocked responses. Use the Network tab to observe the original network.
121126
handler.log({
122127
request: requestCloneForLogs,

src/core/new/sources/index.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,22 @@ export abstract class NetworkSource {
2727
}
2828

2929
/**
30-
* Enables this network source.
31-
* Once enabled, it will start emitting network frame events.
30+
* Enable this source and start the network interception.
3231
*/
3332
public abstract enable(): Promise<unknown>
3433

35-
public push(frame: NetworkFrame): void {
36-
this.#emitter.emit(new TypedEvent('frame', { data: frame }))
34+
/**
35+
* Push a new network frame to the underlying handlers.
36+
* @returns {Promise<void>} A Promise that resolves when the handlers
37+
* are done handling this frame.
38+
*/
39+
public async push(frame: NetworkFrame): Promise<void> {
40+
await this.#emitter.emitAsPromise(new TypedEvent('frame', { data: frame }))
3741
}
3842

43+
/**
44+
* Disable this source and stop the network interception.
45+
*/
3946
public async disable(): Promise<void> {
4047
this.#emitter.removeAllListeners()
4148
}
@@ -56,10 +63,8 @@ class BatchNetworkSource extends NetworkSource {
5663
await Promise.all(this.sources.map((source) => source.enable()))
5764
}
5865

59-
public push(frame: NetworkFrame): void {
60-
for (const source of this.sources) {
61-
source.push(frame)
62-
}
66+
public async push(frame: NetworkFrame): Promise<void> {
67+
await Promise.all(this.sources.map((source) => source.push(frame)))
6368
}
6469

6570
public async disable(): Promise<void> {

src/core/new/sources/interceptor-source.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,27 +53,21 @@ export class InterceptorSource extends NetworkSource {
5353
this.#interceptor.dispose()
5454
}
5555

56-
#onRequest({ request, controller }: HttpRequestEventMap['request'][0]): void {
56+
async #onRequest({ request, controller }: HttpRequestEventMap['request'][0]) {
5757
const httpFrame = new InterceptorHttpNetworkFrame({
5858
request,
5959
controller,
6060
})
6161

62-
/**
63-
* @todo Check if this will be okay with the async-based nature
64-
* of the interceptor's `emitAsPromise()`. Since we emit frames
65-
* into the air, interceptors won't know that a certain handler
66-
* now should be awaited before proceeding to the next handler.
67-
*/
68-
this.push(httpFrame)
62+
await this.push(httpFrame)
6963
}
7064

71-
#onWebSocketConnection(connection: WebSocketEventMap['connection'][0]) {
65+
async #onWebSocketConnection(connection: WebSocketEventMap['connection'][0]) {
7266
const webSocketFrame = new InterceptorWebSocketNetworkFrame({
7367
connection,
7468
})
7569

76-
this.push(webSocketFrame)
70+
await this.push(webSocketFrame)
7771
}
7872
}
7973

src/node/remote-process-source.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as http from 'node:http'
22
import { DeferredPromise } from '@open-draft/deferred-promise'
33
import { Socket, Server as WebSocketServer } from 'socket.io'
4-
import { NetworkSource } from '~/core/new/sources'
4+
import { NetworkSource } from '~/core/new/sources/index'
55
import { HttpNetworkFrame } from '~/core/new/frames/http-frame'
66
import {
77
deserializeHttpRequest,
@@ -22,14 +22,14 @@ export class RemoteProcessSource extends NetworkSource {
2222
this.#server.attach(this.#httpServer)
2323

2424
this.#server.on('connection', (client) => {
25-
client.on('request', (serializedRequest) => {
25+
client.on('request', async (serializedRequest) => {
2626
const request = deserializeHttpRequest(serializedRequest, client)
2727
const httpFrame = new RemoteProcessHttpNetworkFrame({
2828
request,
2929
socket: client,
3030
})
3131

32-
this.push(httpFrame)
32+
await this.push(httpFrame)
3333
})
3434

3535
client.on('websocket', () => {

src/node/setup-server-common.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,17 @@ export class SetupServerCommonApi implements SetupServerCommon {
3131
handlersController,
3232
})
3333

34-
this.events = this.network.use
34+
this.events = this.network.use as any
3535
this.use = this.network.use.bind(this.network)
3636
this.resetHandlers = this.network.resetHandlers.bind(this.network)
3737
this.restoreHandlers = this.network.restoreHandlers.bind(this.network)
3838
this.listHandlers = this.network.listHandlers.bind(this.network)
3939
}
4040

41-
public listen(...args: Array<any>): void {
41+
public listen(
42+
// eslint-disable-next-line
43+
...args: Array<any>
44+
): void {
4245
this.network.enable()
4346
}
4447

src/node/setup-server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ export class SetupServerApi
4949
this.handlersController = handlersController
5050
}
5151

52-
public listen(options: Partial<ListenOptions>): void {
52+
public listen(options?: Partial<ListenOptions>): void {
5353
super.listen()
5454

55-
if (options.remote?.enabled) {
55+
if (options?.remote?.enabled) {
5656
const remoteRequestHandler = new RemoteRequestHandler({
5757
port: options.remote.port,
5858
})
Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
/**
2-
* @vitest-environment node
3-
*/
1+
// @vitest-environment node
42
import { HttpResponse, http } from 'msw'
53
import { setupServer } from 'msw/node'
64
import { encodeBuffer } from '@mswjs/interceptors'
@@ -20,61 +18,56 @@ afterAll(() => {
2018
})
2119

2220
test('reads plain text request body as text', async () => {
23-
const res = await fetch('http://localhost/resource', {
21+
const response = await fetch('http://localhost/resource', {
2422
method: 'POST',
2523
headers: {
2624
'Content-Type': 'text/plain',
2725
},
2826
body: 'hello-world',
2927
})
30-
const body = await res.text()
3128

32-
expect(res.status).toBe(200)
33-
expect(body).toBe('hello-world')
29+
expect.soft(response.status).toBe(200)
30+
await expect.soft(response.text()).resolves.toBe('hello-world')
3431
})
3532

3633
test('reads json request body as text', async () => {
37-
const res = await fetch('http://localhost/resource', {
34+
const response = await fetch('http://localhost/resource', {
3835
method: 'POST',
3936
headers: {
4037
'Content-Type': 'application/json',
4138
},
4239
body: JSON.stringify({ firstName: 'John' }),
4340
})
44-
const body = await res.text()
4541

46-
expect(res.status).toBe(200)
47-
expect(body).toBe(`{"firstName":"John"}`)
42+
expect.soft(response.status).toBe(200)
43+
await expect.soft(response.text()).resolves.toBe(`{"firstName":"John"}`)
4844
})
4945

5046
test('reads array buffer request body as text', async () => {
51-
const res = await fetch('http://localhost/resource', {
47+
const response = await fetch('http://localhost/resource', {
5248
method: 'POST',
5349
body: encodeBuffer('hello-world'),
5450
})
55-
const body = await res.text()
5651

57-
expect(res.status).toBe(200)
58-
expect(body).toBe('hello-world')
52+
expect.soft(response.status).toBe(200)
53+
await expect.soft(response.text()).resolves.toBe('hello-world')
5954
})
6055

6156
test('reads null request body as empty text', async () => {
62-
const res = await fetch('http://localhost/resource', {
57+
const response = await fetch('http://localhost/resource', {
6358
method: 'POST',
6459
body: null as any,
6560
})
66-
const body = await res.text()
6761

68-
expect(res.status).toBe(200)
69-
expect(body).toBe('')
62+
expect.soft(response.status).toBe(200)
63+
await expect.soft(response.text()).resolves.toBe('')
7064
})
7165

7266
test('reads undefined request body as empty text', async () => {
73-
const res = await fetch('http://localhost/resource', {
67+
const response = await fetch('http://localhost/resource', {
7468
method: 'POST',
7569
})
76-
const body = await res.text()
7770

78-
expect(res.status).toBe(200)
79-
expect(body).toBe('')
71+
expect.soft(response.status).toBe(200)
72+
await expect.soft(response.text()).resolves.toBe('')
8073
})

0 commit comments

Comments
 (0)