var q = require('q'); var webdriver = require('selenium-webdriver'); var RunnerReporter = function(emitter) { this.emitter = emitter; this.testResult = [], this.failedCount = 0; }; RunnerReporter.prototype.jasmineStarted = function() { // Need to initiate startTime here, in case reportSpecStarting is not // called (e.g. when fit is used) this.startTime = new Date(); }; RunnerReporter.prototype.specStarted = function() { this.startTime = new Date(); }; RunnerReporter.prototype.specDone = function(result) { var specInfo = { name: result.description, category: result.fullName.slice(0, -result.description.length).trim() }; if (result.status == 'passed') { this.emitter.emit('testPass', specInfo); } else if (result.status == 'failed') { this.emitter.emit('testFail', specInfo); this.failedCount++; } var entry = { description: result.fullName, assertions: [], duration: new Date().getTime() - this.startTime.getTime() }; if (result.failedExpectations.length === 0) { entry.assertions.push({ passed: true }); } result.failedExpectations.forEach(function(item) { entry.assertions.push({ passed: item.passed, errorMsg: item.passed ? undefined : item.message, stackTrace: item.passed ? undefined : item.stack }); }); this.testResult.push(entry); }; /** * Execute the Runner's test cases through Jasmine. * * @param {Runner} runner The current Protractor Runner. * @param {Array} specs Array of Directory Path Strings. * @return {q.Promise} Promise resolved with the test results */ exports.run = function(runner, specs) { var JasmineRunner = require('jasmine'); var jrunner = new JasmineRunner(); /* global jasmine */ require('jasminewd2').init(webdriver.promise.controlFlow(), webdriver); var jasmineNodeOpts = runner.getConfig().jasmineNodeOpts; // On timeout, the flow should be reset. This will prevent webdriver tasks // from overflowing into the next test and causing it to fail or timeout // as well. This is done in the reporter instead of an afterEach block // to ensure that it runs after any afterEach() blocks with webdriver tasks // get to complete first. var reporter = new RunnerReporter(runner); jasmine.getEnv().addReporter(reporter); // Add hooks for afterEach require('./setupAfterEach').setup(runner, specs); // Filter specs to run based on jasmineNodeOpts.grep and jasmineNodeOpts.invert. jasmine.getEnv().specFilter = function(spec) { var grepMatch = !jasmineNodeOpts || !jasmineNodeOpts.grep || spec.getFullName().match(new RegExp(jasmineNodeOpts.grep)) != null; var invertGrep = !!(jasmineNodeOpts && jasmineNodeOpts.invertGrep); if (grepMatch == invertGrep) { spec.disable(); } return true; }; // Run specs in semi-random order if (jasmineNodeOpts.random) { jasmine.getEnv().randomizeTests(true); // Sets the randomization seed if randomization is turned on if (jasmineNodeOpts.seed) { jasmine.getEnv().seed(jasmineNodeOpts.seed); } } return runner.runTestPreparer().then(function() { return q.promise(function(resolve, reject) { if (jasmineNodeOpts && jasmineNodeOpts.defaultTimeoutInterval) { jasmine.DEFAULT_TIMEOUT_INTERVAL = jasmineNodeOpts.defaultTimeoutInterval; } var originalOnComplete = runner.getConfig().onComplete; jrunner.onComplete(function(passed) { try { var completed = q(); if (originalOnComplete) { completed = q(originalOnComplete(passed)); } completed.then(function() { resolve({ failedCount: reporter.failedCount, specResults: reporter.testResult }); }); } catch (err) { reject(err); } }); jrunner.configureDefaultReporter(jasmineNodeOpts); jrunner.projectBaseDir = ''; jrunner.specDir = ''; jrunner.addSpecFiles(specs); jrunner.execute(); }); }); };