@msw/playwright 0.4.0 → 0.4.2

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 CHANGED
@@ -65,3 +65,17 @@ test('displays the user dashboard', async ({ network, page }) => {
65
65
  await page.goto('/dashboard')
66
66
  })
67
67
  ```
68
+
69
+ ## Comparison
70
+
71
+ ### `playwright-msw`
72
+
73
+ [`playwright-msw`](https://github.com/valendres/playwright-msw) is a community package that, just like `@msw/playwright`, aims to provide a better experience when mocking APIs in your Playwright tests.
74
+
75
+ > While `playwright-msw` is a fantastic tool and a huge inspiration for this package to exist, I believe it approaches the idea at a rather complex angle. That introduces a layer of abstraction that is subjected to the "left behind" problem as it needs to map to any MSW changes explicitly.
76
+
77
+ | | `playwright-msw` | `@msw/playwright` |
78
+ | -------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
79
+ | Initialization | `createWorkerFixture()` is used as a _part_ of your custom fixture. | `createNetworkFixture()` creates _the entire_ fixture for you, pre-configured. |
80
+ | Implementation | Uses a custom router to match handlers and a custom wrapper around `SetupWorker` API. | Uses MSW directly. Uses `page.route()` as the source of the network to route through the handlers. |
81
+ | Feature set | Supports `http` and `graphql` namespaces. | Supports all namespaces (`http`, `graphql`, `ws`, any other APIs exposed by MSW in the future). |
package/build/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { LifeCycleEventsMap, RequestHandler, SetupApi, WebSocketHandler } from "msw";
2
- import { Page, TestFixture } from "@playwright/test";
2
+ import { Page, PlaywrightTestArgs, PlaywrightWorkerArgs, TestFixture } from "@playwright/test";
3
3
 
4
4
  //#region src/index.d.ts
5
5
  interface CreateNetworkFixtureArgs {
@@ -24,7 +24,7 @@ interface CreateNetworkFixtureArgs {
24
24
  * })
25
25
  * ```
26
26
  */
27
- declare function createNetworkFixture(args?: CreateNetworkFixtureArgs): [TestFixture<NetworkFixture, any>, {
27
+ declare function createNetworkFixture(args?: CreateNetworkFixtureArgs): [TestFixture<NetworkFixture, PlaywrightTestArgs & PlaywrightWorkerArgs>, {
28
28
  auto: boolean;
29
29
  }];
30
30
  declare class NetworkFixture extends SetupApi<LifeCycleEventsMap> {
@@ -35,6 +35,7 @@ declare class NetworkFixture extends SetupApi<LifeCycleEventsMap> {
35
35
  });
36
36
  start(): Promise<void>;
37
37
  stop(): Promise<void>;
38
+ private getPageUrl;
38
39
  }
39
40
  //#endregion
40
41
  export { CreateNetworkFixtureArgs, NetworkFixture, createNetworkFixture };
package/build/index.js CHANGED
@@ -48,8 +48,12 @@ var NetworkFixture = class extends SetupApi {
48
48
  });
49
49
  const response = await getResponse(this.handlersController.currentHandlers().filter((handler) => {
50
50
  return handler instanceof RequestHandler;
51
- }), fetchRequest);
51
+ }), fetchRequest, { baseUrl: this.getPageUrl() });
52
52
  if (response) {
53
+ if (response.status === 0) {
54
+ route.abort();
55
+ return;
56
+ }
53
57
  route.fulfill({
54
58
  status: response.status,
55
59
  headers: Object.fromEntries(response.headers),
@@ -73,13 +77,17 @@ var NetworkFixture = class extends SetupApi {
73
77
  client,
74
78
  server,
75
79
  info: { protocols: [] }
76
- });
80
+ }, { baseUrl: this.getPageUrl() });
77
81
  });
78
82
  }
79
83
  async stop() {
80
84
  super.dispose();
81
85
  await this.#page.unroute(/.+/);
82
86
  }
87
+ getPageUrl() {
88
+ const url = this.#page.url();
89
+ return url !== "about:blank" ? url : void 0;
90
+ }
83
91
  };
