Skip to content

Extending CodeceptJS

CodeceptJS has four extension points. Pick the lightest one that does the job:

UseTo
bootstrap / teardownrun setup or teardown code once, around the whole suite
Event listenersreact to test, suite, or step events without packaging anything
Pluginsbundle reusable behavior — listeners, recorder hooks, config — into a module
Custom helpersadd 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.

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.

A plugin packages listeners, recorder hooks, container changes, and config into one module. CodeceptJS ships built-in pluginstheir 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
})
}

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 — set true to 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 myPlugin
npx codeceptjs run --plugin myPlugin,allure

Example: 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
})
})
}

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.

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.

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