CrossBrowserTesting.com

A Design, Development, Testing Blog

  • Product Overview
  • Pricing
  • Back Home
  • Free Trial
  • Design
  • Development
  • Manual Testing
  • Test Automation
  • Visual Testing

Maximum Concurrency with Nightwatch.js

January 9, 2019 By John Reese Leave a Comment

Nightwatch.js parallel testing

Nightwatch.js parallel testing

You made it. After weeks writing a dozen Selenium tests with Nightwatch.js, you are done. Your elements have been found, your buttons have been clicked, and your page objects have been modeled. The only thing left is to run your suite of tests across all the browsers you care about. That’s where parallel testing comes in handy. Twelve tests across five platforms mean 60 test cases, but you have a 25-parallel Automation plan, so this shouldn’t take long.

$ nightwatch --env ie,edge,chrome,ff,safari

You press enter and…

Started child process for: ie environment
Started child process for: edge environment
Started child process for: chrome environment
Started child process for: ff environment
Started child process for: safari environment

Huh, that’s funny. It looks like it’s only running five tests at a time, not 20.

Yup, CBT shows that there are only five tests running. What gives?

It turns out that if you use the --env flag to specify the browsers to run on, then Nightwatch will run each environment in parallel, but each test case will execute sequentially.

That’s not what we want! What’s the point of having a big beefy Automation plan if you can’t use it?

So the question becomes, how do we run with MAXIMUM CONCURRENCY?

Well, I couldn’t figure out how to do it in Nightwatch, but I hacked together a workaround!

The following Node.js code will take the --env (or -e) flag and launch an instance of Nightwatch for each specified environment. If no environment is specified, then it will use all environments specified in your Nightwatch configuration file.

parallel-nw.js:

const cbt = require('cbt_tunnels');
const nwConfig = require('./nightwatch')

const spawn = require('child_process').spawn;

const tunnelOptions = {
  'username': nwConfig.test_settings.default.username,
  'authkey': nwConfig.test_settings.default.access_key
}

async function startTunnel(tunnelOptions){
  return new Promise( (resolve, reject) => {
    cbt.start(tunnelOptions, function(err, data) {
      if (err) {
        reject(err)
      } else {
        resolve(data)
      }
    });
  })
}

function envNames(config){
  if(config && config.test_settings){
    return Object.keys(config.test_settings);
  }
  else {
    return [];
  }
}

async function spawnNW(envName){
  return new Promise( (resolve, reject) => {
    let err;
    let proc = spawn('nightwatch', ['-e', envName], {shell:true});
    proc.stdout.on('data', data => {
      if (data.toString('utf8').replace(/\s/g, '') !== ""){
        console.log(`${envName}:\n ${data.toString('utf8')}`)
      }
    })
    proc.stderr.on('data', data => {
      if (data.toString('utf8').replace(/\s/g, '') !== ""){
        console.error(data.toString('utf8'))
      }
    })
    proc.on('close', (code) => {
      if(code === 0){
        console.log(`${envName}: Finished!`)
        resolve(code)
      }
      else {
        reject(new Error(`${envName}: failed ` + err));
      }
    })
  })
}



( async () => {

  // make sure tunnel is started before starting selenium tests
  await startTunnel(tunnelOptions);


  // look for environment names in command line args...
  let names;
  for (let i=0; i < process.argv.length; i++){
    if (process.argv[i] === '--env' || process.argv[i] === '-e'){
      names = process.argv[i+1].split(',');
    }
  }

  // or pull from the config file
  if (names === undefined){
    names = envNames(nwConfig);
  }

  // spawn nightwatch for each environment
  let procs = names.map(spawnNW)

  console.log(`Starting to run Nightwatch on ${names.join(', ')}`)

  // wait for all nightwatch processes to return
  Promise.all(procs)
    .then( () => {
        console.log('Nightwatch finished!')
        // stop tunnel when all tests are done
        cbt.stop()
    })
    .catch( (err) => {console.log(err)})
})()

Once that file is in place, we can use it to run our tests!

node parallel-nw.js --env ie,edge,chrome,ff,safari

Much better!


Nightwatch.js is an End-to-End testing platform for writing and running Selenium tests with Node.js.

Filed Under: Test Automation Tagged With: nightwatch.js, parallel testing, test automation

Try CrossBrowserTesting

Everything you need for testing on the web. Browsers & Devices included.


  • Grid In The Cloud
  • Simple CI Integrations
  • Native Debugging Tools
  • Real iOS and Android
  • 2050+ Browser/OS Combinations
  • Intuitive REST API

Start Testing Today

Want Testing Tips?

Want the latest tips & strategies from industry experts right to your inbox? Sign up below.
 

Join Over 600,000 Testers & Developers And Start Testing Today

Learn more Free Trial

Features

  • Live Testing
  • Selenium Automation
  • Automated Screenshots
  • Screenshot Comparison
  • Local Testing
  • Real Devices

Solutions

  • Automated Testing
  • Visual Testing
  • Manual Testing
  • Enterprise
  • Internet Explorer

Resources

  • Browsers & Devices
  • Blog
  • Webinars
  • Integrations
  • ROI Calculator

Company

  • About Us
  • Careers
  • Plans
  • Terms of use
  • Security

Support

  • Help Center
  • API Docs
  • Schedule A Demo
  • Contact Us
  • Write For Us