Extending CodeceptJS
CodeceptJS has four extension points. Pick the lightest one that does the job:
| Use | To |
|---|---|
bootstrap / teardown | run setup or teardown code once, around the whole suite |
| Event listeners | react to test, suite, or step events without packaging anything |
| Plugins | bundle reusable behavior — listeners, recorder hooks, config — into a module |
| Custom helpers | add new I.* actions backed by a browser or an HTTP library |
Listeners and plugins use CodeceptJS internals — the event dispatcher, the recorder promise chain, the container, output. See Architecture for what those are and how a test runs.
Event Listeners
Section titled “Event Listeners”Attach a listener to event.dispatcher to run code at any point in the test lifecycle. A listener can live in a plugin or in your bootstrap script.
import { event } from 'codeceptjs'
event.dispatcher.on(event.test.before, test => { console.log(`starting ${test.title}`)})Sync events run inline. For async work, queue it on the recorder so it runs in order with the test’s steps:
import { event, recorder } from 'codeceptjs'
event.dispatcher.on(event.test.before, () => { recorder.add('seed fixture data', async () => { await api.post('/users', { name: 'john', email: 'john@example.com' }) })})A listener often needs to know where in the run it is — which test is active, or whether this is a dry run. Read that from store instead of tracking it yourself:
import { event, store } from 'codeceptjs'
event.dispatcher.on(event.step.before, () => { if (store.dryRun) return // skip side effects on a dry run})See Architecture › Events for the full event list and the test and step object fields, and the Store reference for every state field.
Plugins
Section titled “Plugins”A plugin packages listeners, recorder hooks, container changes, and config into one module. CodeceptJS ships built-in plugins — their source doubles as example code.
A plugin is a module that exports a function. CodeceptJS calls it once at startup with the plugin’s config:
import { event } from 'codeceptjs'
const defaultConfig = { someOption: true,}
export default function (config) { config = { ...defaultConfig, ...config }
event.dispatcher.on(event.test.before, test => { // use config, register listeners, hook into the recorder })}Enabling a plugin
Section titled “Enabling a plugin”Add it to the plugins section of the config and point require at the module:
plugins: { myPlugin: { require: './path/to/plugin', // relative to the config file enabled: true, }}require— path to the plugin file, relative to the config file.enabled— settrueto load it.- any other key is passed straight to the plugin function as config.
A disabled or unlisted plugin can be turned on for a single run from the command line:
npx codeceptjs run --plugin myPluginnpx codeceptjs run --plugin myPlugin,allureExample: run code for a tagged group of tests
Section titled “Example: run code for a tagged group of tests”Tag the tests you want to target, then check the tag on event.test.before:
import { event, recorder } from 'codeceptjs'
export default function () { event.dispatcher.on(event.test.before, test => { if (!test.tags.includes('@populate')) return
recorder.add('populate database', async () => { // seed data for this test }) })}Example: run async setup before all tests
Section titled “Example: run async setup before all tests”event.all.before can fire before the recorder chain is running, so start it first:
import { event, recorder } from 'codeceptjs'
export default function () { event.dispatcher.on(event.all.before, () => { recorder.startUnlessRunning() recorder.add('warm up cache', async () => { // your async setup }) })}Wrapping bootstrap logic in a plugin like this lets you share it across projects and combine several setup scripts.
Custom Helpers
Section titled “Custom Helpers”To add new I.* actions — a higher-level step, a wrapper around a browser SDK, an assertion against your backend — write a helper class. Helpers can also be published as npm packages. See Custom Helpers.
Bootstrap & Teardown
Section titled “Bootstrap & Teardown”For setup and teardown that needs no packaging — start a server, create a database — use the bootstrap and teardown config hooks. In parallel runs, bootstrapAll / teardownAll run once in the parent process. See Bootstrap & Teardown.
See also: Architecture · Plugins reference · Custom Helpers · Bootstrap & Teardown