Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Commit

Permalink
chore(launcher): reorganize launcher
Browse files Browse the repository at this point in the history
  • Loading branch information
hankduan committed Nov 3, 2014
1 parent 86ead2c commit 2bdf968
Show file tree
Hide file tree
Showing 9 changed files with 402 additions and 347 deletions.
122 changes: 122 additions & 0 deletions lib/RunnerFork.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
var child = require('child_process');
var q = require('q');
var TaskLogger = require('./TaskLogger.js');
var EventEmitter = require('events').EventEmitter;
var util = require('util');


/**
* A fork of a runner for running a specified task. The RunnerFork will
* start a new process that calls on '/runFromLauncher.js'.
*
* @constructor
* @param {object} task Task to run.
*/
var RunnerFork = function(configFile, additionalConfig, task, runInFork) {
this.configFile = configFile;
this.additionalConfig = additionalConfig;
this.task = task;
this.runInFork = runInFork;
};
util.inherits(RunnerFork, EventEmitter);

/**
* Sends the run command.
*/
RunnerFork.prototype.run = function() {
var self = this;

var runResults = {
taskId: this.task.taskId,
specs: this.task.specs,
capabilities: this.task.capabilities,
// The following are populated while running the test:
failedCount: 0,
exitCode: -1,
specResults: []
}

if (this.runInFork) {
var deferred = q.defer();

var childProcess = child.fork(
__dirname + '/runFromLauncher.js',
process.argv.slice(2), {
cwd: process.cwd(),
silent: true
}
);
var taskLogger = new TaskLogger(this.task, childProcess.pid);

// stdout pipe
childProcess.stdout.on('data', function(data) {
taskLogger.log(data);
});

// stderr pipe
childProcess.stderr.on('data', function(data) {
taskLogger.log(data);
});

childProcess.on('message', function(m) {
switch (m.event) {
case 'testPass':
process.stdout.write('.');
break;
case 'testFail':
process.stdout.write('F');
break;
case 'testsDone':
runResults.failedCount = m.results.failedCount;
runResults.specResults = m.results.specResults;
break;
}
})
.on('error', function(err) {
taskLogger.flush();
deferred.reject(err);
})
.on('exit', function(code) {
taskLogger.flush();
runResults.exitCode = code;
deferred.resolve(runResults);
});

childProcess.send({
command: 'run',
configFile: this.configFile,
additionalConfig: this.additionalConfig,
capabilities: this.task.capabilities,
specs: this.task.specs
});

return deferred.promise;
} else {
var ConfigParser = require('./configParser');
var configParser = new ConfigParser();
if (this.configFile) {
configParser.addFileConfig(this.configFile);
}
if (this.additionalConfig) {
configParser.addConfig(this.additionalConfig);
}
var config = configParser.getConfig();
config.capabilities = this.task.capabilities;
config.specs = this.task.specs;

var Runner = require('./runner');
var runner = new Runner(config);

runner.on('testsDone', function(results) {
runResults.failedCount = results.failedCount;
runResults.specResults = results.specResults;
})

return runner.run().then(function(exitCode) {
runResults.exitCode = exitCode;
return runResults;
});
}
};

module.exports = RunnerFork;
88 changes: 88 additions & 0 deletions lib/TaskLogger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
var EOL = require('os').EOL;

/**
* Log output such that metadata are appended.
* Calling log(data) will not flush to console until you call flush()
*
* @constructor
* @param {object} task Task that is being reported.
* @param {number} pid PID of process running the task.
*/
var TaskLogger = function(task, pid) {
this.task = task;
this.pid = pid;
this.buffer = '';
this.insertTag = true;

this.logHeader_();
};

/**
* Report the header for the current task including information such as
* PID, browser name/version, task Id, specs being run.
*
* @private
*/
TaskLogger.prototype.logHeader_ = function() {
var output = 'PID: ' + this.pid + EOL;
if (this.task.specs.length === 1) {
output += 'Specs: '+ this.task.specs.toString() + EOL + EOL;
}
this.log(output);
};


