| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- var create = require('lodash.create');
- var utils = require('../utils');
- var filter = utils.filter;
- var indexOf = utils.indexOf;
- var some = utils.some;
- var NightwatchClient = require('../nightwatch/client');
- var MochaRunner = require('../runner');
- module.exports = Runner;
- function Runner(suite, delay) {
- MochaRunner.call(this, suite, delay);
- }
- Runner.prototype = create(MochaRunner.prototype, {
- constructor : Runner
- });
- Runner.prototype.run = function(nightwatch, test_settings, fn) {
- var self = this;
- var rootSuite = this.suite;
- var client = new NightwatchClient(nightwatch, this, test_settings);
- if (this.hasOnly) {
- filterOnly(rootSuite);
- }
- fn = fn || function() {};
- function uncaught(err) {
- self.uncaught(err);
- }
- function setClient(test) {
- test.setNightwatchClient(client.get());
- }
- function start() {
- self.emit('start');
- self.runSuite(rootSuite, function() {
- self.emit('end');
- });
- self.on('test', setClient);
- self.on('hook', setClient);
- }
- // callback
- this.on('end', function() {
- process.removeListener('uncaughtException', uncaught);
- fn(self.failures);
- });
- // uncaught exception
- process.on('uncaughtException', uncaught);
- if (this._delay) {
- // for reporters, I guess.
- // might be nice to debounce some dots while we wait.
- this.emit('waiting', rootSuite);
- rootSuite.once('run', start);
- } else {
- start();
- }
- return this;
- };
- Runner.prototype.failOnError = function(err) {
- var runnable = this.currentRunnable;
- if (!runnable) {
- return;
- }
- runnable.clearTimeout();
- // Ignore errors if complete
- if (runnable.state) {
- return;
- }
- this.fail(runnable, err);
- // recover from test
- if (runnable.type === 'test') {
- this.emit('test end', runnable);
- this.hookUp('afterEach', this.next);
- return;
- }
- // bail on hooks
- this.emit('end');
- };
- /**
- * Filter suites based on `isOnly` logic.
- *
- * @param {Array} suite
- * @returns {Boolean}
- * @api private
- */
- function filterOnly (suite) {
- if (suite._onlyTests.length) {
- // If the suite contains `only` tests, run those and ignore any nested suites.
- suite.tests = suite._onlyTests;
- suite.suites = [];
- } else {
- // Otherwise, do not run any of the tests in this suite.
- suite.tests = [];
- utils.forEach(suite._onlySuites, function (onlySuite) {
- // If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite.
- // Otherwise, all of the tests on this `only` suite should be run, so don't filter it.
- if (hasOnly(onlySuite)) {
- filterOnly(onlySuite);
- }
- });
- // Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants.
- suite.suites = filter(suite.suites, function (childSuite) {
- return indexOf(suite._onlySuites, childSuite) !== -1 || filterOnly(childSuite);
- });
- }
- // Keep the suite only if there is something to run
- return suite.tests.length || suite.suites.length;
- }
- /**
- * Determines whether a suite has an `only` test or suite as a descendant.
- *
- * @param {Array} suite
- * @returns {Boolean}
- * @api private
- */
- function hasOnly (suite) {
- return suite._onlyTests.length || suite._onlySuites.length || some(suite.suites, hasOnly);
- }
|