diff --git a/lib/cli.js b/lib/cli.js index d0818f8ee..4715fbf96 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -1,15 +1,46 @@ +/** + * The command line interface for interacting with the Protractor runner. + * It takes care of parsing the config file and command line options. + */ + var util = require('util'); var path = require('path') var fs = require('fs'); var runner = require('./runner.js'); -var glob = require('glob'); +var argv = require('optimist'). + usage('Usage: protractor [options] [config]'). + describe('version', 'Print Protractor version'). + describe('browser', 'Browsername, e.g. chrome or firefox'). + describe('seleniumAddress', 'A running seleium address to use'). + describe('seleniumServerJar', 'Location of the standalone selenium jar file'). + describe('seleniumPort', 'Optional port for the selenium standalone server'). + describe('baseUrl', 'URL to prepend to all relative paths'). + describe('rootElement', 'Element housing ng-app, if not html or body'). + describe('specs', 'Comma-separated list of files to test'). + describe('verbose', 'Print full spec names'). + describe('includeStackTrace', 'Print stack trace on error'). + describe('params', 'Param object to be passed to the tests'). + alias('browser', 'capabilities.browserName'). + alias('name', 'capabilities.name'). + alias('platform', 'capabilities.platform'). + alias('platform-version', 'capabilities.version'). + alias('tags', 'capabilities.tags'). + alias('build', 'capabilities.build'). + boolean('verbose'). + boolean('includeStackTrace'). + alias('verbose', 'jasmineNodeOpts.verbose'). + alias('includeStackTrace', 'jasmineNodeOpts.includeStackTrace'). + check(function(arg) { + if (arg._.length > 1) { + throw 'Error: more than one config file specified' + } + if (!(process.argv.length > 2)) { + throw ''; + } + }). + argv; -/** - * The command line interface for interacting with the Protractor runner. - * It takes care of parsing the config file and command line options. - */ -var args = process.argv.slice(2); var configPath; @@ -19,101 +50,24 @@ var printVersion = function () { process.exit(0); }; - -if (!args.length) { - util.puts('USAGE: protractor [configFile] [options]'); - util.puts('Options:'); - util.puts(' --version: Print Protractor version'); - util.puts(' --browser : Browsername, e.g. chrome or firefox'); - util.puts(' --seleniumAddress : A running selenium address to use'); - util.puts(' --seleniumServerJar : Location of the standalone selenium server .jar file'); - util.puts(' --seleniumPort : Optional port for the standalone selenium server'); - util.puts(' --baseUrl : URL to prepend to all relative paths'); - util.puts(' --rootElement : Element housing ng-app, if not html or body'); - util.puts(' --specs : Comma separated list of files to test'); - util.puts(' --[no]includeStackTrace: Print stack trace on error'); - util.puts(' --verbose: Print full spec names'); - - process.exit(0); +if (argv.version) { + printVersion(); } -var commandLineConfig = { capabilities: {}, jasmineNodeOpts: {}}; - -while(args.length) { - var arg = args.shift(); - switch(arg) { - case '--version': - printVersion(); - break; - case '--browser': - commandLineConfig.capabilities.browserName = args.shift(); - break; - case '--name': - commandLineConfig.capabilities.name = args.shift(); - break; - case '--platform': - commandLineConfig.capabilities.platform = args.shift(); - break; - case '--platform-version': - commandLineConfig.capabilities.version = args.shift(); - break; - case '--build': - commandLineConfig.capabilities.build = args.shift(); - break; - case '--tags': - commandLineConfig.capabilities.tags = args.shift().split(','); - break; - case '--seleniumAddress': - commandLineConfig.seleniumAddress = args.shift(); - break; - case '--seleniumServerJar': - commandLineConfig.seleniumServerJar = args.shift(); - break; - case '--seleniumPort': - commandLineConfig.seleniumPort = args.shift(); - break; - case '--chromeDriver': - commandLineConfig.chromeDriver = args.shift(); - break; - case '--sauceUser': - commandLineConfig.sauceUser = args.shift(); - break; - case '--sauceKey': - commandLineConfig.sauceKey = args.shift(); - break; - case '--baseUrl': - commandLineConfig.baseUrl = args.shift(); - break; - case '--rootElement': - commandLineConfig.rootElement = args.shift(); - break; - case '--specs': - commandLineSpecs = args.shift().split(','); - commandLineSpecs.forEach(function(spec, index, arr) { - arr[index] = path.resolve(process.cwd(), spec); - }); - commandLineConfig.specs = commandLineSpecs; - break; - case '--includeStackTrace': - commandLineConfig.jasmineNodeOpts.includeStackTrace = true; - break; - case '--noincludeStackTrace': - commandLineConfig.jasmineNodeOpts.includeStackTrace = false; - break; - case '--verbose': - commandLineConfig.jasmineNodeOpts.isVerbose = true; - break; - default: - configPath = path.resolve(process.cwd(), arg); - break; - } +if (argv.specs) { + argv.specs = argv.specs.split(','); + argv.specs.forEach(function(spec, index, arr) { + arr[index] = path.resolve(process.cwd(), spec); + }); } -if (configPath) { +var configFilename = argv._[0]; +if (configFilename) { + configPath = path.resolve(process.cwd(), configFilename); runner.addConfig(require(configPath).config); runner.addConfig({specFileBase: path.dirname(configPath)}) } -runner.addConfig(commandLineConfig); +runner.addConfig(argv); runner.runOnce(); diff --git a/lib/protractor.js b/lib/protractor.js index 77a0bb046..419f8a36a 100644 --- a/lib/protractor.js +++ b/lib/protractor.js @@ -91,6 +91,13 @@ var Protractor = function(webdriver, opt_baseUrl, opt_rootElement) { */ this.ignoreSynchronization = false; + /** + * An object that holds custom test parameters. + * + * @type {Object} + */ + this.params = {}; + this.moduleNames_ = []; this.moduleScripts_ = []; diff --git a/lib/runner.js b/lib/runner.js index fe3a93fd3..ea395e163 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -26,6 +26,7 @@ var config = { 'browserName': 'chrome' }, rootElement: 'body', + params: {}, jasmineNodeOpts: { isVerbose: false, showColors: true, @@ -190,10 +191,13 @@ var runJasmineTests = function() { sessionId = session.getId(); - protractor.setInstance(protractor.wrapDriver( + var ptor = protractor.wrapDriver( driver, config.baseUrl, - config.rootElement)); + config.rootElement) + ptor.params = config.params; + + protractor.setInstance(ptor); // Export protractor to the global namespace to be used in tests. global.protractor = protractor; diff --git a/package.json b/package.json index 6255b6551..e8d3ff761 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "minijasminenode": "~0.2.4", "saucelabs": "~0.1.0", "glob": ">=3.1.14", - "adm-zip": ">=0.4.2" + "adm-zip": ">=0.4.2", + "optimist": "~0.6.0" }, "devDependencies": { "expect.js": "~0.2.0", diff --git a/referenceConf.js b/referenceConf.js index 33d6c18bb..a9dec2d4e 100644 --- a/referenceConf.js +++ b/referenceConf.js @@ -56,6 +56,8 @@ exports.config = { 'browserName': 'chrome' }, + // ----- More information for your tests ---- + // // A base URL for your application under test. Calls to protractor.get() // with relative paths will be prepended with this. baseUrl: 'http://localhost:8000', @@ -74,6 +76,18 @@ exports.config = { // jasmine.getEnv().addReporter(new jasmine.JUnitXmlReporter( // 'outputdir/', true, true)); }, + + // The params object will be passed directly to the protractor instance, + // and can be accessed from your test. It is an arbitrary object and can + // contain anything you my need in your test. + // This can be changed via the command line as: + // --params.login.user 'Joe' + params: { + login: { + user: 'Jane', + password: '1234' + } + } // ----- Options to be passed to minijasminenode ----- jasmineNodeOpts: { diff --git a/spec/basicConf.js b/spec/basicConf.js index 0c5ef5383..059799967 100644 --- a/spec/basicConf.js +++ b/spec/basicConf.js @@ -15,4 +15,11 @@ exports.config = { }, baseUrl: 'http://localhost:8000', + + params: { + login: { + user: 'Jane', + password: '1234' + } + } }; diff --git a/spec/lib_spec.js b/spec/lib_spec.js index 46216273b..05f49d5b2 100644 --- a/spec/lib_spec.js +++ b/spec/lib_spec.js @@ -14,6 +14,12 @@ describe('protractor library', function() { expect(ptor.getTitle()).toEqual('My AngularJS App'); }); + it('should export custom parameters to the protractor instance', function() { + expect(ptor.params.login).toBeDefined(); + expect(ptor.params.login.user).toEqual('Jane'); + expect(ptor.params.login.password).toEqual('1234'); + }); + it('should allow a mix of using protractor and using the driver directly', function() { ptor.get('app/index.html');