32

I start my protractor tests by running the following:

protractor protractor.conf.js --params.baseUrl=http://www.google.com --suite all

I would like to run a 'before launch' function which is dependant of one parameter (in this case, the baseUrl). Is it that possible?

exports.config = {
    seleniumServerJar: './node_modules/protractor/selenium/selenium-server-standalone-2.45.0.jar',
    seleniumPort: 4455,
    suites: {
        all: 'test/*/*.js',
    },
    capabilities: {
        'browserName': 'firefox'
    },
    beforeLaunch: function() {
        console.log('I want to access my baseUrl parameter here: ' + config.params.baseUrl);
    },
    onPrepare: function() {

        require('jasmine-reporters');
        jasmine.getEnv().addReporter(
            new jasmine.JUnitXmlReporter('output/xmloutput', true, true));

    }
};

If I run that I get a ReferenceError because config is not defined. How should I do that? Is that even possible?

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
Julio
  • 849
  • 2
  • 10
  • 17

4 Answers4

29

I am not completely sure if protractor globals are set at the beforeLaunch() stage, but they are definitely available at onPrepare() step.

Access the params object through the global browser object:

console.log(browser.params.baseUrl);

Update: Using Jasmine 2.6+, protractor 4.x, browser.params was empty, but the following worked in onPrepare() step:

console.log(browser.baseUrl);
Markus
  • 1,069
  • 8
  • 26
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • As far as I know, they are not available at the beforeLaunch() stage, but for me is good enough to have them in the onPrepare() stage. Thank you for your answer – Julio Apr 02 '15 at 10:32
  • Does this mean that we can't set `specs` based on parameters passed in in this way? I said `specs: [browser.params.test_set+'/*.feature']`, but got "browser not defined" I guess it's because it's way too soon at that point? – GreenAsJade Jun 25 '15 at 03:56
  • @GreenAsJade yeah, global `browser` object is not available at that point. Consider making a separate question: for other users experiencing the same issue it would be helpful in the future. – alecxe Jun 25 '15 at 03:58
  • @alecxe [done](http://stackoverflow.com/questions/31040996/how-can-i-use-a-parameter-to-a-protractor-configuration-file-to-chose-steps) ... if you can help that'd be awesome :) – GreenAsJade Jun 25 '15 at 04:03
  • @GreenAsJade: There is a way to set specs dynamically thru command line arguments. Protractor now processes cmd line args via optimist module which means that, in your config file, you can process command line arguments (via process.argv array) and then define the value of config.specs array dynamically. – exbuddha Feb 12 '16 at 21:55
  • @exbuddha can you give an example of that? Not sure how to pass params using process.argv... – Marko Jun 06 '16 at 22:19
  • @Marko Sure, you can loop thru cmd line args using a simple loop like `for (var i = 3; i < process.argv.length; i++) {...}` and then match each argument against regex pattern `/^--params\.([^=]+)=(.*)$/` to extract the parameter name `match[0]` and its value `match[1]` and finally do what you intend to do with them. In this case, here is a chunk of how I parameterize. See my full response below. – exbuddha Jun 07 '16 at 17:01
  • nice, thank you...I had specific case where I was trying to setup config value of a browserstack config file, that was a adventure and probably one detailed blog post how it can be achieved :D :D – Marko Jun 07 '16 at 18:49
9

In case you need every single item in the entire configuration file, you can use browser.getProcessedConfig() to do this.

onPrepare: () => {
    browser.getProcessedConfig().then(console.log); // even `params` is in here
}
yurisich
  • 6,991
  • 7
  • 42
  • 63
  • 1
    browser.getProcessedConfig() can only retrieve configuration, you cannot transform futher config object for dynamic change of the config variable on a bulid server(i.e. setting up buildnumber) – Marko Jun 07 '16 at 18:52
9

Here is a sample code to iterate thru cmd line args in your Protractor config file and set specs (and some other run configuration values) directly from command line:

config.js

// usage: protractor config.js --params.specs="*" --params.browser=ie --params.threads=1
//        protractor config.js --params.specs="dir1|dir2"
//        protractor config.js --params.specs="dir1|dir2/spec1.js|dir2/spec2.js"

// process command line arguments and initialize run configuration file
var init = function(config) {
  const path = require('path');
  var specs;
  for (var i = 3; i < process.argv.length; i++) {
    var match = process.argv[i].match(/^--params\.([^=]+)=(.*)$/);
    if (match)
      switch (match[1]) {
        case 'specs':
          specs = match[2];
          break;
        case 'browser':
          config.capabilities.browserName = match[2];
          if (match[2].toLowerCase() === 'ie') {
            config.capabilities.browserName = 'internet explorer';
            config.capabilities.platform = 'ANY';
            config.capabilities.version = '11';
            config.seleniumArgs = ['-Dwebdriver.ie.driver=' + path.join('node_modules', 'protractor' ,'selenium' ,'IEDriverServer.exe')];
          }
          if (match[2] !== 'chrome' && match[2] !== 'firefox')
            config.directConnect = false;
          break;
        case 'timeout':
          config.jasmineNodeOpts.defaultTimeoutInterval = parseInt(match[2]);
          break;
        case 'threads':
          config.capabilities.maxInstances = parseInt(match[2]);
          config.capabilities.shardTestFiles = config.capabilities.maxInstances > 1;
          break;
      }
  }

  // generate specs array
  specs.split(/\|/g).forEach(function(dir) {
    if (dir.endsWith('.js'))
      config.specs.push(dir);
    else
      config.specs.push(path.join(dir, '*.js'));
  });

  return config;
};

exports.config = (function() {
  return init({
    specs: [],
    framework: 'jasmine',
    jasmineNodeOpts: {
      defaultTimeoutInterval: 300000 // 5 min
    },
    capabilities: {
      browserName: 'chrome',
      shardTestFiles: false,
      maxInstances: 1
    },
    directConnect: true
  });
})();
exbuddha
  • 603
  • 1
  • 7
  • 19
1

Easy solution

Protractor is a node process. Any node process can be started with custom node variables. Not sure how it's done in windows (please comment if you know how) but for mac and any linux/unix OS you can start protractor with environment variable like this

MY_VAR=Dev protractor tmp/config.js

And then it will be available anywhere within your process

console.log(process.env.MY_VAR)

EVEN OUTSIDE OF onPrepare IN YOUR CONFIG

Sergey Pleshakov
  • 7,964
  • 2
  • 17
  • 40