@chaos-maker/playwright 0.5.0 → 0.6.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 +56 -31
- package/dist/{chunk-IJDMHBUQ.js → chunk-ZJZRSTXG.js} +58 -80
- package/dist/fixture.cjs +59 -86
- package/dist/fixture.js +1 -1
- package/dist/index.cjs +71 -92
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Playwright adapter for [`@chaos-maker/core`](../core/). One-line chaos injection
|
|
|
8
8
|
npm install @chaos-maker/core @chaos-maker/playwright
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
Both packages are required
|
|
11
|
+
Both packages are required - `@chaos-maker/playwright` loads the core UMD bundle into the browser page.
|
|
12
12
|
|
|
13
13
|
## Usage
|
|
14
14
|
|
|
@@ -19,21 +19,27 @@ import { test, expect } from '@playwright/test';
|
|
|
19
19
|
import { injectChaos, removeChaos, getChaosLog } from '@chaos-maker/playwright';
|
|
20
20
|
|
|
21
21
|
test('shows error when API fails', async ({ page }) => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
try {
|
|
23
|
+
await injectChaos(page, {
|
|
24
|
+
network: {
|
|
25
|
+
failures: [{ urlPattern: '/api/data', statusCode: 503, probability: 1.0 }]
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
await page.goto('/dashboard');
|
|
30
|
+
await expect(page.getByText('Something went wrong')).toBeVisible();
|
|
31
|
+
|
|
32
|
+
// Check what chaos was applied
|
|
33
|
+
const log = await getChaosLog(page);
|
|
34
|
+
expect(log.some(e => e.type === 'network:failure' && e.applied)).toBe(true);
|
|
35
|
+
} finally {
|
|
36
|
+
await removeChaos(page);
|
|
37
|
+
}
|
|
34
38
|
});
|
|
35
39
|
```
|
|
36
40
|
|
|
41
|
+
For direct API calls, use `try` / `finally` when a test can fail before explicit cleanup. `removeChaos(page)` restores the current document and is safe during teardown. Playwright `addInitScript()` entries stay registered on the `Page`, so a later `page.reload()` or `page.goto()` on the same reused page can run prior chaos init scripts again. Prefer the fixture, Playwright's default fresh page per test, or a new page/context when reload isolation matters.
|
|
42
|
+
|
|
37
43
|
### Test Fixture
|
|
38
44
|
|
|
39
45
|
For automatic cleanup, use the built-in fixture:
|
|
@@ -182,20 +188,22 @@ SSE chaos and GraphQL operation matching use the same pre-navigation `injectChao
|
|
|
182
188
|
|
|
183
189
|
Inject chaos into a Playwright page. **Call before `page.goto()`** to ensure all network requests are intercepted from the start.
|
|
184
190
|
|
|
185
|
-
- `page`
|
|
186
|
-
- `config`
|
|
187
|
-
- `opts`
|
|
188
|
-
- `tracing?: boolean | 'auto'`
|
|
189
|
-
- `testInfo?: TestInfo`
|
|
190
|
-
- `traceOptions?: { verbose?: boolean; attachmentName?: string }`
|
|
191
|
+
- `page` - Playwright `Page` instance
|
|
192
|
+
- `config` - `ChaosConfig` object (see [@chaos-maker/core](../core/) for full config reference)
|
|
193
|
+
- `opts` - optional. `InjectChaosOptions`:
|
|
194
|
+
- `tracing?: boolean | 'auto'` - emit chaos events into the Playwright trace (see [Debugging with trace](#debugging-with-trace)). Requires `testInfo` when `true`.
|
|
195
|
+
- `testInfo?: TestInfo` - active Playwright `TestInfo` (supplied automatically by the fixture).
|
|
196
|
+
- `traceOptions?: { verbose?: boolean; attachmentName?: string }` - tune trace output.
|
|
191
197
|
|
|
192
198
|
### `removeChaos(page)`
|
|
193
199
|
|
|
194
200
|
Stop chaos and restore original `fetch`/`XHR`/DOM behavior.
|
|
195
201
|
|
|
202
|
+
This restores the active document. It does not remove Playwright `addInitScript()` registrations from a reused `Page`, because Playwright does not expose a removal API for them.
|
|
203
|
+
|
|
196
204
|
### `getChaosLog(page)`
|
|
197
205
|
|
|
198
|
-
Retrieve the chaos event log from the page. Returns `ChaosEvent[]`
|
|
206
|
+
Retrieve the chaos event log from the page. Returns `ChaosEvent[]` - every chaos check emitted since injection, with `applied: true/false`.
|
|
199
207
|
|
|
200
208
|
### `enableGroup(page, name)` / `disableGroup(page, name)`
|
|
201
209
|
|
|
@@ -209,17 +217,17 @@ Toggle a Service Worker Rule Group at runtime. Pass `opts.timeoutMs` to override
|
|
|
209
217
|
|
|
210
218
|
Available when importing `test` from `@chaos-maker/playwright/fixture`:
|
|
211
219
|
|
|
212
|
-
- `chaos.inject(config)`
|
|
213
|
-
- `chaos.remove()`
|
|
214
|
-
- `chaos.getLog()`
|
|
215
|
-
- `chaos.enableGroup(name)`
|
|
216
|
-
- `chaos.disableGroup(name)`
|
|
217
|
-
- `chaos.enableSWGroup(name, opts?)`
|
|
218
|
-
- `chaos.disableSWGroup(name, opts?)`
|
|
220
|
+
- `chaos.inject(config)` - same as `injectChaos(page, config)`
|
|
221
|
+
- `chaos.remove()` - same as `removeChaos(page)` (also called automatically after each test)
|
|
222
|
+
- `chaos.getLog()` - same as `getChaosLog(page)`
|
|
223
|
+
- `chaos.enableGroup(name)` - same as `enableGroup(page, name)`
|
|
224
|
+
- `chaos.disableGroup(name)` - same as `disableGroup(page, name)`
|
|
225
|
+
- `chaos.enableSWGroup(name, opts?)` - same as `enableSWGroup(page, name, opts)`
|
|
226
|
+
- `chaos.disableSWGroup(name, opts?)` - same as `disableSWGroup(page, name, opts)`
|
|
219
227
|
|
|
220
228
|
## Validation
|
|
221
229
|
|
|
222
|
-
`injectChaos` validates the config from Node BEFORE any page touch. A malformed config throws `ChaosConfigError` synchronously from the test runner
|
|
230
|
+
`injectChaos` validates the config from Node BEFORE any page touch. A malformed config throws `ChaosConfigError` synchronously from the test runner - your test fails before navigation, not in the browser console. `ChaosConfigError.issues` is a structured `ValidationIssue[]` with `path`, `code`, `ruleType`, and optional `expected` / `received`. See the [Rule Validation concept page](https://chaos-maker-dev.github.io/chaos-maker/concepts/validation/).
|
|
223
231
|
|
|
224
232
|
```ts
|
|
225
233
|
import { injectChaos, ChaosConfigError } from '@chaos-maker/playwright';
|
|
@@ -238,7 +246,7 @@ try {
|
|
|
238
246
|
|
|
239
247
|
## Debugging with trace
|
|
240
248
|
|
|
241
|
-
When a chaos test fails, the Playwright trace viewer is the first place to look. Enable tracing in your Playwright config and use the fixture
|
|
249
|
+
When a chaos test fails, the Playwright trace viewer is the first place to look. Enable tracing in your Playwright config and use the fixture - every applied chaos decision appears inline in the trace action timeline as a `chaos:<type>` step, and the full event log is attached as `chaos-log.json`.
|
|
242
250
|
|
|
243
251
|
```ts
|
|
244
252
|
// playwright.config.ts
|
|
@@ -284,6 +292,18 @@ test('with direct API', async ({ page }, testInfo) => {
|
|
|
284
292
|
});
|
|
285
293
|
```
|
|
286
294
|
|
|
295
|
+
## Leak diagnostics
|
|
296
|
+
|
|
297
|
+
Enable `debug: true` on the chaos config to surface leaked-runtime diagnostics in the event log. Filter `getChaosLog(page)` for `type === 'debug'` events with `detail.reason` covering double-patched globals, stale wrapper handles, orphaned observers, or active-instance conflicts. See [`@chaos-maker/core`](../core/README.md#leak-diagnostics) for the full reason list.
|
|
298
|
+
|
|
299
|
+
```ts
|
|
300
|
+
await injectChaos(page, { debug: true, network: { /* ... */ } });
|
|
301
|
+
await page.goto('/');
|
|
302
|
+
const issues = (await getChaosLog(page)).filter(
|
|
303
|
+
(e) => e.type === 'debug' && /already-patched|stale|orphaned|active-instance-conflict/.test(String(e.detail.reason ?? '')),
|
|
304
|
+
);
|
|
305
|
+
```
|
|
306
|
+
|
|
287
307
|
## Service Worker chaos
|
|
288
308
|
|
|
289
309
|
Intercept SW-originated fetches. Requires one line in your service-worker script.
|
|
@@ -298,6 +318,7 @@ import {
|
|
|
298
318
|
injectSWChaos,
|
|
299
319
|
removeSWChaos,
|
|
300
320
|
getSWChaosLog,
|
|
321
|
+
getSWChaosLogFromSW,
|
|
301
322
|
enableSWGroup,
|
|
302
323
|
disableSWGroup,
|
|
303
324
|
} from '@chaos-maker/playwright';
|
|
@@ -321,9 +342,13 @@ test('SW-fetched /api returns 503', async ({ page }) => {
|
|
|
321
342
|
});
|
|
322
343
|
```
|
|
323
344
|
|
|
345
|
+
Use `getSWChaosLog(page)` for the page-buffered event log. This is the default assertion surface because it reflects events broadcast from the Service Worker to the page. Use `getSWChaosLogFromSW(page)` when you need a direct pull from the Service Worker's in-memory log, such as debugging a missed page-side broadcast.
|
|
346
|
+
|
|
347
|
+
`removeSWChaos(page)` stops the worker engine and clears both the page-buffered and worker-side logs. For full browser isolation between tests, unregister the app's Service Worker or use a fresh browser context.
|
|
348
|
+
|
|
324
349
|
Two artifacts ship in `@chaos-maker/core`:
|
|
325
|
-
- `dist/sw.js`
|
|
326
|
-
- `dist/sw.mjs`
|
|
350
|
+
- `dist/sw.js` - IIFE bundle for classic SWs (`importScripts('/chaos-maker-sw.js')`).
|
|
351
|
+
- `dist/sw.mjs` - ESM bundle for module SWs (`import { installChaosSW } from '/chaos-maker-sw.mjs'`).
|
|
327
352
|
|
|
328
353
|
Serve whichever your SW type uses at a URL reachable from the service-worker scope.
|
|
329
354
|
|
|
@@ -6,55 +6,14 @@ import { fileURLToPath } from "url";
|
|
|
6
6
|
|
|
7
7
|
// src/trace.ts
|
|
8
8
|
import { test } from "@playwright/test";
|
|
9
|
+
import { formatStepTitle, shouldEmitStep } from "@chaos-maker/core";
|
|
10
|
+
import { formatStepTitle as formatStepTitle2, shouldEmitStep as shouldEmitStep2 } from "@chaos-maker/core";
|
|
9
11
|
var CHAOS_BINDING = "__chaosMakerReport";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const d = event.detail ?? {};
|
|
13
|
-
const parts = [];
|
|
14
|
-
const subject = d.url ?? d.selector;
|
|
15
|
-
if (subject) parts.push(truncate(subject, 48));
|
|
16
|
-
const outcome = formatOutcome(event);
|
|
17
|
-
if (outcome) parts.push(`\u2192 ${outcome}`);
|
|
18
|
-
if (!event.applied) parts.push("(skipped)");
|
|
19
|
-
return parts.length > 0 ? `${prefix} ${parts.join(" ")}` : prefix;
|
|
20
|
-
}
|
|
21
|
-
function formatOutcome(event) {
|
|
22
|
-
const d = event.detail ?? {};
|
|
23
|
-
switch (event.type) {
|
|
24
|
-
case "network:failure":
|
|
25
|
-
return d.statusCode != null ? String(d.statusCode) : null;
|
|
26
|
-
case "network:latency":
|
|
27
|
-
return d.delayMs != null ? `+${d.delayMs}ms` : null;
|
|
28
|
-
case "network:abort":
|
|
29
|
-
return "abort";
|
|
30
|
-
case "network:corruption":
|
|
31
|
-
return d.strategy ?? "corrupted";
|
|
32
|
-
case "network:cors":
|
|
33
|
-
return "cors-block";
|
|
34
|
-
case "ui:assault":
|
|
35
|
-
return d.action ?? null;
|
|
36
|
-
case "websocket:drop":
|
|
37
|
-
return d.direction ? `drop ${d.direction}` : "drop";
|
|
38
|
-
case "websocket:delay":
|
|
39
|
-
return d.delayMs != null ? `delay ${d.direction ?? ""} +${d.delayMs}ms` : "delay";
|
|
40
|
-
case "websocket:corrupt":
|
|
41
|
-
return d.strategy ?? "corrupt";
|
|
42
|
-
case "websocket:close":
|
|
43
|
-
return d.closeCode != null ? `close ${d.closeCode}` : "close";
|
|
44
|
-
default:
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
function truncate(s, max) {
|
|
49
|
-
if (s.length <= max) return s;
|
|
50
|
-
return `\u2026${s.slice(-(max - 1))}`;
|
|
51
|
-
}
|
|
52
|
-
function shouldEmitStep(event, verbose) {
|
|
53
|
-
if (event.type === "debug") return false;
|
|
54
|
-
if (event.applied) return true;
|
|
55
|
-
return verbose;
|
|
56
|
-
}
|
|
12
|
+
var TRACE_HANDLE_KEY = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.traceHandle");
|
|
13
|
+
var TRACE_BINDING_KEY = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.traceBinding");
|
|
57
14
|
async function createTraceReporter(page, testInfo, opts = {}) {
|
|
15
|
+
const existing = page[TRACE_HANDLE_KEY];
|
|
16
|
+
if (existing) return existing;
|
|
58
17
|
const verbose = opts.verbose ?? false;
|
|
59
18
|
const attachmentName = opts.attachmentName ?? "chaos-log.json";
|
|
60
19
|
const events = [];
|
|
@@ -66,31 +25,40 @@ async function createTraceReporter(page, testInfo, opts = {}) {
|
|
|
66
25
|
}).catch(() => {
|
|
67
26
|
});
|
|
68
27
|
};
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
28
|
+
let state = page[TRACE_BINDING_KEY];
|
|
29
|
+
if (!state) {
|
|
30
|
+
state = { handler };
|
|
31
|
+
page[TRACE_BINDING_KEY] = state;
|
|
32
|
+
await page.exposeBinding(CHAOS_BINDING, (source, event) => {
|
|
33
|
+
state.handler(source, event);
|
|
34
|
+
});
|
|
35
|
+
await page.addInitScript((bindingName) => {
|
|
36
|
+
const win = globalThis;
|
|
37
|
+
const attach = () => {
|
|
38
|
+
const utils = win.chaosUtils;
|
|
39
|
+
if (!utils || !utils.instance) return false;
|
|
40
|
+
if (utils.__chaosMakerTraceBound === utils.instance) return true;
|
|
41
|
+
utils.__chaosMakerTraceBound = utils.instance;
|
|
42
|
+
utils.instance.on("*", (event) => {
|
|
43
|
+
try {
|
|
44
|
+
if (typeof win[bindingName] === "function") {
|
|
45
|
+
win[bindingName](event);
|
|
46
|
+
}
|
|
47
|
+
} catch {
|
|
81
48
|
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
return
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
49
|
+
});
|
|
50
|
+
return true;
|
|
51
|
+
};
|
|
52
|
+
if (attach()) return;
|
|
53
|
+
const intervalId = setInterval(() => {
|
|
54
|
+
if (attach()) clearInterval(intervalId);
|
|
55
|
+
}, 10);
|
|
56
|
+
setTimeout(() => clearInterval(intervalId), 5e3);
|
|
57
|
+
}, CHAOS_BINDING);
|
|
58
|
+
} else {
|
|
59
|
+
state.handler = handler;
|
|
60
|
+
}
|
|
61
|
+
const handle = {
|
|
94
62
|
events,
|
|
95
63
|
dispose: async (seed = null) => {
|
|
96
64
|
const payload = {
|
|
@@ -105,13 +73,18 @@ async function createTraceReporter(page, testInfo, opts = {}) {
|
|
|
105
73
|
});
|
|
106
74
|
} catch {
|
|
107
75
|
}
|
|
76
|
+
if (page[TRACE_HANDLE_KEY] === handle) {
|
|
77
|
+
delete page[TRACE_HANDLE_KEY];
|
|
78
|
+
}
|
|
108
79
|
}
|
|
109
80
|
};
|
|
81
|
+
page[TRACE_HANDLE_KEY] = handle;
|
|
82
|
+
return handle;
|
|
110
83
|
}
|
|
111
84
|
|
|
112
85
|
// src/index.ts
|
|
113
86
|
import { Logger } from "@chaos-maker/core";
|
|
114
|
-
import { validateChaosConfig as validateChaosConfig3, ChaosConfigError } from "@chaos-maker/core";
|
|
87
|
+
import { validateChaosConfig as validateChaosConfig3, ChaosConfigError, formatSeedReproduction } from "@chaos-maker/core";
|
|
115
88
|
|
|
116
89
|
// src/sw.ts
|
|
117
90
|
import { validateChaosConfig, SW_BRIDGE_SOURCE } from "@chaos-maker/core";
|
|
@@ -145,8 +118,12 @@ async function removeSWChaos(page, opts = {}) {
|
|
|
145
118
|
async ({ timeoutMs: timeoutMs2 }) => {
|
|
146
119
|
const bridge = globalThis.__chaosMakerSWBridge;
|
|
147
120
|
if (!bridge) return;
|
|
148
|
-
|
|
149
|
-
|
|
121
|
+
try {
|
|
122
|
+
await bridge.stop(timeoutMs2);
|
|
123
|
+
} finally {
|
|
124
|
+
bridge.clearLocalLog();
|
|
125
|
+
await bridge.clearRemoteLog?.(timeoutMs2).catch(() => void 0);
|
|
126
|
+
}
|
|
150
127
|
},
|
|
151
128
|
{ timeoutMs }
|
|
152
129
|
).catch(() => {
|
|
@@ -214,7 +191,7 @@ function getCoreUmdPath() {
|
|
|
214
191
|
cachedUmdPath = resolve(coreDistDir, "chaos-maker.umd.js");
|
|
215
192
|
return cachedUmdPath;
|
|
216
193
|
}
|
|
217
|
-
var
|
|
194
|
+
var TRACE_HANDLE_KEY2 = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.traceHandle");
|
|
218
195
|
async function injectChaos(page, config, opts = {}) {
|
|
219
196
|
const validated = validateChaosConfig2(config, opts.validation);
|
|
220
197
|
const umdPath = getCoreUmdPath();
|
|
@@ -225,10 +202,10 @@ async function injectChaos(page, config, opts = {}) {
|
|
|
225
202
|
"[chaos-maker] tracing requires a `testInfo` in InjectChaosOptions. Use the fixture (`@chaos-maker/playwright/fixture`) or pass testInfo explicitly."
|
|
226
203
|
);
|
|
227
204
|
}
|
|
228
|
-
const existing = page[
|
|
205
|
+
const existing = page[TRACE_HANDLE_KEY2];
|
|
229
206
|
if (!existing) {
|
|
230
207
|
const handle = await createTraceReporter(page, opts.testInfo, opts.traceOptions);
|
|
231
|
-
page[
|
|
208
|
+
page[TRACE_HANDLE_KEY2] = handle;
|
|
232
209
|
}
|
|
233
210
|
}
|
|
234
211
|
const serialized = serializeForTransport(validated);
|
|
@@ -244,7 +221,7 @@ function resolveTracing(opts) {
|
|
|
244
221
|
return false;
|
|
245
222
|
}
|
|
246
223
|
async function removeChaos(page) {
|
|
247
|
-
const handle = page[
|
|
224
|
+
const handle = page[TRACE_HANDLE_KEY2];
|
|
248
225
|
let seed = null;
|
|
249
226
|
if (handle) {
|
|
250
227
|
try {
|
|
@@ -261,7 +238,7 @@ async function removeChaos(page) {
|
|
|
261
238
|
});
|
|
262
239
|
if (handle) {
|
|
263
240
|
await handle.dispose(seed);
|
|
264
|
-
delete page[
|
|
241
|
+
delete page[TRACE_HANDLE_KEY2];
|
|
265
242
|
}
|
|
266
243
|
}
|
|
267
244
|
async function getChaosLog(page) {
|
|
@@ -342,5 +319,6 @@ export {
|
|
|
342
319
|
getChaosSeed,
|
|
343
320
|
Logger,
|
|
344
321
|
validateChaosConfig3 as validateChaosConfig,
|
|
345
|
-
ChaosConfigError
|
|
322
|
+
ChaosConfigError,
|
|
323
|
+
formatSeedReproduction
|
|
346
324
|
};
|
package/dist/fixture.cjs
CHANGED
|
@@ -27,98 +27,66 @@ module.exports = __toCommonJS(fixture_exports);
|
|
|
27
27
|
var import_test2 = require("@playwright/test");
|
|
28
28
|
|
|
29
29
|
// src/index.ts
|
|
30
|
-
var
|
|
30
|
+
var import_core4 = require("@chaos-maker/core");
|
|
31
31
|
var import_path = require("path");
|
|
32
32
|
var import_module = require("module");
|
|
33
33
|
var import_url = require("url");
|
|
34
34
|
|
|
35
35
|
// src/trace.ts
|
|
36
36
|
var import_test = require("@playwright/test");
|
|
37
|
+
var import_core = require("@chaos-maker/core");
|
|
38
|
+
var import_core2 = require("@chaos-maker/core");
|
|
37
39
|
var CHAOS_BINDING = "__chaosMakerReport";
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const d = event.detail ?? {};
|
|
41
|
-
const parts = [];
|
|
42
|
-
const subject = d.url ?? d.selector;
|
|
43
|
-
if (subject) parts.push(truncate(subject, 48));
|
|
44
|
-
const outcome = formatOutcome(event);
|
|
45
|
-
if (outcome) parts.push(`\u2192 ${outcome}`);
|
|
46
|
-
if (!event.applied) parts.push("(skipped)");
|
|
47
|
-
return parts.length > 0 ? `${prefix} ${parts.join(" ")}` : prefix;
|
|
48
|
-
}
|
|
49
|
-
function formatOutcome(event) {
|
|
50
|
-
const d = event.detail ?? {};
|
|
51
|
-
switch (event.type) {
|
|
52
|
-
case "network:failure":
|
|
53
|
-
return d.statusCode != null ? String(d.statusCode) : null;
|
|
54
|
-
case "network:latency":
|
|
55
|
-
return d.delayMs != null ? `+${d.delayMs}ms` : null;
|
|
56
|
-
case "network:abort":
|
|
57
|
-
return "abort";
|
|
58
|
-
case "network:corruption":
|
|
59
|
-
return d.strategy ?? "corrupted";
|
|
60
|
-
case "network:cors":
|
|
61
|
-
return "cors-block";
|
|
62
|
-
case "ui:assault":
|
|
63
|
-
return d.action ?? null;
|
|
64
|
-
case "websocket:drop":
|
|
65
|
-
return d.direction ? `drop ${d.direction}` : "drop";
|
|
66
|
-
case "websocket:delay":
|
|
67
|
-
return d.delayMs != null ? `delay ${d.direction ?? ""} +${d.delayMs}ms` : "delay";
|
|
68
|
-
case "websocket:corrupt":
|
|
69
|
-
return d.strategy ?? "corrupt";
|
|
70
|
-
case "websocket:close":
|
|
71
|
-
return d.closeCode != null ? `close ${d.closeCode}` : "close";
|
|
72
|
-
default:
|
|
73
|
-
return null;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
function truncate(s, max) {
|
|
77
|
-
if (s.length <= max) return s;
|
|
78
|
-
return `\u2026${s.slice(-(max - 1))}`;
|
|
79
|
-
}
|
|
80
|
-
function shouldEmitStep(event, verbose) {
|
|
81
|
-
if (event.type === "debug") return false;
|
|
82
|
-
if (event.applied) return true;
|
|
83
|
-
return verbose;
|
|
84
|
-
}
|
|
40
|
+
var TRACE_HANDLE_KEY = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.traceHandle");
|
|
41
|
+
var TRACE_BINDING_KEY = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.traceBinding");
|
|
85
42
|
async function createTraceReporter(page, testInfo, opts = {}) {
|
|
43
|
+
const existing = page[TRACE_HANDLE_KEY];
|
|
44
|
+
if (existing) return existing;
|
|
86
45
|
const verbose = opts.verbose ?? false;
|
|
87
46
|
const attachmentName = opts.attachmentName ?? "chaos-log.json";
|
|
88
47
|
const events = [];
|
|
89
48
|
const handler = (_source, event) => {
|
|
90
49
|
events.push(event);
|
|
91
|
-
if (!shouldEmitStep(event, verbose)) return;
|
|
92
|
-
const title = formatStepTitle(event);
|
|
50
|
+
if (!(0, import_core.shouldEmitStep)(event, verbose)) return;
|
|
51
|
+
const title = (0, import_core.formatStepTitle)(event);
|
|
93
52
|
import_test.test.step(title, async () => {
|
|
94
53
|
}).catch(() => {
|
|
95
54
|
});
|
|
96
55
|
};
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
56
|
+
let state = page[TRACE_BINDING_KEY];
|
|
57
|
+
if (!state) {
|
|
58
|
+
state = { handler };
|
|
59
|
+
page[TRACE_BINDING_KEY] = state;
|
|
60
|
+
await page.exposeBinding(CHAOS_BINDING, (source, event) => {
|
|
61
|
+
state.handler(source, event);
|
|
62
|
+
});
|
|
63
|
+
await page.addInitScript((bindingName) => {
|
|
64
|
+
const win = globalThis;
|
|
65
|
+
const attach = () => {
|
|
66
|
+
const utils = win.chaosUtils;
|
|
67
|
+
if (!utils || !utils.instance) return false;
|
|
68
|
+
if (utils.__chaosMakerTraceBound === utils.instance) return true;
|
|
69
|
+
utils.__chaosMakerTraceBound = utils.instance;
|
|
70
|
+
utils.instance.on("*", (event) => {
|
|
71
|
+
try {
|
|
72
|
+
if (typeof win[bindingName] === "function") {
|
|
73
|
+
win[bindingName](event);
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
109
76
|
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
return
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
},
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
77
|
+
});
|
|
78
|
+
return true;
|
|
79
|
+
};
|
|
80
|
+
if (attach()) return;
|
|
81
|
+
const intervalId = setInterval(() => {
|
|
82
|
+
if (attach()) clearInterval(intervalId);
|
|
83
|
+
}, 10);
|
|
84
|
+
setTimeout(() => clearInterval(intervalId), 5e3);
|
|
85
|
+
}, CHAOS_BINDING);
|
|
86
|
+
} else {
|
|
87
|
+
state.handler = handler;
|
|
88
|
+
}
|
|
89
|
+
const handle = {
|
|
122
90
|
events,
|
|
123
91
|
dispose: async (seed = null) => {
|
|
124
92
|
const payload = {
|
|
@@ -133,24 +101,29 @@ async function createTraceReporter(page, testInfo, opts = {}) {
|
|
|
133
101
|
});
|
|
134
102
|
} catch {
|
|
135
103
|
}
|
|
104
|
+
if (page[TRACE_HANDLE_KEY] === handle) {
|
|
105
|
+
delete page[TRACE_HANDLE_KEY];
|
|
106
|
+
}
|
|
136
107
|
}
|
|
137
108
|
};
|
|
109
|
+
page[TRACE_HANDLE_KEY] = handle;
|
|
110
|
+
return handle;
|
|
138
111
|
}
|
|
139
112
|
|
|
140
113
|
// src/index.ts
|
|
141
|
-
var
|
|
142
|
-
var
|
|
114
|
+
var import_core5 = require("@chaos-maker/core");
|
|
115
|
+
var import_core6 = require("@chaos-maker/core");
|
|
143
116
|
|
|
144
117
|
// src/sw.ts
|
|
145
|
-
var
|
|
118
|
+
var import_core3 = require("@chaos-maker/core");
|
|
146
119
|
var BRIDGE_INIT_KEY = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.sw.bridgeInit");
|
|
147
120
|
var DEFAULT_SW_TOGGLE_TIMEOUT = 2e3;
|
|
148
121
|
async function ensurePageBridge(page) {
|
|
149
122
|
if (!page[BRIDGE_INIT_KEY]) {
|
|
150
|
-
await page.addInitScript({ content:
|
|
123
|
+
await page.addInitScript({ content: import_core3.SW_BRIDGE_SOURCE });
|
|
151
124
|
page[BRIDGE_INIT_KEY] = true;
|
|
152
125
|
}
|
|
153
|
-
await page.evaluate(
|
|
126
|
+
await page.evaluate(import_core3.SW_BRIDGE_SOURCE).catch(() => {
|
|
154
127
|
});
|
|
155
128
|
}
|
|
156
129
|
async function enableSWGroup(page, name, opts = {}) {
|
|
@@ -198,9 +171,9 @@ function getCoreUmdPath() {
|
|
|
198
171
|
cachedUmdPath = (0, import_path.resolve)(coreDistDir, "chaos-maker.umd.js");
|
|
199
172
|
return cachedUmdPath;
|
|
200
173
|
}
|
|
201
|
-
var
|
|
174
|
+
var TRACE_HANDLE_KEY2 = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.traceHandle");
|
|
202
175
|
async function injectChaos(page, config, opts = {}) {
|
|
203
|
-
const validated = (0,
|
|
176
|
+
const validated = (0, import_core4.validateChaosConfig)(config, opts.validation);
|
|
204
177
|
const umdPath = getCoreUmdPath();
|
|
205
178
|
const tracingEnabled = resolveTracing(opts);
|
|
206
179
|
if (tracingEnabled) {
|
|
@@ -209,13 +182,13 @@ async function injectChaos(page, config, opts = {}) {
|
|
|
209
182
|
"[chaos-maker] tracing requires a `testInfo` in InjectChaosOptions. Use the fixture (`@chaos-maker/playwright/fixture`) or pass testInfo explicitly."
|
|
210
183
|
);
|
|
211
184
|
}
|
|
212
|
-
const existing = page[
|
|
185
|
+
const existing = page[TRACE_HANDLE_KEY2];
|
|
213
186
|
if (!existing) {
|
|
214
187
|
const handle = await createTraceReporter(page, opts.testInfo, opts.traceOptions);
|
|
215
|
-
page[
|
|
188
|
+
page[TRACE_HANDLE_KEY2] = handle;
|
|
216
189
|
}
|
|
217
190
|
}
|
|
218
|
-
const serialized = (0,
|
|
191
|
+
const serialized = (0, import_core4.serializeForTransport)(validated);
|
|
219
192
|
await page.addInitScript((cfg) => {
|
|
220
193
|
const win = globalThis;
|
|
221
194
|
win.__CHAOS_CONFIG__ = cfg;
|
|
@@ -228,7 +201,7 @@ function resolveTracing(opts) {
|
|
|
228
201
|
return false;
|
|
229
202
|
}
|
|
230
203
|
async function removeChaos(page) {
|
|
231
|
-
const handle = page[
|
|
204
|
+
const handle = page[TRACE_HANDLE_KEY2];
|
|
232
205
|
let seed = null;
|
|
233
206
|
if (handle) {
|
|
234
207
|
try {
|
|
@@ -245,7 +218,7 @@ async function removeChaos(page) {
|
|
|
245
218
|
});
|
|
246
219
|
if (handle) {
|
|
247
220
|
await handle.dispose(seed);
|
|
248
|
-
delete page[
|
|
221
|
+
delete page[TRACE_HANDLE_KEY2];
|
|
249
222
|
}
|
|
250
223
|
}
|
|
251
224
|
async function getChaosLog(page) {
|
package/dist/fixture.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -20,12 +20,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
ChaosConfigError: () =>
|
|
24
|
-
Logger: () =>
|
|
23
|
+
ChaosConfigError: () => import_core6.ChaosConfigError,
|
|
24
|
+
Logger: () => import_core5.Logger,
|
|
25
25
|
disableGroup: () => disableGroup,
|
|
26
26
|
disableSWGroup: () => disableSWGroup,
|
|
27
27
|
enableGroup: () => enableGroup,
|
|
28
28
|
enableSWGroup: () => enableSWGroup,
|
|
29
|
+
formatSeedReproduction: () => import_core6.formatSeedReproduction,
|
|
29
30
|
getChaosLog: () => getChaosLog,
|
|
30
31
|
getChaosSeed: () => getChaosSeed,
|
|
31
32
|
getSWChaosLog: () => getSWChaosLog,
|
|
@@ -34,101 +35,69 @@ __export(index_exports, {
|
|
|
34
35
|
injectSWChaos: () => injectSWChaos,
|
|
35
36
|
removeChaos: () => removeChaos,
|
|
36
37
|
removeSWChaos: () => removeSWChaos,
|
|
37
|
-
validateChaosConfig: () =>
|
|
38
|
+
validateChaosConfig: () => import_core6.validateChaosConfig
|
|
38
39
|
});
|
|
39
40
|
module.exports = __toCommonJS(index_exports);
|
|
40
|
-
var
|
|
41
|
+
var import_core4 = require("@chaos-maker/core");
|
|
41
42
|
var import_path = require("path");
|
|
42
43
|
var import_module = require("module");
|
|
43
44
|
var import_url = require("url");
|
|
44
45
|
|
|
45
46
|
// src/trace.ts
|
|
46
47
|
var import_test = require("@playwright/test");
|
|
48
|
+
var import_core = require("@chaos-maker/core");
|
|
49
|
+
var import_core2 = require("@chaos-maker/core");
|
|
47
50
|
var CHAOS_BINDING = "__chaosMakerReport";
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const d = event.detail ?? {};
|
|
51
|
-
const parts = [];
|
|
52
|
-
const subject = d.url ?? d.selector;
|
|
53
|
-
if (subject) parts.push(truncate(subject, 48));
|
|
54
|
-
const outcome = formatOutcome(event);
|
|
55
|
-
if (outcome) parts.push(`\u2192 ${outcome}`);
|
|
56
|
-
if (!event.applied) parts.push("(skipped)");
|
|
57
|
-
return parts.length > 0 ? `${prefix} ${parts.join(" ")}` : prefix;
|
|
58
|
-
}
|
|
59
|
-
function formatOutcome(event) {
|
|
60
|
-
const d = event.detail ?? {};
|
|
61
|
-
switch (event.type) {
|
|
62
|
-
case "network:failure":
|
|
63
|
-
return d.statusCode != null ? String(d.statusCode) : null;
|
|
64
|
-
case "network:latency":
|
|
65
|
-
return d.delayMs != null ? `+${d.delayMs}ms` : null;
|
|
66
|
-
case "network:abort":
|
|
67
|
-
return "abort";
|
|
68
|
-
case "network:corruption":
|
|
69
|
-
return d.strategy ?? "corrupted";
|
|
70
|
-
case "network:cors":
|
|
71
|
-
return "cors-block";
|
|
72
|
-
case "ui:assault":
|
|
73
|
-
return d.action ?? null;
|
|
74
|
-
case "websocket:drop":
|
|
75
|
-
return d.direction ? `drop ${d.direction}` : "drop";
|
|
76
|
-
case "websocket:delay":
|
|
77
|
-
return d.delayMs != null ? `delay ${d.direction ?? ""} +${d.delayMs}ms` : "delay";
|
|
78
|
-
case "websocket:corrupt":
|
|
79
|
-
return d.strategy ?? "corrupt";
|
|
80
|
-
case "websocket:close":
|
|
81
|
-
return d.closeCode != null ? `close ${d.closeCode}` : "close";
|
|
82
|
-
default:
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
function truncate(s, max) {
|
|
87
|
-
if (s.length <= max) return s;
|
|
88
|
-
return `\u2026${s.slice(-(max - 1))}`;
|
|
89
|
-
}
|
|
90
|
-
function shouldEmitStep(event, verbose) {
|
|
91
|
-
if (event.type === "debug") return false;
|
|
92
|
-
if (event.applied) return true;
|
|
93
|
-
return verbose;
|
|
94
|
-
}
|
|
51
|
+
var TRACE_HANDLE_KEY = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.traceHandle");
|
|
52
|
+
var TRACE_BINDING_KEY = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.traceBinding");
|
|
95
53
|
async function createTraceReporter(page, testInfo, opts = {}) {
|
|
54
|
+
const existing = page[TRACE_HANDLE_KEY];
|
|
55
|
+
if (existing) return existing;
|
|
96
56
|
const verbose = opts.verbose ?? false;
|
|
97
57
|
const attachmentName = opts.attachmentName ?? "chaos-log.json";
|
|
98
58
|
const events = [];
|
|
99
59
|
const handler = (_source, event) => {
|
|
100
60
|
events.push(event);
|
|
101
|
-
if (!shouldEmitStep(event, verbose)) return;
|
|
102
|
-
const title = formatStepTitle(event);
|
|
61
|
+
if (!(0, import_core.shouldEmitStep)(event, verbose)) return;
|
|
62
|
+
const title = (0, import_core.formatStepTitle)(event);
|
|
103
63
|
import_test.test.step(title, async () => {
|
|
104
64
|
}).catch(() => {
|
|
105
65
|
});
|
|
106
66
|
};
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
67
|
+
let state = page[TRACE_BINDING_KEY];
|
|
68
|
+
if (!state) {
|
|
69
|
+
state = { handler };
|
|
70
|
+
page[TRACE_BINDING_KEY] = state;
|
|
71
|
+
await page.exposeBinding(CHAOS_BINDING, (source, event) => {
|
|
72
|
+
state.handler(source, event);
|
|
73
|
+
});
|
|
74
|
+
await page.addInitScript((bindingName) => {
|
|
75
|
+
const win = globalThis;
|
|
76
|
+
const attach = () => {
|
|
77
|
+
const utils = win.chaosUtils;
|
|
78
|
+
if (!utils || !utils.instance) return false;
|
|
79
|
+
if (utils.__chaosMakerTraceBound === utils.instance) return true;
|
|
80
|
+
utils.__chaosMakerTraceBound = utils.instance;
|
|
81
|
+
utils.instance.on("*", (event) => {
|
|
82
|
+
try {
|
|
83
|
+
if (typeof win[bindingName] === "function") {
|
|
84
|
+
win[bindingName](event);
|
|
85
|
+
}
|
|
86
|
+
} catch {
|
|
119
87
|
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
return
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
},
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
88
|
+
});
|
|
89
|
+
return true;
|
|
90
|
+
};
|
|
91
|
+
if (attach()) return;
|
|
92
|
+
const intervalId = setInterval(() => {
|
|
93
|
+
if (attach()) clearInterval(intervalId);
|
|
94
|
+
}, 10);
|
|
95
|
+
setTimeout(() => clearInterval(intervalId), 5e3);
|
|
96
|
+
}, CHAOS_BINDING);
|
|
97
|
+
} else {
|
|
98
|
+
state.handler = handler;
|
|
99
|
+
}
|
|
100
|
+
const handle = {
|
|
132
101
|
events,
|
|
133
102
|
dispose: async (seed = null) => {
|
|
134
103
|
const payload = {
|
|
@@ -143,28 +112,33 @@ async function createTraceReporter(page, testInfo, opts = {}) {
|
|
|
143
112
|
});
|
|
144
113
|
} catch {
|
|
145
114
|
}
|
|
115
|
+
if (page[TRACE_HANDLE_KEY] === handle) {
|
|
116
|
+
delete page[TRACE_HANDLE_KEY];
|
|
117
|
+
}
|
|
146
118
|
}
|
|
147
119
|
};
|
|
120
|
+
page[TRACE_HANDLE_KEY] = handle;
|
|
121
|
+
return handle;
|
|
148
122
|
}
|
|
149
123
|
|
|
150
124
|
// src/index.ts
|
|
151
|
-
var
|
|
152
|
-
var
|
|
125
|
+
var import_core5 = require("@chaos-maker/core");
|
|
126
|
+
var import_core6 = require("@chaos-maker/core");
|
|
153
127
|
|
|
154
128
|
// src/sw.ts
|
|
155
|
-
var
|
|
129
|
+
var import_core3 = require("@chaos-maker/core");
|
|
156
130
|
var BRIDGE_INIT_KEY = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.sw.bridgeInit");
|
|
157
131
|
var DEFAULT_SW_TOGGLE_TIMEOUT = 2e3;
|
|
158
132
|
async function ensurePageBridge(page) {
|
|
159
133
|
if (!page[BRIDGE_INIT_KEY]) {
|
|
160
|
-
await page.addInitScript({ content:
|
|
134
|
+
await page.addInitScript({ content: import_core3.SW_BRIDGE_SOURCE });
|
|
161
135
|
page[BRIDGE_INIT_KEY] = true;
|
|
162
136
|
}
|
|
163
|
-
await page.evaluate(
|
|
137
|
+
await page.evaluate(import_core3.SW_BRIDGE_SOURCE).catch(() => {
|
|
164
138
|
});
|
|
165
139
|
}
|
|
166
140
|
async function injectSWChaos(page, config, opts = {}) {
|
|
167
|
-
const validated = (0,
|
|
141
|
+
const validated = (0, import_core3.validateChaosConfig)(config, opts.validation);
|
|
168
142
|
const timeoutMs = opts.timeoutMs ?? 1e4;
|
|
169
143
|
await ensurePageBridge(page);
|
|
170
144
|
const result = await page.evaluate(
|
|
@@ -183,8 +157,12 @@ async function removeSWChaos(page, opts = {}) {
|
|
|
183
157
|
async ({ timeoutMs: timeoutMs2 }) => {
|
|
184
158
|
const bridge = globalThis.__chaosMakerSWBridge;
|
|
185
159
|
if (!bridge) return;
|
|
186
|
-
|
|
187
|
-
|
|
160
|
+
try {
|
|
161
|
+
await bridge.stop(timeoutMs2);
|
|
162
|
+
} finally {
|
|
163
|
+
bridge.clearLocalLog();
|
|
164
|
+
await bridge.clearRemoteLog?.(timeoutMs2).catch(() => void 0);
|
|
165
|
+
}
|
|
188
166
|
},
|
|
189
167
|
{ timeoutMs }
|
|
190
168
|
).catch(() => {
|
|
@@ -253,9 +231,9 @@ function getCoreUmdPath() {
|
|
|
253
231
|
cachedUmdPath = (0, import_path.resolve)(coreDistDir, "chaos-maker.umd.js");
|
|
254
232
|
return cachedUmdPath;
|
|
255
233
|
}
|
|
256
|
-
var
|
|
234
|
+
var TRACE_HANDLE_KEY2 = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.traceHandle");
|
|
257
235
|
async function injectChaos(page, config, opts = {}) {
|
|
258
|
-
const validated = (0,
|
|
236
|
+
const validated = (0, import_core4.validateChaosConfig)(config, opts.validation);
|
|
259
237
|
const umdPath = getCoreUmdPath();
|
|
260
238
|
const tracingEnabled = resolveTracing(opts);
|
|
261
239
|
if (tracingEnabled) {
|
|
@@ -264,13 +242,13 @@ async function injectChaos(page, config, opts = {}) {
|
|
|
264
242
|
"[chaos-maker] tracing requires a `testInfo` in InjectChaosOptions. Use the fixture (`@chaos-maker/playwright/fixture`) or pass testInfo explicitly."
|
|
265
243
|
);
|
|
266
244
|
}
|
|
267
|
-
const existing = page[
|
|
245
|
+
const existing = page[TRACE_HANDLE_KEY2];
|
|
268
246
|
if (!existing) {
|
|
269
247
|
const handle = await createTraceReporter(page, opts.testInfo, opts.traceOptions);
|
|
270
|
-
page[
|
|
248
|
+
page[TRACE_HANDLE_KEY2] = handle;
|
|
271
249
|
}
|
|
272
250
|
}
|
|
273
|
-
const serialized = (0,
|
|
251
|
+
const serialized = (0, import_core4.serializeForTransport)(validated);
|
|
274
252
|
await page.addInitScript((cfg) => {
|
|
275
253
|
const win = globalThis;
|
|
276
254
|
win.__CHAOS_CONFIG__ = cfg;
|
|
@@ -283,7 +261,7 @@ function resolveTracing(opts) {
|
|
|
283
261
|
return false;
|
|
284
262
|
}
|
|
285
263
|
async function removeChaos(page) {
|
|
286
|
-
const handle = page[
|
|
264
|
+
const handle = page[TRACE_HANDLE_KEY2];
|
|
287
265
|
let seed = null;
|
|
288
266
|
if (handle) {
|
|
289
267
|
try {
|
|
@@ -300,7 +278,7 @@ async function removeChaos(page) {
|
|
|
300
278
|
});
|
|
301
279
|
if (handle) {
|
|
302
280
|
await handle.dispose(seed);
|
|
303
|
-
delete page[
|
|
281
|
+
delete page[TRACE_HANDLE_KEY2];
|
|
304
282
|
}
|
|
305
283
|
}
|
|
306
284
|
async function getChaosLog(page) {
|
|
@@ -373,6 +351,7 @@ async function getChaosSeed(page) {
|
|
|
373
351
|
disableSWGroup,
|
|
374
352
|
enableGroup,
|
|
375
353
|
enableSWGroup,
|
|
354
|
+
formatSeedReproduction,
|
|
376
355
|
getChaosLog,
|
|
377
356
|
getChaosSeed,
|
|
378
357
|
getSWChaosLog,
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Page, TestInfo } from '@playwright/test';
|
|
2
2
|
import { ChaosEvent, ValidateChaosConfigOptions, ChaosConfig } from '@chaos-maker/core';
|
|
3
|
-
export { ChaosConfig, ChaosConfigError, ChaosDebugStage, ChaosEvent, ChaosLifecyclePhase, CorruptionStrategy, CustomRuleValidator, CustomValidatorMap, DebugOptions, GraphQLOperationMatcher, Logger, NetworkAbortConfig, NetworkConfig, NetworkCorruptionConfig, NetworkCorsConfig, NetworkFailureConfig, NetworkLatencyConfig, NetworkRuleMatchers, RuleType, SSECloseConfig, SSEConfig, SSECorruptConfig, SSECorruptionStrategy, SSEDelayConfig, SSEDropConfig, SSEEventTypeMatcher, ValidateChaosConfigOptions, ValidationIssue, ValidationIssueCode, WebSocketCloseConfig, WebSocketConfig, WebSocketCorruptConfig, WebSocketCorruptionStrategy, WebSocketDelayConfig, WebSocketDirection, WebSocketDropConfig, validateChaosConfig } from '@chaos-maker/core';
|
|
3
|
+
export { ChaosConfig, ChaosConfigError, ChaosDebugStage, ChaosEvent, ChaosLifecyclePhase, CorruptionStrategy, CustomRuleValidator, CustomValidatorMap, DebugOptions, GraphQLOperationMatcher, Logger, NetworkAbortConfig, NetworkConfig, NetworkCorruptionConfig, NetworkCorsConfig, NetworkFailureConfig, NetworkLatencyConfig, NetworkRuleMatchers, RuleType, SSECloseConfig, SSEConfig, SSECorruptConfig, SSECorruptionStrategy, SSEDelayConfig, SSEDropConfig, SSEEventTypeMatcher, ValidateChaosConfigOptions, ValidationIssue, ValidationIssueCode, WebSocketCloseConfig, WebSocketConfig, WebSocketCorruptConfig, WebSocketCorruptionStrategy, WebSocketDelayConfig, WebSocketDirection, WebSocketDropConfig, formatSeedReproduction, validateChaosConfig } from '@chaos-maker/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Shape of the JSON attachment written to `testInfo.attachments` on teardown.
|
|
@@ -10,6 +10,7 @@ interface ChaosTraceAttachment {
|
|
|
10
10
|
eventCount: number;
|
|
11
11
|
events: ChaosEvent[];
|
|
12
12
|
}
|
|
13
|
+
|
|
13
14
|
interface TraceReporterOptions {
|
|
14
15
|
/** Emit `test.step` for `applied:false` diagnostic events too. Default false. */
|
|
15
16
|
verbose?: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Page, TestInfo } from '@playwright/test';
|
|
2
2
|
import { ChaosEvent, ValidateChaosConfigOptions, ChaosConfig } from '@chaos-maker/core';
|
|
3
|
-
export { ChaosConfig, ChaosConfigError, ChaosDebugStage, ChaosEvent, ChaosLifecyclePhase, CorruptionStrategy, CustomRuleValidator, CustomValidatorMap, DebugOptions, GraphQLOperationMatcher, Logger, NetworkAbortConfig, NetworkConfig, NetworkCorruptionConfig, NetworkCorsConfig, NetworkFailureConfig, NetworkLatencyConfig, NetworkRuleMatchers, RuleType, SSECloseConfig, SSEConfig, SSECorruptConfig, SSECorruptionStrategy, SSEDelayConfig, SSEDropConfig, SSEEventTypeMatcher, ValidateChaosConfigOptions, ValidationIssue, ValidationIssueCode, WebSocketCloseConfig, WebSocketConfig, WebSocketCorruptConfig, WebSocketCorruptionStrategy, WebSocketDelayConfig, WebSocketDirection, WebSocketDropConfig, validateChaosConfig } from '@chaos-maker/core';
|
|
3
|
+
export { ChaosConfig, ChaosConfigError, ChaosDebugStage, ChaosEvent, ChaosLifecyclePhase, CorruptionStrategy, CustomRuleValidator, CustomValidatorMap, DebugOptions, GraphQLOperationMatcher, Logger, NetworkAbortConfig, NetworkConfig, NetworkCorruptionConfig, NetworkCorsConfig, NetworkFailureConfig, NetworkLatencyConfig, NetworkRuleMatchers, RuleType, SSECloseConfig, SSEConfig, SSECorruptConfig, SSECorruptionStrategy, SSEDelayConfig, SSEDropConfig, SSEEventTypeMatcher, ValidateChaosConfigOptions, ValidationIssue, ValidationIssueCode, WebSocketCloseConfig, WebSocketConfig, WebSocketCorruptConfig, WebSocketCorruptionStrategy, WebSocketDelayConfig, WebSocketDirection, WebSocketDropConfig, formatSeedReproduction, validateChaosConfig } from '@chaos-maker/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Shape of the JSON attachment written to `testInfo.attachments` on teardown.
|
|
@@ -10,6 +10,7 @@ interface ChaosTraceAttachment {
|
|
|
10
10
|
eventCount: number;
|
|
11
11
|
events: ChaosEvent[];
|
|
12
12
|
}
|
|
13
|
+
|
|
13
14
|
interface TraceReporterOptions {
|
|
14
15
|
/** Emit `test.step` for `applied:false` diagnostic events too. Default false. */
|
|
15
16
|
verbose?: boolean;
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
disableSWGroup,
|
|
6
6
|
enableGroup,
|
|
7
7
|
enableSWGroup,
|
|
8
|
+
formatSeedReproduction,
|
|
8
9
|
getChaosLog,
|
|
9
10
|
getChaosSeed,
|
|
10
11
|
getSWChaosLog,
|
|
@@ -14,7 +15,7 @@ import {
|
|
|
14
15
|
removeChaos,
|
|
15
16
|
removeSWChaos,
|
|
16
17
|
validateChaosConfig
|
|
17
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-ZJZRSTXG.js";
|
|
18
19
|
export {
|
|
19
20
|
ChaosConfigError,
|
|
20
21
|
Logger,
|
|
@@ -22,6 +23,7 @@ export {
|
|
|
22
23
|
disableSWGroup,
|
|
23
24
|
enableGroup,
|
|
24
25
|
enableSWGroup,
|
|
26
|
+
formatSeedReproduction,
|
|
25
27
|
getChaosLog,
|
|
26
28
|
getChaosSeed,
|
|
27
29
|
getSWChaosLog,
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chaos-maker/playwright",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Playwright adapter for @chaos-maker/core
|
|
5
|
+
"description": "Playwright adapter for @chaos-maker/core - one-line chaos injection in E2E tests",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"chaos-engineering",
|
|
8
8
|
"playwright",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"dist"
|
|
50
50
|
],
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@chaos-maker/core": "0.
|
|
52
|
+
"@chaos-maker/core": "0.6.0"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"@playwright/test": ">=1.40.0"
|