84
92
  var PlaywrightWebSocketClientConnection = class {
85
93
  id;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@msw/playwright",
4
- "version": "0.4.0",
4
+ "version": "0.4.2",
5
5
  "description": "Mock Service Worker binding for Playwright",
6
6
  "main": "./build/index.js",
7
7
  "types": "./build/index.d.ts",
@@ -34,16 +34,17 @@
34
34
  "node": ">=20.0.0"
35
35
  },
36
36
  "peerDependencies": {
37
- "msw": "^2.10.1"
37
+ "msw": "^2.10.3"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@epic-web/test-server": "^0.1.6",
41
41
  "@ossjs/release": "^0.8.1",
42
42
  "@playwright/test": "^1.52.0",
43
43
  "@types/node": "^22.15.29",
44
- "msw": "^2.10.1",
44
+ "msw": "^2.10.3",
45
45
  "tsdown": "^0.12.7",
46
- "typescript": "^5.8.3"
46
+ "typescript": "^5.8.3",
47
+ "vite": "^7.0.2"
47
48
  },
48
49
  "dependencies": {
49
50
  "@mswjs/interceptors": "^0.39.2",
@@ -52,6 +53,9 @@
52
53
  "scripts": {
53
54
  "dev": "tsdown --watch",
54
55
  "test": "playwright test",
56
+ "app:dev": "vite dev",
57
+ "app:build": "vite build",
58
+ "app:start": "vite",
55
59
  "build": "tsdown",
56
60
  "release": "release publish"
57
61
  }
package/src/index.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  import { invariant } from 'outvariant'
2
- import type { Page, TestFixture, WebSocketRoute } from '@playwright/test'
2
+ import type {
3
+ Page,
4
+ PlaywrightTestArgs,
5
+ PlaywrightWorkerArgs,
6
+ TestFixture,
7
+ WebSocketRoute,
8
+ } from '@playwright/test'
3
9
  import {
4
10
  type LifeCycleEventsMap,
5
11
  SetupApi,
@@ -43,7 +49,10 @@ export interface CreateNetworkFixtureArgs {
43
49
  export function createNetworkFixture(
44
50
  args?: CreateNetworkFixtureArgs,
45
51
  /** @todo `onUnhandledRequest`? */
46
- ): [TestFixture<NetworkFixture, any>, { auto: boolean }] {
52
+ ): [
53
+ TestFixture<NetworkFixture, PlaywrightTestArgs & PlaywrightWorkerArgs>,
54
+ { auto: boolean },
55
+ ] {
47
56
  return [
48
57
  async ({ page }, use) => {
49
58
  const worker = new NetworkFixture({
@@ -84,9 +93,17 @@ export class NetworkFixture extends SetupApi<LifeCycleEventsMap> {
84
93
  return handler instanceof RequestHandler
85
94
  }),
86
95
  fetchRequest,
96
+ {
97
+ baseUrl: this.getPageUrl(),
98
+ },
87
99
  )
88
100
 
89
101
  if (response) {
102
+ if (response.status === 0) {
103
+ route.abort()
104
+ return
105
+ }
106
+
90
107
  route.fulfill({
91
108
  status: response.status,
92
109
  headers: Object.fromEntries(response.headers),
@@ -117,11 +134,16 @@ export class NetworkFixture extends SetupApi<LifeCycleEventsMap> {
117
134
  const server = new PlaywrightWebSocketServerConnection(ws)
118
135
 
119
136
  for (const handler of allWebSocketHandlers) {
120
- await handler.run({
121
- client,
122
- server,
123
- info: { protocols: [] },
124
- })
137
+ await handler.run(
138
+ {
139
+ client,
140
+ server,
141
+ info: { protocols: [] },
142
+ },
143
+ {
144
+ baseUrl: this.getPageUrl(),
145
+ },
146
+ )
125
147
  }
126
148
  })
127
149
  }
@@ -130,6 +152,11 @@ export class NetworkFixture extends SetupApi<LifeCycleEventsMap> {
130
152
  super.dispose()
131
153
  await this.#page.unroute(/.+/)
132
154
  }
155
+
156
+ private getPageUrl(): string | undefined {
157
+ const url = this.#page.url()
158
+ return url !== 'about:blank' ? url : undefined
159
+ }
133
160
  }
134
161
 
135
162
  class PlaywrightWebSocketClientConnection