/**
* Flushes the buffer to stdout.
*/
TaskLogger.prototype.flush = function() {
if (this.buffer) {
// Flush buffer if nonempty
process.stdout.write(EOL + '------------------------------------' + EOL);
process.stdout.write(this.buffer);
process.stdout.write(EOL);
this.buffer = '';
}
};

/**
* Log the data in the argument. The data will be saved to a buffer
* until flush() is called.
*
* @param {string} data
*/
TaskLogger.prototype.log = function(data) {
var tag = '[';
var capabilities = this.task.capabilities;
tag += (capabilities.browserName) ?
capabilities.browserName : '';
tag += (capabilities.version) ?
(' ' + capabilities.version) : '';
tag += (capabilities.platform) ?
(' ' + capabilities.platform) : '';
tag += (' #' + this.task.taskId);
tag += '] ';

data = data.toString();
for ( var i = 0; i < data.length; i++ ) {
if (this.insertTag) {
this.insertTag = false;
// This ensures that the '\x1B[0m' appears before the tag, so that
// data remains correct when color is not processed.
// See https://github.com/angular/protractor/pull/1216
if (data[i] === '\x1B' && data.substring(i, i+4) === '\x1B[0m' ) {
this.buffer += ('\x1B[0m' + tag);
i += 3;
continue;
}

this.buffer += tag;
}
if (data[i] === '\n') {
this.insertTag = true;
}
this.buffer += data[i];
}
};

module.exports = TaskLogger;
1 change: 1 addition & 0 deletions lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -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').
alias('browser', 'capabilities.browserName').
alias('name', 'capabilities.name').
alias('platform', 'capabilities.platform').
Expand Down
25 changes: 23 additions & 2 deletions lib/frameworks/jasmine.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,38 @@ exports.run = function(runner, specs) {
require('jasminewd');
/* global jasmine */

testResult = [];

var RunnerReporter = function(emitter) {
this.emitter = emitter;
};

RunnerReporter.prototype.reportRunnerStarting = function() {};
RunnerReporter.prototype.reportRunnerResults = function() {};
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');
}

var entry = {
description: spec.results().description,
result: [],
duration: new Date().getTime() - this.startTime.getTime()
};
spec.results().getItems().forEach(function(item) {
entry.result.push({
passed: item.passed(),
errorMsg: item.passed() ? undefined : item.message,
stacktrace: item.passed() ? undefined : item.trace.stack
});
});
testResult.push(entry);
};
RunnerReporter.prototype.log = function() {};

Expand All @@ -47,7 +65,10 @@ exports.run = function(runner, specs) {
if (originalOnComplete) {
originalOnComplete(jasmineRunner, log);
}
resolve(jasmineRunner.results());
resolve({
failedCount: jasmineRunner.results().failedCount,
specResults: testResult
});
} catch(err) {
reject(err);
}
Expand Down
50 changes: 36 additions & 14 deletions lib/frameworks/mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,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() {
Expand All @@ -56,21 +48,51 @@ exports.run = function(runner, specs) {
mocha.addFile(file);
});

mocha.run(function(failures) {
var testResult = [];

var mochaRunner = mocha.run(function(failures) {
try {
if (runner.getConfig().onComplete) {
runner.getConfig().onComplete();
}
var resolvedObj = {
failedCount: failures
failedCount: failures,

};

deferred.resolve(resolvedObj);
}catch(err){
deferred.resolve({
failedCount: failures,
specResults: testResult
});
} catch(err) {
deferred.reject(err);
}
});
}).catch(function(reason){

mochaRunner.on('pass', function(test) {
runner.emit('testPass');
testResult.push({
description: test.title,
result: [{
passed: true
}],
duration: test.duration
});
});

mochaRunner.on('fail', function(test) {
runner.emit('testFail');
testResult.push({
description: test.title,
result: [{
passed: false,
errorMsg: test.err.message,
stacktrace: test.err.stack
}],
duration: test.duration
});
});
}).catch(function(reason) {
deferred.reject(reason);
});

Expand Down
Loading

0 comments on commit 2bdf968

Please sign in to comment.