UNPKG

codeceptjs

Version:

Modern Era Acceptance Testing Framework for NodeJS

141 lines (117 loc) 4.5 kB
const tty = require('tty'); if (!tty.getWindowSize) { // this is really old method, long removed from Node, but Mocha // reporters fall back on it if they cannot use `process.stdout.getWindowSize` // we need to polyfill it. tty.getWindowSize = () => [40, 80]; } const { parentPort, workerData } = require('worker_threads'); const fs = require('fs'); const path = require('path'); const event = require('../../event'); const output = require('../../output'); const container = require('../../container'); const { getConfig, getTestRoot } = require('../utils'); let stdout = ''; const stderr = ''; // Requiring of Codecept need to be after tty.getWindowSize is available. const Codecept = require('../../codecept'); const { options, tests, testRoot, workerIndex, } = workerData; // hide worker output if (!options.debug && !options.verbose) process.stdout.write = (string, encoding, fd) => { stdout += string; return true; }; const config = getConfig(options.config || testRoot); // Load test and run const codecept = new Codecept(config, options); codecept.init(testRoot); codecept.loadTests(); const mocha = container.mocha(); filterTests(); if (mocha.suite.total()) { codecept.runBootstrap((err) => { if (err) throw new Error(`Error while running bootstrap file :${err}`); initializeListeners(); disablePause(); codecept.run(); }); } function filterTests() { const files = codecept.testFiles; mocha.files = files; mocha.loadFiles(); for (const suite of mocha.suite.suites) { suite.tests = suite.tests.filter(test => tests.indexOf(test.id) >= 0); } } function initializeListeners() { function simplifyTest(test, err = null) { if (test.start && !test.duration) { const end = new Date(); test.duration = end - test.start; } if (test.err) { err = { stack: test.err.stack, uncaught: test.err.uncaught, message: test.err.message, actual: test.err.actual, expected: test.err.expected, }; } const parent = {}; if (test.parent) { parent.title = test.parent.title; } return { workerIndex, title: test.title, status: test.status, duration: test.duration || 0, err, parent, }; } collectStats(); // suite event.dispatcher.on(event.suite.before, suite => sendToParentThread({ event: event.suite.before, workerIndex, data: simplifyTest(suite) })); event.dispatcher.on(event.suite.after, suite => sendToParentThread({ event: event.suite.after, workerIndex, data: simplifyTest(suite) })); // calculate duration event.dispatcher.on(event.test.started, test => test.start = new Date()); // tests event.dispatcher.on(event.test.before, test => sendToParentThread({ event: event.test.before, workerIndex, data: simplifyTest(test) })); event.dispatcher.on(event.test.after, test => sendToParentThread({ event: event.test.after, workerIndex, data: simplifyTest(test) })); event.dispatcher.on(event.test.finished, test => sendToParentThread({ event: event.test.finished, workerIndex, data: simplifyTest(test) })); event.dispatcher.on(event.test.failed, test => sendToParentThread({ event: event.test.failed, workerIndex, data: simplifyTest(test) })); event.dispatcher.on(event.test.passed, test => sendToParentThread({ event: event.test.passed, workerIndex, data: simplifyTest(test) })); event.dispatcher.on(event.test.started, test => sendToParentThread({ event: event.test.started, workerIndex, data: simplifyTest(test) })); event.dispatcher.on(event.hook.failed, (test, err) => sendToParentThread({ event: event.hook.failed, workerIndex, data: simplifyTest(test, err) })); event.dispatcher.on(event.hook.passed, (test, err) => sendToParentThread({ event: event.hook.passed, workerIndex, data: simplifyTest(test, err) })); // all event.dispatcher.once(event.all.result, () => parentPort.close()); } function disablePause() { global.pause = () => {}; } function collectStats() { const stats = { passes: 0, failures: 0, tests: 0, }; event.dispatcher.on(event.test.passed, () => { stats.passes++; }); event.dispatcher.on(event.test.failed, () => { stats.failures++; }); event.dispatcher.on(event.test.finished, () => { stats.tests++; }); event.dispatcher.once(event.all.after, () => { sendToParentThread({ event: event.all.after, data: stats }); }); } function sendToParentThread(data) { parentPort.postMessage(data); }