@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 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 `@chaos-maker/playwright` loads the core UMD bundle into the browser page.
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
- await injectChaos(page, {
23
- network: {
24
- failures: [{ urlPattern: '/api/data', statusCode: 503, probability: 1.0 }]
25
- }
26
- });
27
-
28
- await page.goto('/dashboard');
29
- await expect(page.getByText('Something went wrong')).toBeVisible();
30
-
31
- // Check what chaos was applied
32
- const log = await getChaosLog(page);
33
- expect(log.some(e => e.type === 'network:failure' && e.applied)).toBe(true);
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` Playwright `Page` instance
186
- - `config` `ChaosConfig` object (see [@chaos-maker/core](../core/) for full config reference)
187
- - `opts` optional. `InjectChaosOptions`:
188
- - `tracing?: boolean | 'auto'` emit chaos events into the Playwright trace (see [Debugging with trace](#debugging-with-trace)). Requires `testInfo` when `true`.
189
- - `testInfo?: TestInfo` active Playwright `TestInfo` (supplied automatically by the fixture).
190
- - `traceOptions?: { verbose?: boolean; attachmentName?: string }` tune trace output.
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[]` every chaos check emitted since injection, with `applied: true/false`.
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)` same as `injectChaos(page, config)`
213
- - `chaos.remove()` same as `removeChaos(page)` (also called automatically after each test)
214
- - `chaos.getLog()` same as `getChaosLog(page)`
215
- - `chaos.enableGroup(name)` same as `enableGroup(page, name)`
216
- - `chaos.disableGroup(name)` same as `disableGroup(page, name)`
217
- - `chaos.enableSWGroup(name, opts?)` same as `enableSWGroup(page, name, opts)`
218
- - `chaos.disableSWGroup(name, opts?)` same as `disableSWGroup(page, 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 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/).
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 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`.
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` IIFE bundle for classic SWs (`importScripts('/chaos-maker-sw.js')`).
326
- - `dist/sw.mjs` ESM bundle for module SWs (`import { installChaosSW } from '/chaos-maker-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
- function formatStepTitle(event) {
11
- const prefix = `chaos:${event.type}`;
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
- await page.exposeBinding(CHAOS_BINDING, handler);
70
- await page.addInitScript((bindingName) => {
71
- const win = globalThis;
72
- const attach = () => {
73
- const utils = win.chaosUtils;
74
- if (!utils || !utils.instance) return false;
75
- if (utils.__chaosMakerTraceBound === utils.instance) return true;
76
- utils.__chaosMakerTraceBound = utils.instance;
77
- utils.instance.on("*", (event) => {
78
- try {
79
- if (typeof win[bindingName] === "function") {
80
- win[bindingName](event);
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
- } catch {
83
- }
84
- });
85
- return true;
86
- };
87
- if (attach()) return;
88
- const intervalId = setInterval(() => {
89
- if (attach()) clearInterval(intervalId);
90
- }, 10);
91
- setTimeout(() => clearInterval(intervalId), 5e3);
92
- }, CHAOS_BINDING);
93
- return {
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
- await bridge.stop(timeoutMs2);
149
- bridge.clearLocalLog();
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 TRACE_HANDLE_KEY = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.traceHandle");
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[TRACE_HANDLE_KEY];
205
+ const existing = page[TRACE_HANDLE_KEY2];
229
206
  if (!existing) {
230
207
  const handle = await createTraceReporter(page, opts.testInfo, opts.traceOptions);
231
- page[TRACE_HANDLE_KEY] = handle;
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[TRACE_HANDLE_KEY];
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[TRACE_HANDLE_KEY];
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 import_core2 = require("@chaos-maker/core");
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
- function formatStepTitle(event) {
39
- const prefix = `chaos:${event.type}`;
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
- await page.exposeBinding(CHAOS_BINDING, handler);
98
- await page.addInitScript((bindingName) => {
99
- const win = globalThis;
100
- const attach = () => {
101
- const utils = win.chaosUtils;
102
- if (!utils || !utils.instance) return false;
103
- if (utils.__chaosMakerTraceBound === utils.instance) return true;
104
- utils.__chaosMakerTraceBound = utils.instance;
105
- utils.instance.on("*", (event) => {
106
- try {
107
- if (typeof win[bindingName] === "function") {
108
- win[bindingName](event);
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
- } catch {
111
- }
112
- });
113
- return true;
114
- };
115
- if (attach()) return;
116
- const intervalId = setInterval(() => {
117
- if (attach()) clearInterval(intervalId);
118
- }, 10);
119
- setTimeout(() => clearInterval(intervalId), 5e3);
120
- }, CHAOS_BINDING);
121
- return {
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 import_core3 = require("@chaos-maker/core");
142
- var import_core4 = require("@chaos-maker/core");
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 import_core = require("@chaos-maker/core");
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: import_core.SW_BRIDGE_SOURCE });
123
+ await page.addInitScript({ content: import_core3.SW_BRIDGE_SOURCE });
151
124
  page[BRIDGE_INIT_KEY] = true;
152
125
  }
153
- await page.evaluate(import_core.SW_BRIDGE_SOURCE).catch(() => {
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 TRACE_HANDLE_KEY = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.traceHandle");
174
+ var TRACE_HANDLE_KEY2 = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.traceHandle");
202
175
  async function injectChaos(page, config, opts = {}) {
203
- const validated = (0, import_core2.validateChaosConfig)(config, opts.validation);
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[TRACE_HANDLE_KEY];
185
+ const existing = page[TRACE_HANDLE_KEY2];
213
186
  if (!existing) {
214
187
  const handle = await createTraceReporter(page, opts.testInfo, opts.traceOptions);
215
- page[TRACE_HANDLE_KEY] = handle;
188
+ page[TRACE_HANDLE_KEY2] = handle;
216
189
  }
217
190
  }
218
- const serialized = (0, import_core2.serializeForTransport)(validated);
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[TRACE_HANDLE_KEY];
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[TRACE_HANDLE_KEY];
221
+ delete page[TRACE_HANDLE_KEY2];
249
222
  }
250
223
  }
251
224
  async function getChaosLog(page) {
package/dist/fixture.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  getChaosSeed,
8
8
  injectChaos,
9
9
  removeChaos
10
- } from "./chunk-IJDMHBUQ.js";
10
+ } from "./chunk-ZJZRSTXG.js";
11
11
 
12
12
  // src/fixture.ts
13
13
  import { test as base } from "@playwright/test";
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: () => import_core4.ChaosConfigError,
24
- Logger: () => import_core3.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: () => import_core4.validateChaosConfig
38
+ validateChaosConfig: () => import_core6.validateChaosConfig
38
39
  });
39
40
  module.exports = __toCommonJS(index_exports);
40
- var import_core2 = require("@chaos-maker/core");
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
- function formatStepTitle(event) {
49
- const prefix = `chaos:${event.type}`;
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
- await page.exposeBinding(CHAOS_BINDING, handler);
108
- await page.addInitScript((bindingName) => {
109
- const win = globalThis;
110
- const attach = () => {
111
- const utils = win.chaosUtils;
112
- if (!utils || !utils.instance) return false;
113
- if (utils.__chaosMakerTraceBound === utils.instance) return true;
114
- utils.__chaosMakerTraceBound = utils.instance;
115
- utils.instance.on("*", (event) => {
116
- try {
117
- if (typeof win[bindingName] === "function") {
118
- win[bindingName](event);
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
- } catch {
121
- }
122
- });
123
- return true;
124
- };
125
- if (attach()) return;
126
- const intervalId = setInterval(() => {
127
- if (attach()) clearInterval(intervalId);
128
- }, 10);
129
- setTimeout(() => clearInterval(intervalId), 5e3);
130
- }, CHAOS_BINDING);
131
- return {
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 import_core3 = require("@chaos-maker/core");
152
- var import_core4 = require("@chaos-maker/core");
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 import_core = require("@chaos-maker/core");
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: import_core.SW_BRIDGE_SOURCE });
134
+ await page.addInitScript({ content: import_core3.SW_BRIDGE_SOURCE });
161
135
  page[BRIDGE_INIT_KEY] = true;
162
136
  }
163
- await page.evaluate(import_core.SW_BRIDGE_SOURCE).catch(() => {
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, import_core.validateChaosConfig)(config, opts.validation);
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
- await bridge.stop(timeoutMs2);
187
- bridge.clearLocalLog();
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 TRACE_HANDLE_KEY = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.traceHandle");
234
+ var TRACE_HANDLE_KEY2 = /* @__PURE__ */ Symbol.for("chaos-maker.playwright.traceHandle");
257
235
  async function injectChaos(page, config, opts = {}) {
258
- const validated = (0, import_core2.validateChaosConfig)(config, opts.validation);
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[TRACE_HANDLE_KEY];
245
+ const existing = page[TRACE_HANDLE_KEY2];
268
246
  if (!existing) {
269
247
  const handle = await createTraceReporter(page, opts.testInfo, opts.traceOptions);
270
- page[TRACE_HANDLE_KEY] = handle;
248
+ page[TRACE_HANDLE_KEY2] = handle;
271
249
  }
272
250
  }
273
- const serialized = (0, import_core2.serializeForTransport)(validated);
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[TRACE_HANDLE_KEY];
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[TRACE_HANDLE_KEY];
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-IJDMHBUQ.js";
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.5.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
- "description": "Playwright adapter for @chaos-maker/core one-line chaos injection in E2E tests",
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.5.0"
52
+ "@chaos-maker/core": "0.6.0"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "@playwright/test": ">=1.40.0"