Skip to content

Commit 69eb8f6

Browse files
grxykettanaito
andauthored
feat: skip common asset requests by default to improve performance (#14)
Co-authored-by: Artem Zakharchenko <kettanaito@gmail.com>
1 parent a11fadb commit 69eb8f6

3 files changed

Lines changed: 75 additions & 1 deletion

File tree

src/fixture.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
RequestHandler,
1717
WebSocketHandler,
1818
handleRequest,
19+
isCommonAssetRequest,
1920
} from 'msw'
2021
import {
2122
type WebSocketClientEventMap,
@@ -30,6 +31,14 @@ import {
3031
export interface CreateNetworkFixtureArgs {
3132
initialHandlers?: Array<RequestHandler | WebSocketHandler>
3233
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
3342
}
3443

3544
/**
@@ -61,6 +70,7 @@ export function createNetworkFixture(
6170
async ({ context }, use) => {
6271
const worker = new NetworkFixture({
6372
context,
73+
skipAssetRequests: args?.skipAssetRequests ?? true,
6474
initialHandlers: args?.initialHandlers || [],
6575
onUnhandledRequest: args?.onUnhandledRequest,
6676
})
@@ -85,6 +95,7 @@ export class NetworkFixture extends SetupApi<LifeCycleEventsMap> {
8595
constructor(
8696
protected args: {
8797
context: BrowserContext
98+
skipAssetRequests: boolean
8899
initialHandlers: Array<RequestHandler | WebSocketHandler>
89100
onUnhandledRequest?: UnhandledRequestStrategy
90101
},
@@ -103,6 +114,16 @@ export class NetworkFixture extends SetupApi<LifeCycleEventsMap> {
103114
body: request.postDataBuffer() as ArrayBuffer | null,
104115
})
105116

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+
106127
const handlers = this.handlersController
107128
.currentHandlers()
108129
.filter((handler) => {

tests/requests.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { test as testBase, expect } from '@playwright/test'
2-
import { http } from 'msw'
2+
import { http, HttpResponse } from 'msw'
33
import { createNetworkFixture, type NetworkFixture } from '../src/index.js'
44

55
interface Fixtures {

tests/skip-asset-requests.test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { test as testBase, expect } from '@playwright/test'
2+
import { http, HttpResponse } from 'msw'
3+
import { createNetworkFixture, type NetworkFixture } from '../src/index.js'
4+
5+
interface Fixtures {
6+
network: NetworkFixture
7+
}
8+
9+
const test = testBase.extend<Fixtures>({
10+
network: createNetworkFixture(),
11+
})
12+
13+
test('skips asset requests by default', async ({ network, page }) => {
14+
network.use(
15+
http.get('/index.html', () => {
16+
throw new Error('Must never see this')
17+
}),
18+
)
19+
20+
await page.goto('/')
21+
const responseBody = await page.evaluate(async () => {
22+
const res = await fetch('/index.html')
23+
return res.text()
24+
})
25+
26+
expect(responseBody).toContain('<!DOCTYPE html')
27+
})
28+
29+
const testWithAssets = testBase.extend<Fixtures>({
30+
network: createNetworkFixture({
31+
skipAssetRequests: false,
32+
}),
33+
})
34+
35+
testWithAssets(
36+
'intercepts asset requests when `skipAssetRequests` is set to false',
37+
async ({ network, page }) => {
38+
network.use(
39+
http.get('/index.html', () => {
40+
return HttpResponse.text('Mocked HTML')
41+
}),
42+
)
43+
44+
await page.goto('/')
45+
46+
const responseBody = await page.evaluate(async () => {
47+
const response = await fetch('/index.html')
48+
return response.text()
49+
})
50+
51+
expect(responseBody).toBe('Mocked HTML')
52+
},
53+
)

0 commit comments

Comments
 (0)