diff --git a/README.md b/README.md index bd8bff9a9..0dd7d2fad 100644 --- a/README.md +++ b/README.md @@ -353,7 +353,7 @@ Testem passes its own list of arguments to some of the browsers it launches. You } ``` -You can supply arguments to any number of browsers Testem has available by using the launcher name as a key in `browser_args`. Values may be an array of string arguments, a single string, or an object specifying `args` and a `mode` to apply them to. +You can supply arguments to any number of browsers Testem has available by using the launcher name as a key in `browser_args`. Values may be an array of string arguments, a single string, or an object of arguments by mode. Read [more details](docs/browser_args.md) about the browser argument options. diff --git a/docs/browser_args.md b/docs/browser_args.md index 1553cd9f4..2df427948 100644 --- a/docs/browser_args.md +++ b/docs/browser_args.md @@ -49,7 +49,18 @@ Conventions } ``` - * An object specifying a string `mode` (either `ci` or `dev`) and `args` in the form of one of the first two options. The `mode` will determine which environments the given `args` apply to. + * An object of arguments keyed by mode (either `ci` or `dev`) in the form of one of the first two options. Arguments applicable to both modes can be specified with the `all` key. + + ```javascript + "browser_args": { + "chrome": { + "all": "--no-default-browser-check", + "ci": [ "--auto-open-devtools-for-tabs" ] + } + } + ``` + + * **DEPRECATED** An object specifying a string `mode` (either `ci` or `dev`) and `args` in the form of one of the first two options. The `mode` will determine which environments the given `args` apply to. ```javascript "browser_args": { diff --git a/lib/utils/browser-args.js b/lib/utils/browser-args.js index f9ac9b24f..38cf0183f 100644 --- a/lib/utils/browser-args.js +++ b/lib/utils/browser-args.js @@ -2,6 +2,7 @@ var capitalize = require('./capitalize'); var log = require('npmlog'); +var castArray = require('lodash.castarray'); function Validation() { this.knownBrowser = null; @@ -13,6 +14,20 @@ function warn(message) { log.warn('', message); } +function hasOldBrowserArgsFormat(args) { + return args.hasOwnProperty('mode') || + args.hasOwnProperty('args'); +} + +// Lodash's castArray function will turn `undefined` into `[undefined]`, but we want an empty array in that case. +function safeCastArray(value) { + if (value) { + return castArray(value); + } else { + return []; + } +} + module.exports = { addCustomArgs: function(knownBrowsers, config) { if (!knownBrowsers || !config) { return; } @@ -26,19 +41,24 @@ module.exports = { var args = browserArgs[browserName]; if (typeof args === 'object' && !Array.isArray(args)) { - if (!args.mode) { - warn('Type error: when using an object to specify browser_args for ' + browserName + ' you must specify a mode'); - continue; - } else if (!args.args) { - warn('Type error: when using an object to specify browser_args for ' + browserName + ' you must specify args'); - continue; - } - - if (args.mode !== config.appMode) { - continue; + if (hasOldBrowserArgsFormat(args)) { + if (!args.mode) { + warn('Type error: when using an object to specify browser_args for ' + browserName + ' you must specify a mode'); + continue; + } else if (!args.args) { + warn('Type error: when using an object to specify browser_args for ' + browserName + ' you must specify args'); + continue; + } + + if (args.mode !== config.appMode) { + continue; + } + + warn('[DEPRECATION] Specifying browser_args as a hash with "mode" and "args" properties has been deprecated. Mode should be a key with its arguments as a value.'); + args = args.args; + } else { + args = safeCastArray(args.all).concat(safeCastArray(args[config.appMode])); } - - args = args.args; } this.parseArgs(capitalize(browserName), args, knownBrowsers); diff --git a/package.json b/package.json index de3bfb933..c66e94065 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "http-proxy": "^1.13.1", "js-yaml": "^3.2.5", "lodash.assignin": "^4.1.0", + "lodash.castarray": "^4.4.0", "lodash.clonedeep": "^4.4.1", "lodash.find": "^4.5.1", "lodash.uniqby": "^4.7.0", diff --git a/tests/utils/browser-args_tests.js b/tests/utils/browser-args_tests.js index 1ccec3c02..d81fa155d 100644 --- a/tests/utils/browser-args_tests.js +++ b/tests/utils/browser-args_tests.js @@ -131,6 +131,29 @@ describe('browserArgs', function() { knownBrowsers = createKnownBrowsers(); }); + it('warns about deprecation of mode and args fields', function(done) { + knownBrowsers = createKnownBrowsers(); + + config.appMode = 'dev'; + config.browser_args = { + chrome: { + mode: 'dev', + args: '--fake' + } + }; + + log.once('log.warn', function(warning) { + expect(warning.message).to.equal('[DEPRECATION] Specifying browser_args as a hash with "mode" and "args" properties has been deprecated. Mode should be a key with its arguments as a value.'); + done(); + }); + + browserArgs.addCustomArgs(knownBrowsers, config); + + // Resets known browsers value + knownBrowsers = createKnownBrowsers(); + }); + + // NOTE: knownBrowsers[0] is Chrome it('adds args to browser regardless of key capitalization', function() { // Get Chrome's default args @@ -150,6 +173,75 @@ describe('browserArgs', function() { // Resets known browsers value knownBrowsers = createKnownBrowsers(); }); + + describe('object form with mode as key', function() { + it('adds args for matching appMode', function() { + // Get Chrome's default args + var defaultArgs = createKnownBrowsers()[0].args(); + + knownBrowsers = createKnownBrowsers(); + + config.appMode = 'dev'; + config.browser_args = { + chrome: { + dev: ['--fake'], + ci: ['--ci-only'] + } + }; + + browserArgs.addCustomArgs(knownBrowsers, config); + + expect(knownBrowsers[0].args()).to.deep.equal([ '--fake' ].concat(defaultArgs)); + + // Resets known browsers value + knownBrowsers = createKnownBrowsers(); + }); + + it('adds args with "all" merged in', function() { + // Get Chrome's default args + var defaultArgs = createKnownBrowsers()[0].args(); + + knownBrowsers = createKnownBrowsers(); + + config.appMode = 'ci'; + config.browser_args = { + chrome: { + all: '--all', + dev: ['--fake'], + ci: ['--ci-only'] + } + }; + + browserArgs.addCustomArgs(knownBrowsers, config); + + expect(knownBrowsers[0].args()).to.deep.equal([ '--all', '--ci-only' ].concat(defaultArgs)); + + // Resets known browsers value + knownBrowsers = createKnownBrowsers(); + }); + + it('adds "all" args if arguments for the appMode are not set', function() { + // Get Chrome's default args + var defaultArgs = createKnownBrowsers()[0].args(); + + knownBrowsers = createKnownBrowsers(); + + config.appMode = 'ci'; + config.browser_args = { + chrome: { + all: '--all', + dev: ['--fake'] + } + }; + + browserArgs.addCustomArgs(knownBrowsers, config); + + expect(knownBrowsers[0].args()).to.deep.equal([ '--all' ].concat(defaultArgs)); + + // Resets known browsers value + knownBrowsers = createKnownBrowsers(); + }); + }); }); describe('createValidation', function() {