Skip to content

Commit 0bef6b7

Browse files
committed
Merge branch 'master' into proxy_support
2 parents 4d84076 + 8d59e9b commit 0bef6b7

File tree

5 files changed

+107
-62
lines changed

5 files changed

+107
-62
lines changed

bin/cli.js

Lines changed: 80 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ if (process.argv[2] == '--verbose')
55
else
66
global.logLevel = "info";
77

8+
if (process.argv[2] == 'init') {
9+
require('./init.js');
10+
return;
11+
}
12+
813
var Log = require('../lib/logger'),
914
logger = new Log(global.logLevel),
1015
BrowserStack = require('browserstack'),
@@ -26,30 +31,47 @@ var Log = require('../lib/logger'),
2631
tunnelingAgent,
2732
tunnel;
2833

29-
function cleanUp(signal) {
30-
try {
31-
server.close();
32-
} catch (e) {
33-
logger.debug("Server already closed");
34-
}
35-
36-
logger.info("Exiting");
37-
38-
for (var key in workers) {
39-
var worker = workers[key];
40-
if (workers.hasOwnProperty(key)) {
41-
client.terminateWorker(worker.id, function () {
42-
if (!workers[key]) {
43-
return;
44-
}
45-
34+
function terminateAllWorkers(callback) {
35+
var cleanWorker = function(id, key) {
36+
client.terminateWorker(id, function() {
37+
var worker = workers[key];
38+
if(worker) {
4639
logger.debug('[%s] Terminated', worker.string);
4740
clearTimeout(worker.activityTimeout);
41+
clearTimeout(worker.testActivityTimeout);
4842
delete workers[key];
4943
delete workerKeys[worker.id];
50-
});
44+
}
45+
if (utils.objectSize(workers) === 0) {
46+
callback();
47+
}
48+
});
49+
};
50+
51+
if (utils.objectSize(workers) === 0) {
52+
callback();
53+
} else {
54+
for (var key in workers){
55+
var worker = workers[key];
56+
if (worker.id) {
57+
cleanWorker(worker.id, key);
58+
} else {
59+
delete workers[key];
60+
if (utils.objectSize(workers) === 0) {
61+
callback();
62+
}
63+
}
5164
}
5265
}
66+
};
67+
68+
function cleanUpAndExit(signal, status) {
69+
try {
70+
server.close();
71+
} catch (e) {
72+
logger.debug("Server already closed");
73+
}
74+
5375
if (statusPoller) statusPoller.stop();
5476

5577
try {
@@ -62,9 +84,24 @@ function cleanUp(signal) {
6284
} catch (e) {
6385
logger.debug("Non existent pid file.");
6486
}
65-
if (signal) {
66-
process.kill(process.pid, 'SIGTERM');
87+
88+
if (signal == 'SIGTERM') {
89+
logger.info("Exiting");
90+
process.exit(status);
91+
} else {
92+
terminateAllWorkers(function() {
93+
logger.info("Exiting");
94+
process.exit(1);
95+
});
96+
}
97+
}
98+
99+
function getTestBrowserInfo(browserString, path) {
100+
var info = browserString;
101+
if(config.multipleTest) {
102+
info += ", " + path;
67103
}
104+
return info;
68105
}
69106

70107
function launchServer() {
@@ -74,9 +111,10 @@ function launchServer() {
74111
server.listen(parseInt(serverPort, 10));
75112
}
76113

77-
function launchBrowser(browser, url) {
114+
function launchBrowser(browser, path) {
115+
var url = 'http://localhost:' + serverPort.toString() + '/' + path;
78116
var browserString = utils.browserString(browser);
79-
logger.debug("[%s] Launching", browserString);
117+
logger.debug("[%s] Launching", getTestBrowserInfo(browserString, path));
80118

81119
var key = utils.uuid();
82120

@@ -121,6 +159,7 @@ function launchBrowser(browser, url) {
121159

122160
worker.config = browser;
123161
worker.string = browserString;
162+
worker.test_path = path;
124163
workers[key] = worker;
125164
workerKeys[worker.id] = {key: key, marked: false};
126165
});
@@ -130,13 +169,13 @@ function launchBrowser(browser, url) {
130169
function launchBrowsers(config, browser) {
131170
setTimeout(function () {
132171
if(Object.prototype.toString.call(config.test_path) === '[object Array]'){
172+
config.multipleTest = config.test_path.length > 1? true : false;
133173
config.test_path.forEach(function(path){
134-
var url = 'http://localhost:' + serverPort.toString() + '/' + path;
135-
launchBrowser(browser,url);
174+
launchBrowser(browser, path);
136175
});
137176
} else {
138-
var url = 'http://localhost:' + serverPort.toString() + '/' + config.test_path;
139-
launchBrowser(browser,url);
177+
config.multipleTest = false;
178+
launchBrowser(browser, config.test_path);
140179
}
141180
}, 100);
142181
}
@@ -160,7 +199,7 @@ var statusPoller = {
160199

161200
if (_worker.status === 'running') {
162201
//clearInterval(statusPoller);
163-
logger.debug('[%s] Launched', worker.string);
202+
logger.debug('[%s] Launched', getTestBrowserInfo(worker.string, worker.test_path));
164203
worker.launched = true;
165204
workerData.marked = true;
166205

@@ -180,12 +219,12 @@ var statusPoller = {
180219
config.status = 1;
181220
}
182221

183-
process.exit(config.status);
222+
process.kill(process.pid, 'SIGTERM');
184223
}
185224
}
186225
}, activityTimeout * 1000);
187226

188-
setTimeout(function () {
227+
worker.testActivityTimeout = setTimeout(function () {
189228
if (worker.acknowledged) {
190229
var subject = "Tests timed out on: " + worker.string;
191230
var content = "Worker details:\n" + JSON.stringify(worker.config, null, 4);
@@ -201,7 +240,7 @@ var statusPoller = {
201240
config.status = 1;
202241
}
203242

204-
process.exit(config.status);
243+
process.kill(process.pid, 'SIGTERM');
205244
}
206245
}
207246
}, (activityTimeout * 1000));
@@ -232,7 +271,8 @@ function runTests() {
232271
launchServer();
233272
tunnel = new Tunnel(config.key, serverPort, config.tunnelIdentifier, function () {
234273
statusPoller.start();
235-
logger.info("Launching " + browsers.length + " workers");
274+
var total_workers = config.browsers.length * (Object.prototype.toString.call(config.test_path) === '[object Array]' ? config.test_path.length : 1);
275+
logger.info("Launching " + total_workers + " workers");
236276
browsers.forEach(function(browser) {
237277
if (browser.browser_version === "latest") {
238278
logger.debug("[%s] Finding version.", utils.browserString(browser));
@@ -254,21 +294,16 @@ function runTests() {
254294
}
255295

256296
try {
257-
if (process.argv[2] == 'init') {
258-
require('./init.js');
259-
} else {
260-
var client = BrowserStack.createClient({
261-
username: config.username,
262-
password: config.key
263-
});
264-
runTests();
265-
var pid_file = process.cwd() + '/browserstack-run.pid';
266-
fs.writeFileSync(pid_file, process.pid, 'utf-8')
267-
process.on('exit', function() {cleanUp(false)});
268-
process.on('SIGINT', function() {cleanUp(true)});
269-
}
297+
var client = BrowserStack.createClient({
298+
username: config.username,
299+
password: config.key
300+
});
301+
runTests();
302+
var pid_file = process.cwd() + '/browserstack-run.pid';
303+
fs.writeFileSync(pid_file, process.pid, 'utf-8')
304+
process.on('SIGINT', function() { cleanUpAndExit('SIGINT', 1) });
305+
process.on('SIGTERM', function() { cleanUpAndExit('SIGTERM', config.status) });
270306
} catch (e) {
271307
console.log(e);
272308
console.log('Invalid command.');
273309
}
274-

lib/local.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ var Tunnel = function Tunnel(key, port, uniqueIdentifier, callback, err) {
3030
logger.debug(stderr);
3131
logger.debug(error);
3232
if (stdout.indexOf('Error') >= 0 || error) {
33-
logger.info("[%s] Tunnel launching failed", new Date());
34-
logger.info(stdout);
35-
process.exit(1);
33+
logger.debug("[%s] Tunnel launching failed", new Date());
34+
logger.debug(stdout);
35+
process.kill(process.pid, 'SIGINT');
3636
}
3737
});
3838

@@ -98,7 +98,7 @@ var Tunnel = function Tunnel(key, port, uniqueIdentifier, callback, err) {
9898
}, 100);
9999
}).on('error', function(e) {
100100
logger.info("Got error while downloading binary: " + e.message);
101-
process.exit(1);
101+
process.kill(process.pid, 'SIGINT');
102102
});
103103
});
104104
});

lib/server.js

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ var mimeTypes = {
2020
"css": "text/css"
2121
};
2222

23+
function getTestBrowserInfo(worker) {
24+
var info = worker.string;
25+
if(config.multipleTest) {
26+
info += ", " + worker.test_path
27+
}
28+
return info;
29+
}
30+
2331

2432
exports.Server = function Server(bsClient, workers) {
2533

@@ -28,8 +36,9 @@ exports.Server = function Server(bsClient, workers) {
2836
var query = url_parts.query;
2937

3038
if (query._worker_key && workers[query._worker_key]) {
31-
workers[query._worker_key].acknowledged = true;
32-
logger.debug("[%s] Acknowledged", query._browser_string);
39+
worker = workers[query._worker_key] || {};
40+
worker.acknowledged = true;
41+
logger.debug("[%s] Acknowledged", getTestBrowserInfo(worker));
3342
}
3443

3544
fs.exists(filename, function(exists) {
@@ -136,7 +145,7 @@ exports.Server = function Server(bsClient, workers) {
136145
handlers = {
137146
"_progress": function progressHandler(uri, body, request, response) {
138147
var uuid = request.headers['x-worker-uuid'];
139-
var worker = workers[uuid];
148+
var worker = workers[uuid] || {};
140149
query = "";
141150
try {
142151
query = parseBody(body);
@@ -147,7 +156,7 @@ exports.Server = function Server(bsClient, workers) {
147156

148157
if (query.tracebacks) {
149158
query.tracebacks.forEach(function(traceback) {
150-
logger.info(chalk.red("[%s] Error:"), worker.string, formatTraceback(traceback));
159+
logger.info(chalk.red("[%s] Error:"), getTestBrowserInfo(worker), formatTraceback(traceback));
151160
});
152161
}
153162
response.end();
@@ -159,36 +168,37 @@ exports.Server = function Server(bsClient, workers) {
159168
query = parseBody(body);
160169
} catch (e) {}
161170
var uuid = request.headers['x-worker-uuid'];
162-
var worker = workers[uuid];
171+
var worker = workers[uuid] || {};
163172

164173
if (query === null) {
165174
logger.info("[%s] Null response from remote Browser", request.headers['x-browser-string']);
166175
} else {
167176
if (query.tracebacks && query.tracebacks.length > 0) {
168-
logger.info("Tracebacks:");
177+
logger.info(chalk["red"]("[%s] Tracebacks:"), getTestBrowserInfo(worker));
169178
query.tracebacks.forEach(function(traceback) {
170179
logger.info(traceback);
171180
});
172181
}
173182
var color = query.failed ? "red" : "green";
174-
logger.info(chalk[color]("[%s] Completed in %d milliseconds. %d of %d passed, %d failed."), request.headers['x-browser-string'], query.runtime, query.passed, query.total, query.failed);
183+
logger.info(chalk[color]("[%s] Completed in %d milliseconds. %d of %d passed, %d failed."), getTestBrowserInfo(worker), query.runtime, query.passed, query.total, query.failed);
175184
config.status += query.failed;
176185
}
177186

178187
if (worker) {
179188
bsClient.takeScreenshot(worker.id, function(error, screenshot) {
180189
if (!error && screenshot.url) {
181-
logger.info('[%s] ' + chalk['yellow']('Screenshot') + ': %s', worker.string, screenshot.url);
190+
logger.info('[%s] ' + chalk['yellow']('Screenshot') + ': %s', getTestBrowserInfo(worker), screenshot.url);
182191
}
183192

184193
bsClient.terminateWorker(worker.id, function() {
185194
if (!workers[uuid]) {
186195
return;
187196
}
188197

189-
logger.debug('[%s] Terminated', worker.string);
198+
logger.debug('[%s] Terminated', getTestBrowserInfo(worker));
190199

191200
clearTimeout(workers[uuid].activityTimeout);
201+
clearTimeout(workers[uuid].testActivityTimeout);
192202
delete workers[uuid];
193203

194204
if (utils.objectSize(workers) === 0) {
@@ -199,7 +209,7 @@ exports.Server = function Server(bsClient, workers) {
199209
config.status = 1;
200210
}
201211

202-
process.exit(config.status);
212+
process.kill(process.pid, 'SIGTERM');
203213
}
204214
});
205215
});

lib/utils.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ var uuid = function uuidGenerator() {
2626
};
2727

2828
var browserString = function browserString(config) {
29-
return config.os + ' ' + config.os_version + ', ' + titleCase(config.browser || config.device) + ' ' + (config.browser_version || config.device);
29+
return config.os + ' ' + config.os_version + ', ' + (config.browser == 'ie' ? 'IE' : titleCase(config.browser || config.device)) + ' ' + (config.browser_version || config.device);
3030
};
3131

3232
var objectSize = function objectSize(obj) {
@@ -49,7 +49,7 @@ var alertBrowserStack = function alertBrowserStack(subject, content, params, fn)
4949
if (typeof params === 'function') {
5050
} else {
5151
fn = function() {
52-
process.exit(1);
52+
process.kill(process.pid, 'SIGINT');
5353
};
5454
}
5555
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "browserstack-runner",
33
"description": "A command line interface to run browser tests over BrowserStack",
4-
"version": "0.1.10",
4+
"version": "0.1.11",
55
"homepage": "https://github.com/browserstack/browserstack-runner",
66
"repository": {
77
"type": "git",

0 commit comments

Comments
 (0)