diff --git a/lib/cli.js b/lib/cli.js index b9fe16361..b27d9f122 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -50,6 +50,7 @@ var optimist = require('optimist'). describe('stackTrace', 'Print stack trace on error'). describe('params', 'Param object to be passed to the tests'). describe('framework', 'Test framework to use: jasmine, cucumber or mocha'). + describe('testResultOutput', 'Path to save JSON test result (Jasmine only)'). alias('browser', 'capabilities.browserName'). alias('name', 'capabilities.name'). alias('platform', 'capabilities.platform'). diff --git a/lib/frameworks/jasmine.js b/lib/frameworks/jasmine.js index 4cae42b82..22a1128f0 100644 --- a/lib/frameworks/jasmine.js +++ b/lib/frameworks/jasmine.js @@ -1,4 +1,5 @@ var q = require('q'); +var fs = require('fs'); /** * Execute the Runner's test cases through Jasmine. @@ -15,18 +16,49 @@ exports.run = function(runner, specs) { var RunnerReporter = function(emitter) { this.emitter = emitter; + this.jsonOutput = []; }; RunnerReporter.prototype.reportRunnerStarting = function() {}; - RunnerReporter.prototype.reportRunnerResults = function() {}; + RunnerReporter.prototype.reportRunnerResults = function() { + // If store results to json file + var testResultFile = runner.getConfig().testResultOutput; + if (testResultFile) { + if (fs.existsSync(testResultFile)) { + var prevDataRaw = fs.readFileSync(testResultFile); + var prevDataJson = JSON.parse(prevDataRaw); + this.jsonOutput = this.jsonOutput.concat(prevDataJson); + } + + var json = JSON.stringify(this.jsonOutput, null, ' '); + fs.writeFileSync(testResultFile, json); + } + }; RunnerReporter.prototype.reportSuiteResults = function() {}; - RunnerReporter.prototype.reportSpecStarting = function() {}; + RunnerReporter.prototype.reportSpecStarting = function() { + this.startTime = new Date(); + }; RunnerReporter.prototype.reportSpecResults = function(spec) { if (spec.results().passed()) { this.emitter.emit('testPass'); } else { this.emitter.emit('testFail'); } + + if (runner.getConfig().testResultOutput) { + var entry = { + result: [], + duration: new Date().getTime() - this.startTime.getTime() + }; + spec.results().getItems().forEach(function(item) { + entry.result.push({ + passed: item.passed(), + errorMsg: item.message, + stacktrace: item.trace.stack + }); + }); + this.jsonOutput.push(entry); + } }; RunnerReporter.prototype.log = function() {}; diff --git a/lib/frameworks/mocha.js b/lib/frameworks/mocha.js index b7c5c443c..1ffd68fc9 100644 --- a/lib/frameworks/mocha.js +++ b/lib/frameworks/mocha.js @@ -1,4 +1,5 @@ var q = require('q'); +var fs = require('fs'); /** * Execute the Runner's test cases through Mocha. @@ -35,19 +36,11 @@ exports.run = function(runner, specs) { global.it.only = global.iit = originalOnly; global.it.skip = global.xit = mochaAdapters.xit; - }catch(err){ + } catch(err){ deferred.reject(err); } }); - mocha.suite.on('pass', function() { - runner.emit('testPass'); - }); - - mocha.suite.on('fail', function() { - runner.emit('testFail'); - }); - mocha.loadFiles(); runner.runTestPreparer().then(function() { @@ -56,7 +49,7 @@ exports.run = function(runner, specs) { mocha.addFile(file); }); - mocha.run(function(failures) { + var mochaRunner = mocha.run(function(failures) { try { if (runner.getConfig().onComplete) { runner.getConfig().onComplete(); @@ -66,10 +59,54 @@ exports.run = function(runner, specs) { }; deferred.resolve(resolvedObj); - }catch(err){ + } catch(err){ deferred.reject(err); } }); + + var jsonOutput = []; + + mochaRunner.on('end', function() { + // If store results to json file + var testResultFile = runner.getConfig().testResultOutput; + if (testResultFile) { + if (fs.existsSync(testResultFile)) { + var prevDataRaw = fs.readFileSync(testResultFile); + var prevDataJson = JSON.parse(prevDataRaw); + jsonOutput = jsonOutput.concat(prevDataJson); + } + + var json = JSON.stringify(jsonOutput, null, ' '); + fs.writeFileSync(testResultFile, json); + } + }); + + mochaRunner.on('pass', function(test) { + runner.emit('testPass'); + if (runner.getConfig().testResultOutput) { + jsonOutput.push({ + result: [{ + passed: true + }], + duration: test.duration + }); + } + }); + + mochaRunner.on('fail', function(test) { + runner.emit('testFail'); + if (runner.getConfig().testResultOutput) { + jsonOutput.push({ + result: [{ + passed: false, + errorMsg: test.err.message, + stacktrace: test.err.stack + }], + duration: test.duration + }); + } + }); + }).catch(function(reason){ deferred.reject(reason); });