Skip to content

Commit 7986297

Browse files
committedFeb 25, 2016
updated code to follow ruby python php style
1 parent 0d4eed5 commit 7986297

15 files changed

+467
-1663
lines changed
 

‎.eslintrc.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"no-trailing-spaces": 2,
2121
"no-irregular-whitespace": 2,
2222
"camelcase": 2,
23-
"brace-style": [2, "1tbs", { "allowSingleLine": true }]
23+
"brace-style": [2, "1tbs", { "allowSingleLine": true }],
24+
"no-constant-condition": 0
2425
},
2526
"env": {
2627
"es6": true,

‎README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ npm install browserstack
1010

1111
### Constructor
1212

13-
* `new BrowserStack::Local`: creates an instance of Local
13+
* `new browserstack.Local()`: creates an instance of Local
1414

1515
### Methods
1616

@@ -36,7 +36,7 @@ The first and only argument to any callback function will be an error object.
3636
* `localIdentifier`: If doing simultaneous multiple local testing connections, set this uniquely for different processes
3737
* `hosts`: List of hosts and ports where Local must be enabled for eg. localhost,3000,1,localhost,3001,0
3838
* `logfile`: Path to file where Local logs be saved to
39-
* `binaryPath`: Optional path to Local binary
39+
* `binarypath`: Optional path to Local binary
4040

4141

4242
## Tests

‎index.js

+1-28
Original file line numberDiff line numberDiff line change
@@ -1,28 +1 @@
1-
var browserStackTunnel = require('./lib/browserStackTunnel');
2-
3-
function Local() {
4-
var tunnel = null;
5-
6-
this.start = function(options, callback) {
7-
tunnel = new browserStackTunnel(options);
8-
if(callback == null) {
9-
callback = function() {};
10-
}
11-
tunnel.start(callback);
12-
};
13-
14-
this.isRunning = function() {
15-
return (tunnel.state === 'started');
16-
};
17-
18-
this.logs = function() {
19-
};
20-
21-
this.stop = function(callback) {
22-
if(tunnel) {
23-
tunnel.stop(callback);
24-
}
25-
};
26-
}
27-
28-
module.exports.Local = Local;
1+
module.exports.Local = require('./lib/Local');

‎lib/Local.js

+209
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
var childProcess = require('child_process'),
2+
fs = require('fs'),
3+
path = require('path'),
4+
running = require('is-running'),
5+
LocalBinary = require('./LocalBinary'),
6+
LocalError = require('./LocalError');
7+
8+
9+
function Local(){
10+
this.pid = undefined;
11+
this.key = process.env.BROWSERSTACK_ACCESS_KEY;
12+
this.logfile = path.join(process.cwd(), 'local.log');
13+
this.exitCallback;
14+
15+
this.errorRegex = /\*\*\* Error\: [^\n]+/i;
16+
this.doneRegex = /Press Ctrl-C to exit/i;
17+
18+
this.start = function(options, callback){
19+
var that = this;
20+
this.addArgs(options);
21+
22+
if(typeof options['onlyCommand'] !== 'undefined')
23+
return callback();
24+
25+
this.getBinaryPath(function(binaryPath){
26+
that.binaryPath = binaryPath;
27+
childProcess.exec('echo "" > ' + that.logfile);
28+
29+
that.tunnel = childProcess.spawn(binaryPath, that.getBinaryArgs());
30+
that.tunnel.on('exit', function(){
31+
that.tunnel = undefined;
32+
if(that.exitCallback) that.exitCallback();
33+
});
34+
35+
that.stdout = fs.openSync(that.logfile, 'r');
36+
var chunkSize = 512,
37+
buffer = new Buffer(81920),
38+
bytesRead = 0,
39+
error = undefined;
40+
41+
while(true){
42+
var bytes = fs.readSync(that.stdout, buffer, bytesRead, chunkSize, bytesRead);
43+
if(bytes == 0) continue;
44+
45+
var buffRead = buffer.slice(bytesRead, bytesRead+bytes);
46+
bytesRead += bytes;
47+
48+
var data = buffRead.toString();
49+
//console.log(data);
50+
51+
if(data.match(that.errorRegex)){
52+
fs.closeSync(that.stdout);
53+
error = data.match(that.errorRegex)[0].trim();
54+
break;
55+
}
56+
57+
if(data.match(that.doneRegex)){
58+
fs.closeSync(that.stdout);
59+
break;
60+
}
61+
}
62+
63+
if(error) throw new LocalError(data);
64+
callback();
65+
});
66+
};
67+
68+
this.isRunning = function(){
69+
return this.tunnel && running(this.tunnel.pid);
70+
};
71+
72+
this.stop = function (callback) {
73+
if (this.tunnel) {
74+
if(callback) this.exitCallback = callback;
75+
this.tunnel.kill();
76+
}
77+
else if(callback) callback();
78+
};
79+
80+
this.addArgs = function(options){
81+
for(var key in options){
82+
var value = options[key];
83+
84+
switch(key){
85+
case 'key':
86+
this.key = value;
87+
break;
88+
89+
case 'v':
90+
if(value)
91+
this.verboseFlag = '-vvv';
92+
break;
93+
94+
case 'force':
95+
if(value)
96+
this.forceFlag = '-force';
97+
break;
98+
99+
case 'only':
100+
if(value)
101+
this.onlyFlag = '-only';
102+
break;
103+
104+
case 'onlyAutomate':
105+
if(value)
106+
this.onlyAutomateFlag = '-onlyAutomate';
107+
break;
108+
109+
case 'forcelocal':
110+
if(value)
111+
this.forceLocalFlag = '-forcelocal';
112+
break;
113+
114+
case 'localIdentifier':
115+
if(value)
116+
this.localIdentifierFlag = '-localIdentifier ' + value;
117+
break;
118+
119+
case 'f':
120+
if(value){
121+
this.folderFlag = '-f';
122+
this.folderPath = value;
123+
}
124+
break;
125+
126+
case 'proxyHost':
127+
if(value)
128+
this.proxyHost = '-proxyHost ' + value;
129+
break;
130+
131+
case 'proxyPort':
132+
if(value)
133+
this.proxyPort = '-proxyPort ' + value;
134+
break;
135+
136+
case 'proxyUser':
137+
if(value)
138+
this.proxyUser = '-proxyUser ' + value;
139+
break;
140+
141+
case 'proxyPass':
142+
if(value)
143+
this.proxyPass = '-proxyPass ' + value;
144+
break;
145+
146+
case 'hosts':
147+
if(value)
148+
this.hosts = value;
149+
break;
150+
151+
case 'logfile':
152+
if(value)
153+
this.logfile = value;
154+
break;
155+
156+
case 'binarypath':
157+
if(value)
158+
this.binaryPath = value;
159+
break;
160+
161+
default:
162+
break;
163+
}
164+
}
165+
};
166+
167+
this.getBinaryPath = function(callback){
168+
if(typeof(this.binaryPath) == 'undefined'){
169+
this.binary = new LocalBinary();
170+
this.binary.binaryPath(callback);
171+
} else {
172+
callback(this.binaryPath);
173+
}
174+
};
175+
176+
this.getBinaryArgs = function(){
177+
var args = ['-logFile', this.logfile];
178+
if(this.folderFlag)
179+
args.push(this.folderFlag);
180+
args.push(this.key);
181+
if(this.folderPath)
182+
args.push(this.folderPath);
183+
if(this.forceLocalFlag)
184+
args.push(this.forceLocalFlag);
185+
if(this.localIdentifierFlag)
186+
args.push(this.localIdentifierFlag);
187+
if(this.onlyFlag)
188+
args.push(this.onlyFlag);
189+
if(this.onlyAutomateFlag)
190+
args.push(this.onlyAutomateFlag);
191+
if(this.proxyHost)
192+
args.push(this.proxyHost);
193+
if(this.proxyPort)
194+
args.push(this.proxyPort);
195+
if(this.proxyUser)
196+
args.push(this.proxyUser);
197+
if(this.proxyPass)
198+
args.push(this.proxyPass);
199+
if(this.forceFlag)
200+
args.push(this.forceFlag);
201+
if(this.verboseFlag)
202+
args.push(this.verboseFlag);
203+
if(this.hosts)
204+
args.push(this.hosts);
205+
return args;
206+
};
207+
}
208+
209+
module.exports = Local;

‎lib/LocalBinary.js

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
var https = require('https'),
2+
unzip = require('unzip'),
3+
fs = require('fs'),
4+
path = require('path'),
5+
os = require('os'),
6+
LocalError = require('./LocalError');
7+
8+
function LocalBinary(){
9+
this.hostOS = process.platform;
10+
this.is64bits = process.arch == 'x64';
11+
12+
if(this.hostOS.match(/darwin|mac os/i)){
13+
this.httpPath = 'https://www.browserstack.com/browserstack-local/BrowserStackLocal-darwin-x64.zip';
14+
} else if(this.hostOS.match(/mswin|msys|mingw|cygwin|bccwin|wince|emc/i)) {
15+
this.windows = true;
16+
this.httpPath = 'https://s3.amazonaws.com/browserStack/browserstack-local/BrowserStackLocal.exe';
17+
} else {
18+
if(this.is64bits)
19+
this.httpPath = 'https://s3.amazonaws.com/browserStack/browserstack-local/BrowserStackLocal-linux-x64';
20+
else
21+
this.httpPath = 'https://s3.amazonaws.com/browserStack/browserstack-local/BrowserStackLocal-linux-ia32';
22+
}
23+
24+
this.orderedPaths = [
25+
path.join(os.homedir(), '.browserstack'),
26+
process.cwd(),
27+
os.tmpdir()
28+
];
29+
30+
this.download = function(destParentDir, callback){
31+
if(!this.checkPath(destParentDir))
32+
fs.mkdirSync(path);
33+
34+
var binaryPath = destParentDir + './BrowserStackLocal';
35+
var extractStream = unzip.Extract({
36+
path: destParentDir
37+
});
38+
https.get(this.http_path, function (response) {
39+
extractStream.on('close', function () {
40+
fs.chmod(binaryPath, '0755', function() {
41+
callback(binaryPath);
42+
});
43+
});
44+
response.pipe(extractStream);
45+
});
46+
};
47+
48+
this.binaryPath = function(callback){
49+
var destParentDir = this.getAvailableDirs();
50+
var binaryPath = path.join(destParentDir, 'BrowserStackLocal');
51+
if(this.checkPath(binaryPath, fs.X_OK)){
52+
callback(binaryPath);
53+
} else {
54+
this.download(destParentDir, callback);
55+
}
56+
};
57+
58+
this.checkPath = function(path, mode){
59+
mode = mode || (fs.R_OK | fs.W_OK);
60+
try {
61+
fs.accessSync(path, mode);
62+
return true;
63+
} catch(e){
64+
return false;
65+
}
66+
};
67+
68+
this.getAvailableDirs = function(){
69+
for(var i=0; i < this.orderedPaths.length; i++){
70+
var path = this.orderedPaths[i];
71+
if(this.makePath(path))
72+
return path;
73+
}
74+
throw new LocalError('Error trying to download BrowserStack Local binary');
75+
};
76+
77+
this.makePath = function(path){
78+
try {
79+
if(!this.checkPath(path)){
80+
fs.mkdirSync(path);
81+
}
82+
return true;
83+
} catch(e){
84+
return false;
85+
}
86+
};
87+
}
88+
89+
module.exports = LocalBinary;

‎lib/LocalError.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = function LocalError(message, extra) {
2+
Error.captureStackTrace(this, this.constructor);
3+
this.name = this.constructor.name;
4+
this.message = message;
5+
this.extra = extra;
6+
};
7+
8+
require('util').inherits(module.exports, Error);

‎lib/ZipBinary.js

-89
This file was deleted.

‎lib/browserStackTunnel.js

-242
This file was deleted.

‎lib/helper.js

-70
This file was deleted.

‎node-example.js

+34-30
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var browserstack = require('browserstack');
1+
var browserstack = require('./index');
22

33
var local = new browserstack.Local();
44
var webdriver = require('selenium-webdriver');
@@ -8,8 +8,8 @@ var capabilities = {
88
build: 'build',
99
'browserName': 'chrome',
1010
'os': 'OS X',
11-
'browserstack.local': true,
12-
'browserstack.localIdentifier': identifier
11+
'browserstack.local': true
12+
//'browserstack.localIdentifier': identifier
1313
}
1414

1515
var options = {
@@ -20,42 +20,46 @@ var options = {
2020
// sslFlag: 0
2121
//}],
2222
//f: __dirname,
23-
binaryPath: '/var/BrowserStackLocal',
24-
logfile: '/var/log/local.log',
25-
localIdentifier: identifier,
26-
verbose: true,
23+
//binaryPath: '/var/BrowserStackLocal',
24+
//logfile: '/var/log/local.log',
25+
//localIdentifier: identifier,
26+
//verbose: true,
2727
//proxyUser: '',
2828
//proxyPass: '',
2929
//proxyPort: 80,
3030
//proxyHost: 'host',
31-
force: true,
32-
forcelocal: true,
33-
onlyAutomate: true
31+
//force: true,
32+
//forcelocal: true,
33+
//onlyAutomate: true
3434
};
3535

36-
local.start(options, function(error) {
37-
if(error) {
38-
console.log("Got Error From Local " + error);
39-
process.exit();
40-
}
41-
console.log('Is Running ' + local.isRunning());
42-
console.log('Started');
43-
44-
capabilities['browserstack.user'] = process.env.BROWSERSTACK_USERNAME;
45-
capabilities['browserstack.key'] = process.env.BROWSERSTACK_ACCESS_KEY;
46-
capabilities['browserstack.local'] = true;
47-
capabilities['browserstack.localIdentifier'] = identifier;
48-
49-
driver = new webdriver.Builder().usingServer('http://hub.browserstack.com/wd/hub').withCapabilities(capabilities).build();
50-
console.log('Is Running ' + local.isRunning());
51-
driver.get("http://localhost:3000").then(function() {
36+
// try {
37+
local.start(options, function() {
5238
console.log('Is Running ' + local.isRunning());
53-
driver.quit().then(function() {
39+
console.log('Started');
40+
41+
capabilities['browserstack.user'] = process.env.BROWSERSTACK_USERNAME;
42+
capabilities['browserstack.key'] = process.env.BROWSERSTACK_ACCESS_KEY;
43+
capabilities['browserstack.local'] = true;
44+
//capabilities['browserstack.localIdentifier'] = identifier;
45+
46+
driver = new webdriver.Builder().usingServer('http://hub.browserstack.com/wd/hub').withCapabilities(capabilities).build();
47+
console.log('Is Running ' + local.isRunning());
48+
driver.get("http://www.google.com").then(function() {
5449
console.log('Is Running ' + local.isRunning());
55-
local.stop(function() {
50+
driver.quit().then(function() {
5651
console.log('Is Running ' + local.isRunning());
57-
console.log('Stopped');
52+
local.stop(function() {
53+
console.log('Is Running ' + local.isRunning());
54+
console.log('Stopped');
55+
});
5856
});
5957
});
6058
});
61-
});
59+
// }
60+
// catch(error){
61+
// console.log("Got Error From Local " + error);
62+
// process.exit();
63+
// }
64+
65+

‎package.json

+2-6
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,12 @@
1515
"author": "BrowserStack",
1616
"license": "MIT",
1717
"dependencies": {
18-
"npmlog": "2.0.2",
19-
"os-homedir": "^1.0.1",
20-
"tail": "^0.4.0",
18+
"is-running": "^2.0.0",
2119
"unzip": "0.1.11"
2220
},
2321
"devDependencies": {
2422
"eslint": "1.10.3",
2523
"expect.js": "0.3.1",
26-
"mocha": "2.4.5",
27-
"mocks": "0.0.15",
28-
"sinon": "1.17.3"
24+
"mocha": "2.4.5"
2925
}
3026
}

‎test/ZipBinary.js

-153
This file was deleted.

‎test/browserStackTunnel.js

-878
This file was deleted.

‎test/lib/mocks.js

-164
This file was deleted.

‎test/local.js

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
var expect = require('expect.js'),
2+
mocks = require('mocks'),
3+
browserstack = require('../index');
4+
5+
describe('Local', function () {
6+
var bsLocal;
7+
beforeEach(function () {
8+
bsLocal = new browserstack.Local();
9+
});
10+
11+
it('should have pid when running', function (done) {
12+
this.timeout(15000);
13+
bsLocal.start({ key: process.env.BROWSERSTACK_ACCESS_KEY }, function(){
14+
expect(bsLocal.tunnel.pid).to.not.equal(0);
15+
done();
16+
});
17+
});
18+
19+
it('should return is running properly', function (done) {
20+
this.timeout(15000);
21+
expect(bsLocal.isRunning()).to.not.equal(true);
22+
bsLocal.start({ key: process.env.BROWSERSTACK_ACCESS_KEY }, function(){
23+
expect(bsLocal.isRunning()).to.equal(true);
24+
done();
25+
});
26+
});
27+
28+
it('should throw error on running multiple binary', function (done) {
29+
this.timeout(25000);
30+
bsLocal.start({ key: process.env.BROWSERSTACK_ACCESS_KEY }, function(){
31+
bsLocal_2 = new browserstack.Local();
32+
try{
33+
bsLocal_2.start({ key: process.env.BROWSERSTACK_ACCESS_KEY }, function(){});
34+
}
35+
catch(err){
36+
expect(err.toString().trim()).to.equal('LocalError: *** Error: Either another browserstack local client is running on your machine or some server is listening on port 45691');
37+
done();
38+
}
39+
});
40+
});
41+
42+
it('should enable verbose', function (done) {
43+
bsLocal.start({ key: process.env.BROWSERSTACK_ACCESS_KEY, onlyCommand: true, v: true }, function(){
44+
expect(bsLocal.getBinaryArgs().indexOf('-vvv')).to.not.equal(-1);
45+
done();
46+
});
47+
});
48+
49+
it('should set folder testing', function (done) {
50+
bsLocal.start({ key: process.env.BROWSERSTACK_ACCESS_KEY, onlyCommand: true, f: '/var/html' }, function(){
51+
expect(bsLocal.getBinaryArgs().indexOf('-f')).to.not.equal(-1);
52+
expect(bsLocal.getBinaryArgs().indexOf('/var/html')).to.not.equal(-1);
53+
done();
54+
});
55+
});
56+
57+
it('should enable force', function (done) {
58+
bsLocal.start({ key: process.env.BROWSERSTACK_ACCESS_KEY, onlyCommand: true, force: true }, function(){
59+
expect(bsLocal.getBinaryArgs().indexOf('-force')).to.not.equal(-1);
60+
done();
61+
});
62+
});
63+
64+
it('should enable only', function (done) {
65+
bsLocal.start({ key: process.env.BROWSERSTACK_ACCESS_KEY, onlyCommand: true, only: true }, function(){
66+
expect(bsLocal.getBinaryArgs().indexOf('-only')).to.not.equal(-1);
67+
done();
68+
});
69+
});
70+
71+
it('should enable onlyAutomate', function (done) {
72+
bsLocal.start({ key: process.env.BROWSERSTACK_ACCESS_KEY, onlyCommand: true, onlyAutomate: true }, function(){
73+
expect(bsLocal.getBinaryArgs().indexOf('-onlyAutomate')).to.not.equal(-1);
74+
done();
75+
});
76+
});
77+
78+
it('should enable forcelocal', function (done) {
79+
bsLocal.start({ key: process.env.BROWSERSTACK_ACCESS_KEY, onlyCommand: true, forcelocal: true }, function(){
80+
expect(bsLocal.getBinaryArgs().indexOf('-forcelocal')).to.not.equal(-1);
81+
done();
82+
});
83+
});
84+
85+
it('should set localIdentifier', function (done) {
86+
bsLocal.start({ key: process.env.BROWSERSTACK_ACCESS_KEY, onlyCommand: true, localIdentifier: 'abcdef' }, function(){
87+
expect(bsLocal.getBinaryArgs().indexOf('-localIdentifier abcdef')).to.not.equal(-1);
88+
done();
89+
});
90+
});
91+
92+
it('should set proxy', function (done) {
93+
bsLocal.start({
94+
key: process.env.BROWSERSTACK_ACCESS_KEY,
95+
onlyCommand: true,
96+
proxyHost: 'localhost',
97+
proxyPort: 8080,
98+
proxyUser: 'user',
99+
proxyPass: 'pass'
100+
}, function(){
101+
expect(bsLocal.getBinaryArgs().indexOf('-proxyHost localhost')).to.not.equal(-1);
102+
expect(bsLocal.getBinaryArgs().indexOf('-proxyPort 8080')).to.not.equal(-1);
103+
expect(bsLocal.getBinaryArgs().indexOf('-proxyUser user')).to.not.equal(-1);
104+
expect(bsLocal.getBinaryArgs().indexOf('-proxyPass pass')).to.not.equal(-1);
105+
done();
106+
});
107+
});
108+
109+
it('should set hosts', function (done) {
110+
bsLocal.start({ key: process.env.BROWSERSTACK_ACCESS_KEY, onlyCommand: true, hosts: 'localhost,8000,0' }, function(){
111+
expect(bsLocal.getBinaryArgs().indexOf('localhost,8000,0')).to.not.equal(-1);
112+
done();
113+
});
114+
});
115+
116+
afterEach(function (done) {
117+
bsLocal.stop(done);
118+
});
119+
120+
});

0 commit comments

Comments
 (0)
Please sign in to comment.