# 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
boostrapscript
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 whenBeforehooks 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
recorderto 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.printsteps: toggled by--stepsoption, prints step executiondebug: toggled by--debugoption, prints steps, and debug information withoutput.debugverbose: toggled by--verboseprints 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:
titletitle of the testbodytest function as a stringoptsadditional test options like retries, and otherspendingtrue if test is scheduled for execution and false if a test has finishedtagsarray of tags for this testartifactslist of files attached to this test. Screenshots, videos and other files can be saved here and shared accross different reportersfilepath to a file with a teststepsarray of executed steps (available only intest.passed,test.failed,test.finishedevent)skipInfoadditional test options when test skippedmessagestring with reason for skip
descriptionstring with test body and others
# Step Object
Step events provide step objects with following fields:
namename of a step, like 'see', 'click', and othersactorcurrent actor, in most cases it isIhelpercurrent helper instance used to execute this stephelperMethodcorresponding helper method, in most cases is the same asnamestatusstatus of a step (passed or failed)prefixif a step is executed insidewithinblock contain within text, like: 'Within .js-signup-form'.argspassed 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.