# Concepts
In this guide we will overview the internal API of CodeceptJS. This knowledge is required for customization, writing plugins, etc.
CodeceptJS provides an API which can be loaded via require('codeceptjs')
when CodeceptJS is installed locally. Otherwise, you can load codeceptjs API via global codeceptjs
object:
// via module
const { recorder, event, output } = require('codeceptjs');
// or using global object
const { recorder, event, output } = codeceptjs;
These internal objects are available:
codecept
(opens new window): test runner classconfig
(opens new window): current codecept configevent
(opens new window): event listenerrecorder
(opens new window): global promise chainoutput
(opens new window): internal printercontainer
(opens new window): dependency injection container for tests, includes current helpers and support objectshelper
(opens new window): basic helper classactor
(opens new window): basic actor (I) class
API reference (opens new window) is available on GitHub. Also please check the source code of corresponding modules.
# Container
CodeceptJS has a dependency injection container with helpers and support objects. They can be retrieved from the container:
const { container } = require('codeceptjs');
// get object with all helpers
const helpers = container.helpers();
// get helper by name
const { WebDriver } = container.helpers();
// get support objects
const supportObjects = container.support();
// get support object by name
const { UserPage } = container.support();
// get all registered plugins
const plugins = container.plugins();
New objects can also be added to container in runtime:
const { container } = require('codeceptjs');
container.append({
helpers: { // add helper
MyHelper: new MyHelper({ config1: 'val1' });
},
support: { // add page object
UserPage: require('./pages/user');
}
})
Use this trick to define custom objects inside
boostrap
script
The container also contains the current Mocha instance:
const mocha = container.mocha();
# Event Listeners
CodeceptJS provides a module with an event dispatcher and set of predefined events (opens new window).
It can be required from codeceptjs package if it is installed locally.
const { event } = require('codeceptjs');
module.exports = function() {
event.dispatcher.on(event.test.before, function (test) {
console.log('--- I am before test --');
});
}
Available events:
event.test.before(test)
- async whenBefore
hooks from helpers and from test is executedevent.test.after(test)
- async after each testevent.test.started(test)
- sync at the very beginning of a test.event.test.passed(test)
- sync when test passedevent.test.failed(test, error)
- sync when test failedevent.test.finished(test)
- sync when test finishedevent.suite.before(suite)
- async before a suiteevent.suite.after(suite)
- async after a suiteevent.step.before(step)
- async when the step is scheduled for executionevent.step.after(step)
- async after a stepevent.step.started(step)
- sync when step starts.event.step.passed(step)
- sync when step passed.event.step.failed(step, err)
- sync when step failed.event.step.finished(step)
- sync when step finishes.event.step.comment(step)
- sync fired for comments likeI.say
.event.all.before
- before running testsevent.all.after
- after running testsevent.all.result
- when results are printedevent.workers.before
- before spawning workers in parallel runevent.workers.after
- after workers finished in parallel runevent.workers.result
- test results after workers finished in parallel run
sync - means that event is fired in the moment of the action happening. async - means that event is fired when an action is scheduled. Use
recorder
to schedule your actions.
For further reference look for currently available listeners (opens new window) using the event system.
# Recorder
To inject asynchronous functions in a test or before/after a test you can subscribe to corresponding event and register a function inside a recorder object. Recorder (opens new window) represents a global promises chain.
Provide a function in the first parameter, a function must be async or must return a promise:
const { event, recorder } = require('codeceptjs');
module.exports = function() {
event.dispatcher.on(event.test.before, function (test) {
const request = require('request');
recorder.add('create fixture data via API', function() {
return new Promise((doneFn, errFn) => {
request({
baseUrl: 'http://api.site.com/',
method: 'POST',
url: '/users',
json: { name: 'john', email: '[email protected]' }
}), (err, httpResponse, body) => {
if (err) return errFn(err);
doneFn();
}
});
}
});
}
# Config
CodeceptJS config can be accessed from require('codeceptjs').config.get()
:
const { config } = require('codeceptjs');
// config object has access to all values of the current config file
if (config.get().myKey == 'value') {
// run something
}
# Output
Output module provides four verbosity levels. Depending on the mode you can have different information printed using corresponding functions.
default
: prints basic information usingoutput.print
steps
: toggled by--steps
option, prints step executiondebug
: toggled by--debug
option, prints steps, and debug information withoutput.debug
verbose
: toggled by--verbose
prints debug information and internal logs withoutput.log
It is recommended to avoid console.log
and use output.* methods for printing.
const output = require('codeceptjs').output;
output.print('This is basic information');
output.debug('This is debug information');
output.log('This is verbose logging information');
# Test Object
The test events are providing a test object with following properties:
title
title of the testbody
test function as a stringopts
additional test options like retries, and otherspending
true if test is scheduled for execution and false if a test has finishedtags
array of tags for this testartifacts
list of files attached to this test. Screenshots, videos and other files can be saved here and shared accross different reportersfile
path to a file with a teststeps
array of executed steps (available only intest.passed
,test.failed
,test.finished
event)skipInfo
additional test options when test skippedmessage
string with reason for skip
description
string with test body and others
# Step Object
Step events provide step objects with following fields:
name
name of a step, like 'see', 'click', and othersactor
current actor, in most cases it isI
helper
current helper instance used to execute this stephelperMethod
corresponding helper method, in most cases is the same asname
status
status of a step (passed or failed)prefix
if a step is executed insidewithin
block contain within text, like: 'Within .js-signup-form'.args
passed arguments
Whenever you execute tests with --verbose
option you will see registered events and promises executed by a recorder.
# Custom Runner
You can run CodeceptJS tests from your script.
const { codecept: Codecept } = require('codeceptjs');
// define main config
const config = {
helpers: {
WebDriver: {
browser: 'chrome',
url: 'http://localhost'
}
}
};
const opts = { steps: true };
// run CodeceptJS inside async function
(async () => {
const codecept = new Codecept(config, options);
codecept.init(__dirname);
try {
await codecept.bootstrap();
codecept.loadTests('**_test.js');
// run tests
await codecept.run(test);
} catch (err) {
printError(err);
process.exitCode = 1;
} finally {
await codecept.teardown();
}
})();
Also, you can run tests inside workers in a custom scripts. Please refer to the parallel execution guide for more details.