6axter82
6axter82

Reputation: 589

how to set cucumber environment variables

I am having the following package.json:

{
  "name": "newcucumber",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "./node_modules/.bin/cucumber-js",
    "firefox": "./node_modules/.bin/cucumber-js -- --profile.desktop.env.browser ff"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "chromedriver": "^2.24.1",
    "cucumber": "^1.3.0",
    "firefox-profile": "^0.4.2",
    "geckodriver": "^1.1.2",
    "phantomjs-prebuilt": "^2.1.12",
    "selenium-webdriver": "^3.0.0-beta-2"
  }
}

I run the program using:

npm test

I would like to set an environment variable for cucumber, such that I could run from the command line: npm test firefox or npm test phantomjs.

It could also be as a part of package.json 'scripts' as seen above, but I am not sure if I did it right. Invoking npm run-script firefox

How does one implement it, such that in the js code, like world.js or browser.js I grab the env variable?

Upvotes: 2

Views: 16885

Answers (5)

Varangian
Varangian

Reputation: 23

6axter82's solutions works for me...to some degree. In order to pass in variables from command line, I have to add following adjustments. (Environment: Windows 10 / VS Code / Command Prompt)

  1. To execute from scripts property inside package.json, additional backslash () is needed.
    "firefox": "cucumber-js --world-parameters '{\"browser\":\"firefox\"}'",

    is converted into

    "firefox": "cucumber-js --world-parameters {\\\"browser\\\":\\\"firefox\\\"}"

  2. (If default constructor is overridden by setWorldConstructor(World)) Create constructor for World as specified on Cucumber.js/World Doc, specifically

    function World({attach, parameters}) { this.attach = attach this.parameters = parameters }

  3. To reference parameter values inside World class (world.js), use following expression this.parameters.browser

Hope this helps.

Upvotes: 0

6axter82
6axter82

Reputation: 589

Once more, now I have got the answer I wanted to use in the first place:

This is how part of package.json (MIND!!! the syntax of quotation marks) looks like:

"scripts": {
    "test": "cucumber-js",
    "firefox": "cucumber-js --world-parameters '{\"browser\":\"firefox\"}'",
    "chrome": "cucumber-js --world-parameters '{\"browser\":\"chrome\"}'",
    "safari": "cucumber-js --world-parameters '{\"browser\":\"safari\"}'",
    "phantomjs": "cucumber-js --world-parameters '{\"browser\":\"phantomjs\"}'"
  }

The JSON object is passed to World. In your World.js the code looks like this:

module.exports = function() {
  this.World = function(input) {
    console.log(input.browser); // Do whatever you want with the JSON (input) object
  };
};

Upvotes: 2

6axter82
6axter82

Reputation: 589

I decided not to change something in node_modules or whatever, cause after the next npm update <package> the changes will be lost.

The Idea is to set the env variable:

  1. Create a start.sh file in the directory where you call npm test from.
  2. Write in start.sh:

    #!/bin/bash
    export BROWSER=$1
    npm test
    
  3. Inside your browser.jsor the file where you call your browsers type:

    var chrome = require('chromedriver'),
    phantom = require('phantomjs-prebuilt'),
    firefox = require('selenium-webdriver/firefox'),
    webdriver = require('selenium-webdriver');
    ...
    
    console.log("What was passed into global env: ", process.env.BROWSER);
    switch(process.env.BROWSER) {
        case 'firefox':                             //Setup Firefox
            var capabilities = {
                'browserName' : 'firefox'
            }
            break; 
        case 'phantomjs':
            var capabilities = {
                'browserName' : 'phantomjs'
            }
            break;
        case 'chrome':
            var capabilities = {
                'browserName' : 'chrome'
            }
            break;
        }
    
    return browserHandle = new webdriver
        .Builder()
        .withCapabilities(capabilities)
        .build();
    
    1. Call . start.sh firefox (phantomjs, chrome)

Upvotes: 1

acontell
acontell

Reputation: 6932

I haven't tried it myself but, according to cucumber's CLI documentation, there's a way to pass data to the world constructor (World parameters, by the end of the page)

You could pass the browser to the World constructor and let it create the webdriver instance according to your choice.

I guess the script part in your package.json could be (more or less) as follows:

"scripts": {
    "test": "cucumber-js",
    "firefox": "./node_modules/.bin/cucumber-js --world-parameters <JSON>"
  }

where <JSON> would contain the info. about the browser type, etc. Hope it helps.

Upvotes: 0

Stavros Zavrakas
Stavros Zavrakas

Reputation: 3063

You can do something like that when you want to define env vars. By the way, it is not mandatory to add the whole path, npm will figure it out

{
  "name": "newcucumber",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "cucumber-js",
    "firefox": "NODE_ENV=test cucumber-js -- --profile.desktop.env.browser ff"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "chromedriver": "^2.24.1",
    "cucumber": "^1.3.0",
    "firefox-profile": "^0.4.2",
    "geckodriver": "^1.1.2",
    "phantomjs-prebuilt": "^2.1.12",
    "selenium-webdriver": "^3.0.0-beta-2"
  }
}

Upvotes: 1

Related Questions