@chaos-maker/playwright 0.2.0 → 0.4.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 +54 -0
- package/dist/{chunk-XVP3BFFM.js → chunk-KHKPTES5.js} +64 -1
- package/dist/fixture.cjs +6 -1
- package/dist/fixture.js +1 -1
- package/dist/index.cjs +70 -3
- package/dist/index.d.cts +54 -3
- package/dist/index.d.ts +54 -3
- package/dist/index.js +11 -3
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -90,6 +90,28 @@ test('checkout handles combined chaos', async ({ page }) => {
|
|
|
90
90
|
});
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
+
### SSE and GraphQL
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
await injectChaos(page, {
|
|
97
|
+
seed: 42,
|
|
98
|
+
sse: {
|
|
99
|
+
drops: [{ urlPattern: '/events', eventType: 'token', probability: 0.1 }],
|
|
100
|
+
},
|
|
101
|
+
network: {
|
|
102
|
+
failures: [{
|
|
103
|
+
urlPattern: '/graphql',
|
|
104
|
+
graphqlOperation: 'GetUser',
|
|
105
|
+
statusCode: 503,
|
|
106
|
+
probability: 1,
|
|
107
|
+
}],
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
await page.goto('/dashboard');
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
SSE chaos and GraphQL operation matching use the same pre-navigation `injectChaos()` timing as fetch, XHR, and WebSocket chaos.
|
|
114
|
+
|
|
93
115
|
## API
|
|
94
116
|
|
|
95
117
|
### `injectChaos(page, config, opts?)`
|
|
@@ -167,6 +189,38 @@ test('with direct API', async ({ page }, testInfo) => {
|
|
|
167
189
|
});
|
|
168
190
|
```
|
|
169
191
|
|
|
192
|
+
## Service Worker chaos
|
|
193
|
+
|
|
194
|
+
Intercept SW-originated fetches. Requires one line in your service-worker script.
|
|
195
|
+
|
|
196
|
+
```js
|
|
197
|
+
// user's sw.js (classic)
|
|
198
|
+
importScripts('/chaos-maker-sw.js');
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
import { injectSWChaos, removeSWChaos, getSWChaosLog } from '@chaos-maker/playwright';
|
|
203
|
+
|
|
204
|
+
test('SW-fetched /api returns 503', async ({ page }) => {
|
|
205
|
+
await page.goto('/app-with-sw/');
|
|
206
|
+
// wait for controller after your app's SW registration
|
|
207
|
+
await injectSWChaos(page, {
|
|
208
|
+
network: { failures: [{ urlPattern: '/api/data', statusCode: 503, probability: 1 }] },
|
|
209
|
+
seed: 1,
|
|
210
|
+
});
|
|
211
|
+
await page.click('#trigger');
|
|
212
|
+
const log = await getSWChaosLog(page);
|
|
213
|
+
expect(log.some(e => e.type === 'network:failure' && e.applied)).toBe(true);
|
|
214
|
+
await removeSWChaos(page);
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Two artifacts ship in `@chaos-maker/core`:
|
|
219
|
+
- `dist/sw.js` — IIFE bundle for classic SWs (`importScripts('/chaos-maker-sw.js')`).
|
|
220
|
+
- `dist/sw.mjs` — ESM bundle for module SWs (`import { installChaosSW } from '/chaos-maker-sw.mjs'`).
|
|
221
|
+
|
|
222
|
+
Serve whichever your SW type uses at a URL reachable from the service-worker scope.
|
|
223
|
+
|
|
170
224
|
## License
|
|
171
225
|
|
|
172
226
|
[MIT](../../LICENSE)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
+
import { serializeForTransport } from "@chaos-maker/core";
|
|
2
3
|
import { resolve, dirname } from "path";
|
|
3
4
|
import { createRequire } from "module";
|
|
4
5
|
import { fileURLToPath } from "url";
|
|
@@ -107,6 +108,63 @@ async function createTraceReporter(page, testInfo, opts = {}) {
|
|
|
107
108
|
};
|
|
108
109
|
}
|
|
109
110
|
|
|
111
|
+
// src/sw.ts
|
|
112
|
+
import { validateConfig, SW_BRIDGE_SOURCE } from "@chaos-maker/core";
|
|
113
|
+
var BRIDGE_INIT_KEY = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.sw.bridgeInit");
|
|
114
|
+
async function ensurePageBridge(page) {
|
|
115
|
+
if (!page[BRIDGE_INIT_KEY]) {
|
|
116
|
+
await page.addInitScript({ content: SW_BRIDGE_SOURCE });
|
|
117
|
+
page[BRIDGE_INIT_KEY] = true;
|
|
118
|
+
}
|
|
119
|
+
await page.evaluate(SW_BRIDGE_SOURCE).catch(() => {
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
async function injectSWChaos(page, config, opts = {}) {
|
|
123
|
+
const validated = validateConfig(config);
|
|
124
|
+
const timeoutMs = opts.timeoutMs ?? 1e4;
|
|
125
|
+
await ensurePageBridge(page);
|
|
126
|
+
const result = await page.evaluate(
|
|
127
|
+
async ({ cfg, timeoutMs: timeoutMs2 }) => {
|
|
128
|
+
const bridge = globalThis.__chaosMakerSWBridge;
|
|
129
|
+
if (!bridge) throw new Error("[chaos-maker] SW bridge missing from page \u2014 ensurePageBridge failed");
|
|
130
|
+
return await bridge.apply(cfg, timeoutMs2);
|
|
131
|
+
},
|
|
132
|
+
{ cfg: validated, timeoutMs }
|
|
133
|
+
);
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
async function removeSWChaos(page, opts = {}) {
|
|
137
|
+
const timeoutMs = opts.timeoutMs ?? 5e3;
|
|
138
|
+
await page.evaluate(
|
|
139
|
+
async ({ timeoutMs: timeoutMs2 }) => {
|
|
140
|
+
const bridge = globalThis.__chaosMakerSWBridge;
|
|
141
|
+
if (!bridge) return;
|
|
142
|
+
await bridge.stop(timeoutMs2);
|
|
143
|
+
bridge.clearLocalLog();
|
|
144
|
+
},
|
|
145
|
+
{ timeoutMs }
|
|
146
|
+
).catch(() => {
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
async function getSWChaosLog(page) {
|
|
150
|
+
return page.evaluate(() => {
|
|
151
|
+
const bridge = globalThis.__chaosMakerSWBridge;
|
|
152
|
+
if (!bridge) return [];
|
|
153
|
+
return bridge.getLocalLog();
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
async function getSWChaosLogFromSW(page, opts = {}) {
|
|
157
|
+
const timeoutMs = opts.timeoutMs ?? 5e3;
|
|
158
|
+
return page.evaluate(
|
|
159
|
+
async ({ timeoutMs: timeoutMs2 }) => {
|
|
160
|
+
const bridge = globalThis.__chaosMakerSWBridge;
|
|
161
|
+
if (!bridge) return [];
|
|
162
|
+
return bridge.getRemoteLog(timeoutMs2);
|
|
163
|
+
},
|
|
164
|
+
{ timeoutMs }
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
110
168
|
// src/index.ts
|
|
111
169
|
var cachedUmdPath = null;
|
|
112
170
|
function getCoreUmdPath() {
|
|
@@ -134,10 +192,11 @@ async function injectChaos(page, config, opts = {}) {
|
|
|
134
192
|
page[TRACE_HANDLE_KEY] = handle;
|
|
135
193
|
}
|
|
136
194
|
}
|
|
195
|
+
const serialized = serializeForTransport(config);
|
|
137
196
|
await page.addInitScript((cfg) => {
|
|
138
197
|
const win = globalThis;
|
|
139
198
|
win.__CHAOS_CONFIG__ = cfg;
|
|
140
|
-
},
|
|
199
|
+
}, serialized);
|
|
141
200
|
await page.addInitScript({ path: umdPath });
|
|
142
201
|
}
|
|
143
202
|
function resolveTracing(opts) {
|
|
@@ -186,6 +245,10 @@ async function getChaosSeed(page) {
|
|
|
186
245
|
}
|
|
187
246
|
|
|
188
247
|
export {
|
|
248
|
+
injectSWChaos,
|
|
249
|
+
removeSWChaos,
|
|
250
|
+
getSWChaosLog,
|
|
251
|
+
getSWChaosLogFromSW,
|
|
189
252
|
injectChaos,
|
|
190
253
|
removeChaos,
|
|
191
254
|
getChaosLog,
|
package/dist/fixture.cjs
CHANGED
|
@@ -27,6 +27,7 @@ module.exports = __toCommonJS(fixture_exports);
|
|
|
27
27
|
var import_test2 = require("@playwright/test");
|
|
28
28
|
|
|
29
29
|
// src/index.ts
|
|
30
|
+
var import_core2 = require("@chaos-maker/core");
|
|
30
31
|
var import_path = require("path");
|
|
31
32
|
var import_module = require("module");
|
|
32
33
|
var import_url = require("url");
|
|
@@ -135,6 +136,9 @@ async function createTraceReporter(page, testInfo, opts = {}) {
|
|
|
135
136
|
};
|
|
136
137
|
}
|
|
137
138
|
|
|
139
|
+
// src/sw.ts
|
|
140
|
+
var import_core = require("@chaos-maker/core");
|
|
141
|
+
|
|
138
142
|
// src/index.ts
|
|
139
143
|
var import_meta = {};
|
|
140
144
|
var cachedUmdPath = null;
|
|
@@ -163,10 +167,11 @@ async function injectChaos(page, config, opts = {}) {
|
|
|
163
167
|
page[TRACE_HANDLE_KEY] = handle;
|
|
164
168
|
}
|
|
165
169
|
}
|
|
170
|
+
const serialized = (0, import_core2.serializeForTransport)(config);
|
|
166
171
|
await page.addInitScript((cfg) => {
|
|
167
172
|
const win = globalThis;
|
|
168
173
|
win.__CHAOS_CONFIG__ = cfg;
|
|
169
|
-
},
|
|
174
|
+
}, serialized);
|
|
170
175
|
await page.addInitScript({ path: umdPath });
|
|
171
176
|
}
|
|
172
177
|
function resolveTracing(opts) {
|
package/dist/fixture.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -22,10 +22,15 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
getChaosLog: () => getChaosLog,
|
|
24
24
|
getChaosSeed: () => getChaosSeed,
|
|
25
|
+
getSWChaosLog: () => getSWChaosLog,
|
|
26
|
+
getSWChaosLogFromSW: () => getSWChaosLogFromSW,
|
|
25
27
|
injectChaos: () => injectChaos,
|
|
26
|
-
|
|
28
|
+
injectSWChaos: () => injectSWChaos,
|
|
29
|
+
removeChaos: () => removeChaos,
|
|
30
|
+
removeSWChaos: () => removeSWChaos
|
|
27
31
|
});
|
|
28
32
|
module.exports = __toCommonJS(index_exports);
|
|
33
|
+
var import_core2 = require("@chaos-maker/core");
|
|
29
34
|
var import_path = require("path");
|
|
30
35
|
var import_module = require("module");
|
|
31
36
|
var import_url = require("url");
|
|
@@ -134,6 +139,63 @@ async function createTraceReporter(page, testInfo, opts = {}) {
|
|
|
134
139
|
};
|
|
135
140
|
}
|
|
136
141
|
|
|
142
|
+
// src/sw.ts
|
|
143
|
+
var import_core = require("@chaos-maker/core");
|
|
144
|
+
var BRIDGE_INIT_KEY = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.sw.bridgeInit");
|
|
145
|
+
async function ensurePageBridge(page) {
|
|
146
|
+
if (!page[BRIDGE_INIT_KEY]) {
|
|
147
|
+
await page.addInitScript({ content: import_core.SW_BRIDGE_SOURCE });
|
|
148
|
+
page[BRIDGE_INIT_KEY] = true;
|
|
149
|
+
}
|
|
150
|
+
await page.evaluate(import_core.SW_BRIDGE_SOURCE).catch(() => {
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
async function injectSWChaos(page, config, opts = {}) {
|
|
154
|
+
const validated = (0, import_core.validateConfig)(config);
|
|
155
|
+
const timeoutMs = opts.timeoutMs ?? 1e4;
|
|
156
|
+
await ensurePageBridge(page);
|
|
157
|
+
const result = await page.evaluate(
|
|
158
|
+
async ({ cfg, timeoutMs: timeoutMs2 }) => {
|
|
159
|
+
const bridge = globalThis.__chaosMakerSWBridge;
|
|
160
|
+
if (!bridge) throw new Error("[chaos-maker] SW bridge missing from page \u2014 ensurePageBridge failed");
|
|
161
|
+
return await bridge.apply(cfg, timeoutMs2);
|
|
162
|
+
},
|
|
163
|
+
{ cfg: validated, timeoutMs }
|
|
164
|
+
);
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
async function removeSWChaos(page, opts = {}) {
|
|
168
|
+
const timeoutMs = opts.timeoutMs ?? 5e3;
|
|
169
|
+
await page.evaluate(
|
|
170
|
+
async ({ timeoutMs: timeoutMs2 }) => {
|
|
171
|
+
const bridge = globalThis.__chaosMakerSWBridge;
|
|
172
|
+
if (!bridge) return;
|
|
173
|
+
await bridge.stop(timeoutMs2);
|
|
174
|
+
bridge.clearLocalLog();
|
|
175
|
+
},
|
|
176
|
+
{ timeoutMs }
|
|
177
|
+
).catch(() => {
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
async function getSWChaosLog(page) {
|
|
181
|
+
return page.evaluate(() => {
|
|
182
|
+
const bridge = globalThis.__chaosMakerSWBridge;
|
|
183
|
+
if (!bridge) return [];
|
|
184
|
+
return bridge.getLocalLog();
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
async function getSWChaosLogFromSW(page, opts = {}) {
|
|
188
|
+
const timeoutMs = opts.timeoutMs ?? 5e3;
|
|
189
|
+
return page.evaluate(
|
|
190
|
+
async ({ timeoutMs: timeoutMs2 }) => {
|
|
191
|
+
const bridge = globalThis.__chaosMakerSWBridge;
|
|
192
|
+
if (!bridge) return [];
|
|
193
|
+
return bridge.getRemoteLog(timeoutMs2);
|
|
194
|
+
},
|
|
195
|
+
{ timeoutMs }
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
137
199
|
// src/index.ts
|
|
138
200
|
var import_meta = {};
|
|
139
201
|
var cachedUmdPath = null;
|
|
@@ -162,10 +224,11 @@ async function injectChaos(page, config, opts = {}) {
|
|
|
162
224
|
page[TRACE_HANDLE_KEY] = handle;
|
|
163
225
|
}
|
|
164
226
|
}
|
|
227
|
+
const serialized = (0, import_core2.serializeForTransport)(config);
|
|
165
228
|
await page.addInitScript((cfg) => {
|
|
166
229
|
const win = globalThis;
|
|
167
230
|
win.__CHAOS_CONFIG__ = cfg;
|
|
168
|
-
},
|
|
231
|
+
}, serialized);
|
|
169
232
|
await page.addInitScript({ path: umdPath });
|
|
170
233
|
}
|
|
171
234
|
function resolveTracing(opts) {
|
|
@@ -216,6 +279,10 @@ async function getChaosSeed(page) {
|
|
|
216
279
|
0 && (module.exports = {
|
|
217
280
|
getChaosLog,
|
|
218
281
|
getChaosSeed,
|
|
282
|
+
getSWChaosLog,
|
|
283
|
+
getSWChaosLogFromSW,
|
|
219
284
|
injectChaos,
|
|
220
|
-
|
|
285
|
+
injectSWChaos,
|
|
286
|
+
removeChaos,
|
|
287
|
+
removeSWChaos
|
|
221
288
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Page, TestInfo } from '@playwright/test';
|
|
2
2
|
import { ChaosEvent, ChaosConfig } from '@chaos-maker/core';
|
|
3
|
-
export { ChaosConfig, ChaosEvent, WebSocketCloseConfig, WebSocketConfig, WebSocketCorruptConfig, WebSocketCorruptionStrategy, WebSocketDelayConfig, WebSocketDirection, WebSocketDropConfig } from '@chaos-maker/core';
|
|
3
|
+
export { ChaosConfig, ChaosEvent, CorruptionStrategy, GraphQLOperationMatcher, NetworkAbortConfig, NetworkConfig, NetworkCorruptionConfig, NetworkCorsConfig, NetworkFailureConfig, NetworkLatencyConfig, NetworkRuleMatchers, SSECloseConfig, SSEConfig, SSECorruptConfig, SSECorruptionStrategy, SSEDelayConfig, SSEDropConfig, SSEEventTypeMatcher, WebSocketCloseConfig, WebSocketConfig, WebSocketCorruptConfig, WebSocketCorruptionStrategy, WebSocketDelayConfig, WebSocketDirection, WebSocketDropConfig } from '@chaos-maker/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Shape of the JSON attachment written to `testInfo.attachments` on teardown.
|
|
@@ -17,6 +17,57 @@ interface TraceReporterOptions {
|
|
|
17
17
|
attachmentName?: string;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Options accepted by {@link injectSWChaos} / {@link removeSWChaos} /
|
|
22
|
+
* {@link getSWChaosLog}.
|
|
23
|
+
*/
|
|
24
|
+
interface SWChaosOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Maximum milliseconds to wait for `navigator.serviceWorker.controller` and
|
|
27
|
+
* the SW's ack message. Defaults to `10000`. Raise for slow CI workers or
|
|
28
|
+
* SWs that do heavy work during `install`.
|
|
29
|
+
*/
|
|
30
|
+
timeoutMs?: number;
|
|
31
|
+
}
|
|
32
|
+
interface InjectSWChaosResult {
|
|
33
|
+
/** Seed used by the PRNG inside the SW. `null` if the ack did not carry one. */
|
|
34
|
+
seed: number | null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Configure Service-Worker chaos for a Playwright page. Call **after**
|
|
38
|
+
* `page.goto(...)` so there is a SW registration + controller to target.
|
|
39
|
+
*
|
|
40
|
+
* Requires the user's service worker to load the chaos SW bundle — typically
|
|
41
|
+
* via `importScripts('/path/to/chaos-maker-sw.js')` (classic SW) or
|
|
42
|
+
* `import { installChaosSW } from '@chaos-maker/core/sw'; installChaosSW();`
|
|
43
|
+
* (module SW).
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* await page.goto('/');
|
|
48
|
+
* await injectSWChaos(page, {
|
|
49
|
+
* network: { failures: [{ urlPattern: '/api', statusCode: 503, probability: 1 }] },
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
declare function injectSWChaos(page: Page, config: ChaosConfig, opts?: SWChaosOptions): Promise<InjectSWChaosResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Stop Service-Worker chaos for a Playwright page. Posts `__chaosMakerStop` to
|
|
56
|
+
* the current controller and clears the page's in-memory log buffer.
|
|
57
|
+
*/
|
|
58
|
+
declare function removeSWChaos(page: Page, opts?: SWChaosOptions): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Read the chaos event log buffered on the page side. Every event emitted by
|
|
61
|
+
* the SW is broadcast to all controlled clients and captured here.
|
|
62
|
+
*/
|
|
63
|
+
declare function getSWChaosLog(page: Page): Promise<ChaosEvent[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Ask the SW for its in-memory log. Useful when debugging a race where the
|
|
66
|
+
* page-side listener missed an early broadcast (e.g. first-paint navigation).
|
|
67
|
+
* Prefer {@link getSWChaosLog} in normal assertions.
|
|
68
|
+
*/
|
|
69
|
+
declare function getSWChaosLogFromSW(page: Page, opts?: SWChaosOptions): Promise<ChaosEvent[]>;
|
|
70
|
+
|
|
20
71
|
/**
|
|
21
72
|
* Options for `injectChaos`. Most callers can omit this entirely; defaults
|
|
22
73
|
* preserve backward compatibility with the v0.1.x signature.
|
|
@@ -74,4 +125,4 @@ declare function getChaosLog(page: Page): Promise<ChaosEvent[]>;
|
|
|
74
125
|
*/
|
|
75
126
|
declare function getChaosSeed(page: Page): Promise<number | null>;
|
|
76
127
|
|
|
77
|
-
export { type ChaosTraceAttachment, type InjectChaosOptions, type TraceReporterOptions, getChaosLog, getChaosSeed, injectChaos, removeChaos };
|
|
128
|
+
export { type ChaosTraceAttachment, type InjectChaosOptions, type InjectSWChaosResult, type SWChaosOptions, type TraceReporterOptions, getChaosLog, getChaosSeed, getSWChaosLog, getSWChaosLogFromSW, injectChaos, injectSWChaos, removeChaos, removeSWChaos };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Page, TestInfo } from '@playwright/test';
|
|
2
2
|
import { ChaosEvent, ChaosConfig } from '@chaos-maker/core';
|
|
3
|
-
export { ChaosConfig, ChaosEvent, WebSocketCloseConfig, WebSocketConfig, WebSocketCorruptConfig, WebSocketCorruptionStrategy, WebSocketDelayConfig, WebSocketDirection, WebSocketDropConfig } from '@chaos-maker/core';
|
|
3
|
+
export { ChaosConfig, ChaosEvent, CorruptionStrategy, GraphQLOperationMatcher, NetworkAbortConfig, NetworkConfig, NetworkCorruptionConfig, NetworkCorsConfig, NetworkFailureConfig, NetworkLatencyConfig, NetworkRuleMatchers, SSECloseConfig, SSEConfig, SSECorruptConfig, SSECorruptionStrategy, SSEDelayConfig, SSEDropConfig, SSEEventTypeMatcher, WebSocketCloseConfig, WebSocketConfig, WebSocketCorruptConfig, WebSocketCorruptionStrategy, WebSocketDelayConfig, WebSocketDirection, WebSocketDropConfig } from '@chaos-maker/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Shape of the JSON attachment written to `testInfo.attachments` on teardown.
|
|
@@ -17,6 +17,57 @@ interface TraceReporterOptions {
|
|
|
17
17
|
attachmentName?: string;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Options accepted by {@link injectSWChaos} / {@link removeSWChaos} /
|
|
22
|
+
* {@link getSWChaosLog}.
|
|
23
|
+
*/
|
|
24
|
+
interface SWChaosOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Maximum milliseconds to wait for `navigator.serviceWorker.controller` and
|
|
27
|
+
* the SW's ack message. Defaults to `10000`. Raise for slow CI workers or
|
|
28
|
+
* SWs that do heavy work during `install`.
|
|
29
|
+
*/
|
|
30
|
+
timeoutMs?: number;
|
|
31
|
+
}
|
|
32
|
+
interface InjectSWChaosResult {
|
|
33
|
+
/** Seed used by the PRNG inside the SW. `null` if the ack did not carry one. */
|
|
34
|
+
seed: number | null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Configure Service-Worker chaos for a Playwright page. Call **after**
|
|
38
|
+
* `page.goto(...)` so there is a SW registration + controller to target.
|
|
39
|
+
*
|
|
40
|
+
* Requires the user's service worker to load the chaos SW bundle — typically
|
|
41
|
+
* via `importScripts('/path/to/chaos-maker-sw.js')` (classic SW) or
|
|
42
|
+
* `import { installChaosSW } from '@chaos-maker/core/sw'; installChaosSW();`
|
|
43
|
+
* (module SW).
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* await page.goto('/');
|
|
48
|
+
* await injectSWChaos(page, {
|
|
49
|
+
* network: { failures: [{ urlPattern: '/api', statusCode: 503, probability: 1 }] },
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
declare function injectSWChaos(page: Page, config: ChaosConfig, opts?: SWChaosOptions): Promise<InjectSWChaosResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Stop Service-Worker chaos for a Playwright page. Posts `__chaosMakerStop` to
|
|
56
|
+
* the current controller and clears the page's in-memory log buffer.
|
|
57
|
+
*/
|
|
58
|
+
declare function removeSWChaos(page: Page, opts?: SWChaosOptions): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Read the chaos event log buffered on the page side. Every event emitted by
|
|
61
|
+
* the SW is broadcast to all controlled clients and captured here.
|
|
62
|
+
*/
|
|
63
|
+
declare function getSWChaosLog(page: Page): Promise<ChaosEvent[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Ask the SW for its in-memory log. Useful when debugging a race where the
|
|
66
|
+
* page-side listener missed an early broadcast (e.g. first-paint navigation).
|
|
67
|
+
* Prefer {@link getSWChaosLog} in normal assertions.
|
|
68
|
+
*/
|
|
69
|
+
declare function getSWChaosLogFromSW(page: Page, opts?: SWChaosOptions): Promise<ChaosEvent[]>;
|
|
70
|
+
|
|
20
71
|
/**
|
|
21
72
|
* Options for `injectChaos`. Most callers can omit this entirely; defaults
|
|
22
73
|
* preserve backward compatibility with the v0.1.x signature.
|
|
@@ -74,4 +125,4 @@ declare function getChaosLog(page: Page): Promise<ChaosEvent[]>;
|
|
|
74
125
|
*/
|
|
75
126
|
declare function getChaosSeed(page: Page): Promise<number | null>;
|
|
76
127
|
|
|
77
|
-
export { type ChaosTraceAttachment, type InjectChaosOptions, type TraceReporterOptions, getChaosLog, getChaosSeed, injectChaos, removeChaos };
|
|
128
|
+
export { type ChaosTraceAttachment, type InjectChaosOptions, type InjectSWChaosResult, type SWChaosOptions, type TraceReporterOptions, getChaosLog, getChaosSeed, getSWChaosLog, getSWChaosLogFromSW, injectChaos, injectSWChaos, removeChaos, removeSWChaos };
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getChaosLog,
|
|
3
3
|
getChaosSeed,
|
|
4
|
+
getSWChaosLog,
|
|
5
|
+
getSWChaosLogFromSW,
|
|
4
6
|
injectChaos,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
injectSWChaos,
|
|
8
|
+
removeChaos,
|
|
9
|
+
removeSWChaos
|
|
10
|
+
} from "./chunk-KHKPTES5.js";
|
|
7
11
|
export {
|
|
8
12
|
getChaosLog,
|
|
9
13
|
getChaosSeed,
|
|
14
|
+
getSWChaosLog,
|
|
15
|
+
getSWChaosLogFromSW,
|
|
10
16
|
injectChaos,
|
|
11
|
-
|
|
17
|
+
injectSWChaos,
|
|
18
|
+
removeChaos,
|
|
19
|
+
removeSWChaos
|
|
12
20
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chaos-maker/playwright",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Playwright adapter for @chaos-maker/core — one-line chaos injection in E2E tests",
|
|
6
6
|
"keywords": [
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
16
|
-
"url": "https://github.com/
|
|
16
|
+
"url": "https://github.com/chaos-maker-dev/chaos-maker.git",
|
|
17
17
|
"directory": "packages/playwright"
|
|
18
18
|
},
|
|
19
|
-
"homepage": "https://github.com/
|
|
19
|
+
"homepage": "https://github.com/chaos-maker-dev/chaos-maker",
|
|
20
20
|
"engines": {
|
|
21
21
|
"node": ">=18"
|
|
22
22
|
},
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"dist"
|
|
50
50
|
],
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@chaos-maker/core": "0.
|
|
52
|
+
"@chaos-maker/core": "0.4.0"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"@playwright/test": ">=1.40.0"
|