diff --git a/.travis.yml b/.travis.yml index fc80815..c9d2de8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +dist: trusty sudo: true language: node_js before_install: @@ -11,3 +12,5 @@ os: node_js: - 4 - node +addons: + chrome: stable diff --git a/lib/local/chrome.js b/lib/local/chrome.js new file mode 100644 index 0000000..90b1c88 --- /dev/null +++ b/lib/local/chrome.js @@ -0,0 +1,21 @@ +var chromeLauncher = require('chrome-launcher-4'); + +function chromeWithFlags (flags) { + return function startChrome (url) { + return chromeLauncher + .launch({ + startingUrl: url, + flags: flags + }) + .then(function (chrome) { + return function stopChrome () { + return chrome.kill(); + }; + }); + }; +} + +module.exports = { + chromeHeadfull: chromeWithFlags([]), + chromeHeadless: chromeWithFlags(['--headless', '--disable-gpu']) +}; diff --git a/lib/local/index.js b/lib/local/index.js index 33826cc..1913011 100644 --- a/lib/local/index.js +++ b/lib/local/index.js @@ -2,6 +2,7 @@ var _ = require('underscore'); var Q = require('q'); var debug = require('debug')('launchpad:local'); +var chrome = require('./chrome'); var instance = require('./instance'); var getBrowser = require('./browser'); var getVersion = require('./version'); @@ -28,6 +29,13 @@ module.exports = function (settings, callback) { var api = function(url, options, callback) { var name = options.browser; + if (name === 'chromeHeadfull') { + return api.chromeHeadfull(url, options, callback); + } + if (name === 'chromeHeadless') { + return api.chromeHeadless(url, options, callback); + } + debug('Launching browser', url, options); getBrowser(_.extend({ name: name }, platform[name])).then(function(browser) { if(browser === null) { @@ -42,7 +50,7 @@ module.exports = function (settings, callback) { if(options.args) { args = args.concat(options.args); } - + // Convert the command if set (some browsers need some customization) if(browser.getCommand) { browser.command = browser.getCommand(browser, url, args, options); @@ -80,7 +88,35 @@ module.exports = function (settings, callback) { }; }); + api.chromeHeadfull = instafy(chrome.chromeHeadfull); + api.chromeHeadless = instafy(chrome.chromeHeadless); + callback(null, api); }; +function instafy (promiseLauncher) { + return function _instafy (url, options, callback) { + if (!callback) { + callback = options; + options = {}; + } + + nodeify(promiseLauncher(url, options), function (error, stop) { + if (error) return callback(error); + + var instanceStop = function (callback) { + nodeify(stop(), callback); + }; + + callback(null, {stop: instanceStop}); + }); + }; +} + +function nodeify (promise, callback) { + promise + .then(function (stop) {callback(null, stop);}) + .catch(function (error) {callback(error);}); +} + module.exports.platform = platform; diff --git a/package.json b/package.json index 3cbf861..db8c489 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "dependencies": { "async": "^2.0.1", "browserstack": "^1.2.0", + "chrome-launcher-4": "0.0.2", "debug": "^2.2.0", "plist": "^2.0.1", "q": "^1.4.1", diff --git a/test/local.js b/test/local.js index f8a4436..baa1644 100644 --- a/test/local.js +++ b/test/local.js @@ -16,10 +16,8 @@ var server = http.createServer(function (req, res) { describe('Local browser launcher tests', function() { + var local = require('../lib/local'); 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) { @@ -32,9 +30,17 @@ describe('Local browser launcher tests', function() { }); }); }); - - Object.keys(local.platform).forEach(function (name) { - it('Launches ' + name + ' browser on ' + process.platform, function (done) { + + var browsers = Object.keys(local.platform); + browsers.forEach(function (name) { + var testTitle = 'Should launch ' + name + ' browser on ' + process.platform; + + if (name === 'firefox') { + it.skip(testTitle); + return; + } + + it(testTitle, function (done) { local(function (error, launcher) { launcher[name]('http://localhost:6785', function (error, instance) { if (error) { @@ -47,7 +53,7 @@ describe('Local browser launcher tests', function() { var userAgent = useragent.parse(req.headers['user-agent']); var expected = familyMapping[name] || name; - assert.equal(userAgent.family.toLowerCase(), expected, 'Got expected browser family'); + assert.equal(userAgent.family.toLowerCase(), expected, 'User agent family should match browser family'); instance.stop(done); }); }); @@ -56,6 +62,42 @@ describe('Local browser launcher tests', function() { }); }); + describe('Supported Chrome Launcher', function () { + var url = 'http://localhost:6785'; + + it('should launch Chrome', function (done) { + local(function (error, launcher) { + if (error) return done(error); + + launcher.chromeHeadfull(url, function (error, instance) { + if (error) return done(error); + + server.once('request', function (req) { + var userAgent = useragent.parse(req.headers['user-agent']); + assert.equal(userAgent.family.toLowerCase(), 'chrome', 'Should be Chrome useragent'); + instance.stop(done); + }); + }); + }); + }); + + it('should launch Headless Chrome', function (done) { + local(function (error, launcher) { + if (error) return done(error); + + launcher.chromeHeadless(url, function (error, instance) { + if (error) return done(error); + + server.once('request', function (req) { + var userAgent = useragent.parse(req.headers['user-agent']); + assert.equal(userAgent.family.toLowerCase(), 'chrome', 'Should be Chrome useragent'); + instance.stop(done); + }); + }); + }); + }); + }); + describe('Custom env settings', function () { var node_modules = path.join(__dirname, '..', 'node_modules');