Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'master' into issue/#572-browserstackSessionClose
  • Loading branch information
samhatoum committed Mar 29, 2017
2 parents 6f22600 + a4478cf commit da0453f
Show file tree
Hide file tree
Showing 12 changed files with 344 additions and 39 deletions.
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -85,7 +85,7 @@
"chromedriver": "^2.27.2",
"colors": "1.1.2",
"commander": "^2.9.0",
"cucumber": "xolvio/cucumber-js#v1.3.0-chimp.2",
"cucumber": "xolvio/cucumber-js#v1.3.0-chimp.3",
"deep-extend": "^0.4.1",
"exit": "^0.1.2",
"fibers": "^1.0.14",
Expand Down
29 changes: 24 additions & 5 deletions src/__tests__/process-helper-spec.js
Expand Up @@ -138,11 +138,19 @@ describe('process-helper', function () {
waitForMessage: 'we have lift off'
};

var eventToBeRemoved = false;
var eventToBeRemovedStdOut = false;
var eventToBeRemovedStdErr = false;
var child = {
stdout: {
on: jest.genMockFn().mockImplementation(function (event, eventTrigger) {
eventToBeRemoved = eventTrigger;
eventToBeRemovedStdOut = eventTrigger;
eventTrigger('Huston, we have lift off!');
}),
removeListener: jest.genMockFn()
},
stderr: {
on: jest.genMockFn().mockImplementation(function (event, eventTrigger) {
eventToBeRemovedStdErr = eventTrigger;
eventTrigger('Huston, we have lift off!');
}),
removeListener: jest.genMockFn()
Expand All @@ -153,10 +161,15 @@ describe('process-helper', function () {

expect(child.stdout.removeListener.mock.calls.length).toBe(1);
expect(child.stdout.removeListener.mock.calls[0][0]).toBe('data');
expect(child.stdout.removeListener.mock.calls[0][1]).toBe(eventToBeRemoved);
expect(child.stdout.removeListener.mock.calls[0][1]).toBe(eventToBeRemovedStdOut);

expect(callback.mock.calls.length).toBe(1);
expect(child.stderr.removeListener.mock.calls.length).toBe(1);
expect(child.stderr.removeListener.mock.calls[0][0]).toBe('data');
expect(child.stderr.removeListener.mock.calls[0][1]).toBe(eventToBeRemovedStdErr);

expect(callback.mock.calls.length).toBe(2);
expect(callback.mock.calls[0][0]).toBeFalsy();
expect(callback.mock.calls[1][0]).toBeFalsy();

});

Expand All @@ -178,13 +191,19 @@ describe('process-helper', function () {
on: jest.genMockFn().mockImplementation(function (event, eventTrigger) {
eventTrigger('Huston, we have a problem - engine failure!');
})
},
stderr: {
on: jest.genMockFn().mockImplementation(function (event, eventTrigger) {
eventTrigger('Huston, we have a problem - engine failure!');
})
}
};

processHelper.waitForMessage(options, child, callback);

expect(callback.mock.calls.length).toBe(1);
expect(callback.mock.calls.length).toBe(2);
expect(callback.mock.calls[0][0]).toBe('Huston, we have a problem - engine failure!');
expect(callback.mock.calls[1][0]).toBe('Huston, we have a problem - engine failure!');

});

Expand Down
2 changes: 1 addition & 1 deletion src/bin/default.js
Expand Up @@ -66,7 +66,7 @@ module.exports = {
seleniumStandaloneOptions: {
// check for more recent versions of selenium here:
// http://selenium-release.storage.googleapis.com/index.html
version: '2.53.1',
version: '3.0.1',
baseURL: 'https://selenium-release.storage.googleapis.com',
drivers: {
chrome: {
Expand Down
3 changes: 2 additions & 1 deletion src/lib/babel-register.js
@@ -1,4 +1,5 @@
require('babel-register')({
'plugins': ['transform-runtime'],
'presets': ['es2015', 'stage-2']
});

require('babel-polyfill');
57 changes: 44 additions & 13 deletions src/lib/chimp.js
Expand Up @@ -12,7 +12,8 @@ var async = require('async'),
Hapi = require('hapi'),
AutoupdateWatcher = require('./ddp-watcher'),
colors = require('colors'),
booleanHelper = require('./boolean-helper');
booleanHelper = require('./boolean-helper'),
Versions = require('../lib/versions');

colors.enabled = true;
var DEFAULT_COLOR = 'yellow';
Expand Down Expand Up @@ -59,6 +60,7 @@ function Chimp(options) {
this.exec = require('child_process').exec;
this.fs = fs;
this.testRunnerRunOrder = [];
this.watcher = undefined;

// store all cli parameters in env hash
// Note: Environment variables are always strings.
Expand All @@ -72,7 +74,7 @@ function Chimp(options) {
}
}

this._handleMeteorInterrupt();
this._handleChimpInterrupt();
}

function handleDdpOption(options) {
Expand Down Expand Up @@ -105,7 +107,21 @@ Chimp.prototype.init = function (callback) {
callback(error);
return;
}
self.selectMode(callback);

if (this.options.versions || this.options.debug) {
const versions = new Versions(this.options);
if (this.options.debug) {
versions.show(() => {
self.selectMode(callback)
});
}
else {
versions.show();
}
}
else {
self.selectMode(callback);
}
};

Chimp.prototype.informUser = function () {
Expand Down Expand Up @@ -222,7 +238,7 @@ Chimp.prototype.watch = function () {

watchDirectories.push(self.options.path);

var watcher = chokidar.watch(watchDirectories, {
this.watcher = chokidar.watch(watchDirectories, {
ignored: /[\/\\](\.|node_modules)/,
persistent: true,
usePolling: this.options.watchWithPolling
Expand All @@ -242,16 +258,21 @@ Chimp.prototype.watch = function () {
}

// wait for initial file scan to complete
watcher.once('ready', function () {
this.watcher.once('ready', function () {

var watched = [];
if (self.options.watchTags) {
if (_.isArray(self.options.watchTags)) {
_.each(self.options.watchTags, (watchTag) => {
watched.push(watchTag.split(','));
});
}
else if (_.isString(self.options.watchTags)) {
watched.push(self.options.watchTags.split(','));
}
log.info(`[chimp] Watching features with tagged with ${watched.join()}`.white);

// start watching
watcher.on('all', function (event, path) {
self.watcher.on('all', function (event, path) {

// removing feature files should not rerun
if (event === 'unlink' && path.match(/\.feature$/)) {
Expand Down Expand Up @@ -438,6 +459,9 @@ Chimp.prototype.run = function (callback) {
function (error, result) {
if (error) {
log.debug('[chimp] run complete with errors', error);
if (booleanHelper.isFalsey(self.options.watch)) {
self.interrupt(() => {});
}
} else {
log.debug('[chimp] run complete');
}
Expand Down Expand Up @@ -476,7 +500,9 @@ Chimp.prototype.interrupt = function (callback) {
if (!self.processes || self.processes.length === 0) {
self.isInterrupting = false;
log.debug('[chimp] no processes to interrupt');
callback();
if (callback) {
callback();
}
return;
}

Expand All @@ -497,7 +523,9 @@ Chimp.prototype.interrupt = function (callback) {
if (error) {
log.error('[chimp] with errors', error);
}
callback.apply(this, arguments);
if (callback) {
callback.apply(this, arguments);
}
});

};
Expand Down Expand Up @@ -672,13 +700,16 @@ Chimp.prototype._createProcesses = function () {
*
* @api private
*/
Chimp.prototype._handleMeteorInterrupt = function () {
if (process.env.MIRROR_PORT) {
Chimp.prototype._handleChimpInterrupt = function () {
var self = this;
process.on('SIGINT', function () {
log.debug('[chimp] SIGINT detected, killing process');
process.kill();
process.stdin.end();
self.interrupt();
if (booleanHelper.isTruthy(self.options.watch)) {
self.watcher.close();
}
});
}
};

module.exports = Chimp;
22 changes: 15 additions & 7 deletions src/lib/chromedriver.js
@@ -1,5 +1,6 @@
var chromedriver = require('chromedriver'),
processHelper = require('./process-helper.js'),
fs = require('fs'),
log = require('./log');

/**
Expand Down Expand Up @@ -38,13 +39,20 @@ Chromedriver.prototype.start = function (callback) {
return;
}

this.child = processHelper.start({
bin: chromedriver.path,
prefix: 'chromedriver',
args: ['--port=' + port, '--url-base=wd/hub'],
waitForMessage: /Starting ChromeDriver/,
errorMessage: /Error/
}, callback);
const chromedriverPath = chromedriver.path;

if (fs.existsSync(chromedriverPath)) {
this.child = processHelper.start({
bin: chromedriverPath,
prefix: 'chromedriver',
args: ['--port=' + port, '--url-base=wd/hub'],
waitForMessage: /Starting ChromeDriver/,
errorMessage: /Error/
}, callback);
}
else {
callback('[chimp][chromedriver] Chromedriver executable not found.');
}

};

Expand Down
5 changes: 3 additions & 2 deletions src/lib/cucumberjs/cucumber-wrapper.js
Expand Up @@ -83,8 +83,9 @@ function createIpcFormatter() {
ipcFormatter.finish = function sendResultToChimp(callback) {
finish.call(this, (error, result) => {
const results = this.getLogs();
process.send(results);
callback(error, result);
process.send(results, () => {
callback(error, result);
});
});
};
return ipcFormatter;
Expand Down
5 changes: 2 additions & 3 deletions src/lib/cucumberjs/cucumber.js
Expand Up @@ -79,8 +79,7 @@ class Cucumber {
if (!this.cucumberChild.stopping) {
log.debug('[chimp][cucumber] Cucumber not in a stopping state');

const result = jsonResults;
if (this.options.jsonOutput && JSON.parse(jsonResults).length) {
if (this.options.jsonOutput && jsonResults && JSON.parse(jsonResults).length) {
const dir = path.dirname(this.options.jsonOutput);
log.debug('[chimp][cucumber] Ensuring directory exists', dir);
fs.mkdirsSync(dir);
Expand All @@ -89,7 +88,7 @@ class Cucumber {
log.debug('[chimp][cucumber] Finished writing results');
}

callback(code !== 0 ? 'Cucumber steps failed' : null, result);
callback(code !== 0 ? 'Cucumber steps failed' : null, jsonResults);
}
});
}
Expand Down
3 changes: 2 additions & 1 deletion src/lib/ddp-watcher.js
Expand Up @@ -78,11 +78,12 @@ AutoupdateWatcher.prototype.watch = function (trigger) {
host: this._url.hostname,
port: this._url.port,
ssl: this._url.protocol === 'https:',
path: this._url.pathname !== '/' ? this._url.pathname + '/websocket' : undefined,
autoReconnect: true,
autoReconnectTimer: 500,
maintainCollections: true,
ddpVersion: '1',
useSockJs: true
useSockJs: this._url.pathname === '/'
});

/*
Expand Down
4 changes: 2 additions & 2 deletions src/lib/ddp.js
Expand Up @@ -43,13 +43,13 @@ DDP.prototype._getOptions = function () {
host: this.url.hostname,
port: this.url.port,
ssl: this.url.protocol === 'https:',
path: this.url.pathname !== '/' ? this.url.pathname + '/websocket' : undefined,
// TODO extract all options
autoReconnect: true,
autoReconnectTimer: 500,
maintainCollections: true,
ddpVersion: '1',
useSockJs: true
//path: "websocket"
useSockJs: this.url.pathname === '/'
};
};

Expand Down
21 changes: 18 additions & 3 deletions src/lib/process-helper.js
Expand Up @@ -36,9 +36,24 @@ module.exports = {
},

waitForMessage: function (options, child, callback) {
child.stdout.on('data', function onData(data) {
child.stderr.on('data', onDataStdErr);
child.stdout.on('data', onDataStdOut);

function onDataStdErr(data) {
onData(data, () => {
child.stderr.removeListener('data', onDataStdErr);
});
}

function onDataStdOut(data) {
onData(data, () => {
child.stdout.removeListener('data', onDataStdOut);
});
}

function onData(data, removeListener) {
if (data.toString().match(options.waitForMessage)) {
child.stdout.removeListener('data', onData);
removeListener();
log.debug('[chimp][' + options.prefix + ']', 'started successfully');
return callback();
}
Expand All @@ -47,7 +62,7 @@ module.exports = {
log.error(data.toString());
callback(data.toString());
}
});
}
},

kill: function (options, callback) {
Expand Down

0 comments on commit da0453f

Please sign in to comment.