@chaos-maker/webdriverio
v0.4.0
Published
WebdriverIO adapter for @chaos-maker/core — one-line chaos injection in WDIO tests
Maintainers
Readme
@chaos-maker/webdriverio
WebdriverIO adapter for @chaos-maker/core. Custom commands for one-line chaos injection in WebdriverIO E2E tests.
Install
npm install --save-dev @chaos-maker/core @chaos-maker/webdriverioBoth packages are required. webdriverio (>=8) is a peer dependency.
Setup
Register the custom commands once in wdio.conf.ts:
import { registerChaosCommands, registerSWChaosCommands } from '@chaos-maker/webdriverio';
export const config: WebdriverIO.Config = {
// ...
async before() {
registerChaosCommands(browser);
registerSWChaosCommands(browser);
},
};That's it. Every spec now has browser.injectChaos, browser.removeChaos, browser.getChaosLog, browser.getChaosSeed, and the Service Worker helpers.
Usage
import { browser, $ } from '@wdio/globals';
describe('resilience', () => {
it('handles API failure', async () => {
await browser.url('/');
await browser.injectChaos({
network: {
failures: [{ urlPattern: '/api', statusCode: 503, probability: 1.0 }],
},
});
await $('button.refresh').click();
await expect($('#status')).toHaveText('Error!');
});
});You can also call the functional API without registering commands:
import { injectChaos, getChaosLog } from '@chaos-maker/webdriverio';
await browser.url('/');
await injectChaos(browser, { /* config */ });
const log = await getChaosLog(browser);Important: inject after navigation
WebDriver has no cross-browser pre-navigation hook, so @chaos-maker/webdriverio injects chaos after browser.url(...) completes. Requests issued during the initial page load are not intercepted.
If your app fires its first API call on boot and you need that request to be chaotic too, use @chaos-maker/playwright or @chaos-maker/cypress instead — both support pre-navigation injection.
For requests fired on user interaction (clicks, form submits), the adapter works identically to the Playwright and Cypress ones.
SSE and GraphQL
Inject after browser.url() and before the click or action that creates the stream or request.
await browser.url('/dashboard');
await browser.injectChaos({
seed: 42,
sse: {
drops: [{ urlPattern: '/events', eventType: 'token', probability: 0.1 }],
},
network: {
failures: [{
urlPattern: '/graphql',
graphqlOperation: /^Get/,
statusCode: 503,
probability: 1,
}],
},
});
await $('#refresh').click();Content Security Policy
injectChaos appends an inline <script> to the page. A restrictive script-src policy (no 'unsafe-inline' / no matching nonce) blocks it and injectChaos throws [chaos-maker] injectChaos did not start. — relax CSP for your test environment (e.g. add 'unsafe-inline' or a matching nonce) or serve a chaos-friendly CSP from your test fixture.
API
registerChaosCommands(browser)
Attach the injectChaos, removeChaos, getChaosLog, and getChaosSeed methods as custom commands on the given browser object. Call once in wdio.conf.ts' before hook.
injectChaos(browser, config)
Inject chaos into the current page. config matches @chaos-maker/core's ChaosConfig.
removeChaos(browser)
Stop chaos and restore the original fetch / XHR / WebSocket / DOM behaviour on the current page.
getChaosLog(browser): Promise<ChaosEvent[]>
Read every chaos decision emitted since injectChaos was called — applied or skipped.
getChaosSeed(browser): Promise<number | null>
Read the PRNG seed used by the active chaos instance. Log this on test failure to replay the exact sequence of chaos decisions with a fixed seed.
Service Worker chaos
Register the SW commands in wdio.conf.ts:
import { registerChaosCommands, registerSWChaosCommands } from '@chaos-maker/webdriverio';
// ...
async before() {
registerChaosCommands(browser);
registerSWChaosCommands(browser);
},Spec:
await browser.url('/app-with-sw/');
await browser.waitUntil(() =>
browser.execute(() => !!navigator.serviceWorker.controller),
);
await browser.injectSWChaos({
network: { failures: [{ urlPattern: '/api/data', statusCode: 503, probability: 1 }] },
seed: 1,
});
// ...interact...
const log = await browser.getSWChaosLog();
await browser.removeSWChaos();User's SW must importScripts('/chaos-maker-sw.js') (classic) or import { installChaosSW } from '@chaos-maker/core/sw' (module).
License
MIT
