codeceptjs
Version:
Modern Era Acceptance Testing Framework for NodeJS
184 lines (166 loc) • 4.77 kB
JavaScript
const fsPath = require('path');
const readFileSync = require('fs').readFileSync;
const container = require('./container');
const Config = require('./config');
const event = require('../lib/event');
const glob = require('glob');
const runHook = require('./hooks');
const existsSync = require('fs').existsSync;
const resolve = require('path').resolve;
/**
* CodeceptJS runner
*/
class Codecept {
/**
* Create CodeceptJS runner.
* Config and options should be passed
*
* @param {*} config
* @param {*} opts
*/
constructor(config, opts) {
this.config = Config.create(config);
this.opts = opts;
this.testFiles = new Array(0);
this.requireModules(config.require);
}
/**
* Require modules before codeceptjs running
*
* @param {string[]} requiringModules
*/
requireModules(requiringModules) {
if (requiringModules) {
requiringModules.forEach((requiredModule) => {
const isLocalFile = existsSync(requiredModule) || existsSync(`${requiredModule}.js`);
if (isLocalFile) {
requiredModule = resolve(requiredModule);
}
require(requiredModule);
});
}
}
/**
* Initialize CodeceptJS at specific directory.
* If async initialization is required, pass callback as second parameter.
*
* @param {string} dir
*/
init(dir) {
this.initGlobals(dir);
// initializing listeners
container.create(this.config, this.opts);
this.runHooks();
}
/**
* Creates global variables
*
* @param {string} dir
*/
initGlobals(dir) {
global.codecept_dir = dir;
global.output_dir = fsPath.resolve(dir, this.config.output);
if (!this.config.noGlobals) {
global.actor = global.codecept_actor = require('./actor');
global.Helper = global.codecept_helper = require('./helper');
global.pause = require('./pause');
global.within = require('./within');
global.session = require('./session');
global.DataTable = require('./data/table');
global.locate = locator => require('./locator').build(locator);
global.inject = container.support;
global.secret = require('./secret').secret;
global.codeceptjs = require('./index'); // load all objects
// BDD
const stepDefinitions = require('./interfaces/bdd');
global.Given = stepDefinitions.Given;
global.When = stepDefinitions.When;
global.Then = stepDefinitions.Then;
}
}
/**
* Executes hooks.
*/
runHooks() {
// default hooks
runHook(require('./listener/steps'));
runHook(require('./listener/config'));
runHook(require('./listener/helpers'));
runHook(require('./listener/exit'));
runHook(require('./listener/trace'));
// custom hooks
this.config.hooks.forEach(hook => runHook(hook));
}
/**
* Executes bootstrap.
* If bootstrap is async, second parameter is required.
*
* @param {Function} [done]
*/
runBootstrap(done) {
runHook(this.config.bootstrap, done, 'bootstrap');
}
/**
* Executes teardown.
* If teardown is async a parameter is provided.
*
* @param {*} done
*/
teardown(done = undefined) {
runHook(this.config.teardown, done, 'teardown');
}
/**
* Loads tests by pattern or by config.tests
*
* @param {string} [pattern]
*/
loadTests(pattern) {
const options = {
cwd: global.codecept_dir,
};
let patterns = [pattern];
if (!pattern) {
patterns = [];
if (this.config.tests && !this.opts.features) patterns.push(this.config.tests);
if (this.config.gherkin.features && !this.opts.tests) patterns.push(this.config.gherkin.features);
}
for (pattern of patterns) {
glob.sync(pattern, options).forEach((file) => {
if (!fsPath.isAbsolute(file)) {
file = fsPath.join(global.codecept_dir, file);
}
this.testFiles.push(fsPath.resolve(file));
});
}
}
/**
* Run a specific test or all loaded tests.
*
* @param {string} [test]
*/
run(test) {
const mocha = container.mocha();
mocha.files = this.testFiles;
if (test) {
if (!fsPath.isAbsolute(test)) {
test = fsPath.join(global.codecept_dir, test);
}
mocha.files = mocha.files.filter(t => fsPath.basename(t, '.js') === test || t === test);
}
const done = () => {
event.emit(event.all.result, this);
event.emit(event.all.after, this);
};
try {
event.emit(event.all.before, this);
mocha.run(() => this.teardown(done));
} catch (e) {
this.teardown(done);
throw new Error(e);
}
}
static version() {
return JSON.parse(readFileSync(`${__dirname}/../package.json`, 'utf8')).version;
}
}
module.exports = Codecept;