UNPKG

codeceptjs

Version:

Supercharged End 2 End Testing Framework for NodeJS

132 lines (115 loc) 3.06 kB
import event from '../event.js' import pause from '../pause.js' import recorder from '../recorder.js' import output from '../output.js' import { parsePluginArgs, resolveTrigger, matchStepFile, matchUrl, getBrowserHelper, } from '../utils/pluginParser.js' /** * Pauses test execution interactively. Replaces the legacy `pauseOnFail` * plugin. The default `on=fail` matches the old `pauseOnFail` behavior. * * #### Configuration * * ```js * plugins: { * pause: { * enabled: false, * on: 'fail', * } * } * ``` * * #### `on=` modes * * * **fail** — pause when a step fails (default) * * **test** — pause after each test * * **step** — pause before the first step (interactive walk-through) * * **file** — pause when execution reaches `path=...[;line=...]` * * **url** — pause when the browser URL matches `pattern=...` * * CLI examples: * * ``` * npx codeceptjs run -p pause * npx codeceptjs run -p pause:on=step * npx codeceptjs run -p pause:on=file:path=tests/login_test.js;line=43 * npx codeceptjs run -p pause:on=url:pattern=/users/* * ``` */ export default function (config = {}) { const cliArgs = parsePluginArgs(config._args) const trigger = resolveTrigger(cliArgs, config, { on: 'fail' }, { name: 'pause' }) if (!trigger) return switch (trigger.on) { case 'fail': return initFailMode() case 'test': return initTestMode() case 'step': return initStepMode() case 'file': return initFileMode(trigger.path, trigger.line) case 'url': return initUrlMode(trigger.pattern) } } function initFailMode() { let failed = false event.dispatcher.on(event.test.started, () => { failed = false }) event.dispatcher.on(event.step.failed, () => { failed = true }) event.dispatcher.on(event.test.after, () => { if (failed) pause() }) } function initTestMode() { event.dispatcher.on(event.test.after, () => pause()) } function initStepMode() { let activated = false event.dispatcher.on(event.test.before, () => { if (activated) return activated = true recorder.add('pause:step', () => pause()) }) } function initFileMode(targetPath, targetLine) { let paused = false event.dispatcher.on(event.step.before, step => { if (paused) return if (!matchStepFile(step, targetPath, targetLine)) return paused = true recorder.add('pause:file', () => pause()) }) } function initUrlMode(pattern) { const helper = getBrowserHelper() if (!helper) { output.error('pause:on=url requires a browser helper (Playwright, WebDriver, Puppeteer, Appium)') return } let paused = false event.dispatcher.on(event.step.after, () => { if (paused) return recorder.add('pause:url check', async () => { if (paused) return try { const currentUrl = await helper.grabCurrentUrl() if (matchUrl(currentUrl, pattern)) { paused = true return pause() } } catch (err) { // page may not be loaded yet } }) }) }