Internal API
Concepts
Section titled “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 moduleconst { recorder, event, output } = require('codeceptjs');// or using global objectconst { recorder, event, output } = codeceptjs;These internal objects are available:
codecept: test runner classconfig: current codecept configevent: event listenerrecorder: global promise chainoutput: internal printercontainer: dependency injection container for tests, includes current helpers and support objectshelper: basic helper classactor: basic actor (I) class
API reference is available on GitHub. Also please check the source code of corresponding modules.
Container
Section titled “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 helpersconst helpers = container.helpers();
// get helper by nameconst { WebDriver } = container.helpers();
// get support objectsconst supportObjects = container.support();
// get support object by nameconst { UserPage } = container.support();
// get all registered pluginsconst 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
Section titled “Event Listeners”CodeceptJS provides a module with an event dispatcher and set of predefined events.
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 using the event system.
Recorder
Section titled “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 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: 'john@john.com' } }), (err, httpResponse, body) => { if (err) return errFn(err); doneFn(); } }); } });}Config
Section titled “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
Section titled “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
Section titled “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 skipped-
messagestring with reason for skip
-
descriptionstring with test body and others
Step Object
Section titled “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
Section titled “Custom Runner”You can run CodeceptJS tests from your script.
const { codecept: Codecept } = require('codeceptjs');
// define main configconst 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.