Skip to content

Commit

Permalink
Merge pull request #52 from mazswojejzony/env-settings
Browse files Browse the repository at this point in the history
LAUNCHPAD_<browser> & LAUNCHPAD_BROWSERS env vars
  • Loading branch information
daffl committed Nov 19, 2015
2 parents d6662c0 + c9f7b91 commit 9f409cb
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 43 deletions.
2 changes: 2 additions & 0 deletions .jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
"describe": true,
"before": true,
"after": true,
"beforeEach": true,
"afterEach": true,
"exports": true
},
"eqnull": true,
Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Launchpad
Touched
[![Build Status](https://travis-ci.org/ekryski/launchpad.svg)](https://travis-ci.org/ekryski/launchpad)

You can launch browsers! With NodeJS!
Expand Down Expand Up @@ -34,7 +33,7 @@ launch.<type>(configuration, function(error, launcher) {

## Local launchers

Local launchers look up all currently installed browsers and allow you to start new browser processes.
Local launchers look up all currently installed browsers (unless limited by LAUNCHPAD_BROWSERS - see below for details) and allow you to start new browser processes.

```js
// Launch a local browser
Expand All @@ -52,6 +51,16 @@ launch.local(function(err, local) {
});
```

### Environment variables impacting local browsers detection

By default Launchpad looks up all installed browsers. To speed-up this process you can define the following env variables:
* `LAUNCHPAD_BROWSERS` - comma delimited list of browsers you want to use, e.g. `LAUNCHPAD_BROWSERS=chrome,firefox,opera`. Other browsers will not be detected even if they are installed.
* `LAUNCHPAD_<browser>` - specifies where given browser is installed so that Launchpad does not need to look for it, e.g.
`LAUNCHPAD_CHROME=/usr/bin/chromium`

The following browser names are recognized: `chrome`, `firefox`, `safari`, `ie`, `opera`, `canary`, `aurora`, `phantom`, `nodeWebKit`.
Not all platforms support all browsers - see [platform](lib/local/platform) for details.

## Browserstack

BrowserStack is a great cross-browser testing tool and offers API access to any account that is on a monthly plan.
Expand Down
24 changes: 20 additions & 4 deletions lib/local/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ module.exports = function (browser) {
if (!cache[name]) {
debug('Caching discovery for local browser', browser.name);
cache[name] = Q(_.clone(browser)).then(function (current) {
// Check in default location first
if (browser.defaultLocation && fs.existsSync(browser.defaultLocation)) {
debug('Found browser ' + current.name + ' in default location', browser.defaultLocation);
return setPath(current, browser.defaultLocation);
var location = checkDefaultLocations(browser, current);
if (location) {
return setPath(current, location);
}

// Run the pathQuery to see if we can find it somewhere else
Expand Down Expand Up @@ -53,6 +52,23 @@ module.exports = function (browser) {
return cache[name];
};

function checkDefaultLocations(browser, current) {
var locations = browser.defaultLocation ? [].concat(browser.defaultLocation) : [];
var envLocation = process.env['LAUNCHPAD_' + browser.name.toUpperCase()];
if (envLocation) {
locations.unshift(envLocation);
}

for (var i = 0; i < locations.length; i++) {
var location = locations[i];
if (location && fs.existsSync(location)) {
debug('Found browser ' + current.name + ' in', location);
return location;
}
}
return null;
}

function setPath(browser, newPath) {
browser.path = newPath;
if (browser.path.slice(-4) === '.app') {
Expand Down
10 changes: 2 additions & 8 deletions lib/local/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,12 @@ var debug = require('debug')('launchpad:local');
var instance = require('./instance');
var getBrowser = require('./browser');
var getVersion = require('./version');
var platform = require('./platform');

var normalize = function(browser) {
return _.pick(browser, 'name', 'version', 'path', 'binPath');
};
var platforms = {
win32 : './platform/windows',
darwin : './platform/macos',
linux : './platform/unix',
freebsd : './platform/unix',
sunos : './platform/unix'
};
var platform = require(platforms[process.platform]);

var tmpdir = process.env.TMPDIR || process.env.TMP;
var cleanLaunch = {
firefox: ['-no-remote', '-silent', '-p', 'launchpad-firefox'],
Expand Down
17 changes: 17 additions & 0 deletions lib/local/platform/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
var _ = require('underscore');
var debug = require('debug')('launchpad:local:platform');

var platforms = {
win32 : './windows',
darwin : './macos',
linux : './unix',
freebsd : './unix',
sunos : './unix'
};

var platform = require(platforms[process.platform]);
var envBrowsers = process.env.LAUNCHPAD_BROWSERS;
var enabledBrowsers = envBrowsers ? envBrowsers.split(/\s*,\s*/) : Object.keys(platform);

debug('Local platform init. Enabled browsers:', enabledBrowsers.sort().join(', '));
module.exports = _.pick(platform, enabledBrowsers);
12 changes: 10 additions & 2 deletions lib/local/platform/windows.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ var appData = appData || process.env.APPDATA;

module.exports = {
chrome: {
defaultLocation: path.join(appData, 'Google', 'Chrome', 'Application', 'chrome.exe') ,
defaultLocation: altPaths('Google', 'Chrome', 'Application', 'chrome.exe') ,
pathQuery: 'dir /s /b chrome.exe',
cwd: cwd,
opensTab: true
},
canary: {
defaultLocation: path.join(appData, 'Google', 'Chrome SxS', 'Application', 'chrome.exe')
defaultLocation: altPaths('Google', 'Chrome SxS', 'Application', 'chrome.exe')
},
firefox: {
defaultLocation: path.join(programFiles, 'Mozilla Firefox', 'firefox.exe'),
Expand Down Expand Up @@ -54,3 +54,11 @@ module.exports = {
}
}
};

function altPaths() {
var args = Array.prototype.slice.call(arguments);
return [
path.join.apply(path, [programFiles].concat(args)),
path.join.apply(path, [appData].concat(args))
];
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@
"test": "grunt test --stack"
},
"devDependencies": {
"decache": "^3.0.3",
"expect.js": "^0.3.1",
"grunt": "^0.4.5",
"grunt-cli": "^0.1.13",
"grunt-contrib-jshint": "^0.11.2",
"grunt-release": "^0.13.0",
"grunt-simple-mocha": "^0.4.0",
"mocha": "^2.3.0",
"phantomjs": "^1.9.18",
"useragent": "^2.1.7"
},
"dependencies": {
Expand Down
84 changes: 57 additions & 27 deletions test/local.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
var assert = require('assert');
var http = require('http');
var local = require('../lib/local');
var path = require('path');
var decache = require('decache');
var useragent = require('useragent');
var familyMapping = {
canary: 'chrome',
Expand All @@ -13,38 +14,67 @@ var server = http.createServer(function (req, res) {
}).listen(6785);

describe('Local browser launcher tests', function() {
it('does local browser and version discovery', function(done) {
local(function(error, launcher) {
launcher.browsers(function(error, browsers) {
assert.ok(!error, 'No error discovering browsers');
assert.ok(browsers.length, 'Found at least one browser');
assert.ok(browsers[0].version, 'First browser has a version');
assert.ok(browsers[0].path, 'First browser has a path');
assert.ok(browsers[0].binPath, 'First browser has a binPath');
done();

describe('Default env settings', function () {

var local = require('../lib/local');

it('does local browser and version discovery', function (done) {
local(function (error, launcher) {
launcher.browsers(function (error, browsers) {
assert.ok(!error, 'No error discovering browsers');
assert.ok(browsers.length, 'Found at least one browser');
assert.ok(browsers[0].version, 'First browser has a version');
assert.ok(browsers[0].path, 'First browser has a path');
assert.ok(browsers[0].binPath, 'First browser has a binPath');
done();
});
});
});
});

Object.keys(local.platform).forEach(function(name) {
it('Launches ' + name + ' browser on ' + process.platform, function(done) {
local(function(error, launcher) {
launcher[name]('http://localhost:6785', function(error, instance) {
if(error) {
// That's the only error we should get
assert.equal(error.message, 'Browser ' + name + ' not available.');
return done();
}

server.once('request', function(req) {
var userAgent = useragent.parse(req.headers['user-agent']);
var expected = familyMapping[name] || name;

assert.equal(userAgent.family.toLowerCase(), expected, 'Got expected browser family');
instance.stop(done);
Object.keys(local.platform).forEach(function (name) {
it('Launches ' + name + ' browser on ' + process.platform, function (done) {
local(function (error, launcher) {
launcher[name]('http://localhost:6785', function (error, instance) {
if (error) {
// That's the only error we should get
assert.equal(error.message, 'Browser ' + name + ' not available.');
return done();
}

server.once('request', function (req) {
var userAgent = useragent.parse(req.headers['user-agent']);
var expected = familyMapping[name] || name;

assert.equal(userAgent.family.toLowerCase(), expected, 'Got expected browser family');
instance.stop(done);
});
});
});
});
});
});

describe('Custom env settings', function () {

decache(path.join(__dirname, '..', 'lib', 'local', 'index.js'));

process.env.LAUNCHPAD_BROWSERS = 'phantom';
process.env.LAUNCHPAD_PHANTOM = /^win/.test(process.platform) ?
path.join(__dirname, '..', 'node_modules', 'phantomjs', 'lib', 'phantom', 'phantomjs.exe') :
path.join(__dirname, '..', 'node_modules', 'phantomjs', 'bin', 'phantomjs');

var local = require('../lib/local');

it('detects PhantomJS only due to env settings', function (done) {
local(function (error, launcher) {
launcher.browsers(function (error, browsers) {
assert.ok(!error, 'No error discovering browsers');
assert.ok(browsers.length == 1, 'Found PhantomJS browser');
assert.ok(browsers[0].path == process.env.LAUNCHPAD_PHANTOM, 'Found PhantomJS at selected location');
done();
});
});
});
});
});

0 comments on commit 9f409cb

Please sign in to comment.