Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

End-to-End Automation Using Nightwatch

DZone's Guide to

End-to-End Automation Using Nightwatch

Nightwatch makes it easy to write and automate end-to-end browser tests. Learn how to take advantage of this browser testing solution.

· DevOps Zone
Free Resource

The Nexus Suite is uniquely architected for a DevOps native world and creates value early in the development pipeline, provides precise contextual controls at every phase, and accelerates DevOps innovation with automation you can trust. Read how in this ebook.

What is Nightwatch.js?

Nightwatch.js is an automated testing framework for web applications written in Node.js and using the W3C WebDriver API (formerly Selenium WebDriver).

It is a complete (End-to-End) browser testing solution which aims to simplify the process of setting up a Continuous Integration and writing automated tests. Nightwatch can also be used to write Node.js unit tests. Nightwatch gives the flexibility of using JavaScript to automate the required scenarios similar to using WebDriver.

Mode of Operation

Nightwatch works by communicating over a restful HTTP API with a WebDriver server (typically the Selenium server), the restful API protocol is defined by the W3C WebDriver API. See the following diagram to understand the Nightwatch workflow.

operation

Nightwatch sends two requests to the WebDriver server in order to perform an assertion or for interacting with the required page objects of the application. The first request sent is to locate the element using Xpath or CSS selector and the next to perform the actual command/assertion on the given element.

Installation

It is very easy to install. All you need is to have Node.js and NPM (node package manager) installed within your system.

There are two ways of installing Nightwatch in your system:

  • To install Nightwatch respective to your project or within your project directory, just run the following command:
npm install nightwatch
  • To install Nightwatch as a global runner within your system, run the following command:
npm install [-g] nightwatch

You will just need to add a -g option to make Nightwatch runner available globally in your system.

Note: You might need to add a sudo before running npm if you are operating in a Linux system.

Selenium Server Setup

The most common WebDriver implementation is the Selenium Server. This allows you to manage multiple browser configurations in one place. However, you can also run the individual browser drivers directly.

Selenium Server

Selenium Server is a Java application which Nightwatch uses to connect to the various browsers. It runs separately on the machine with the browser you want to test. You will need to have the Java Development Kit (JDK) installed, minimum required java version should be 7.

Running Selenium Automatically

If the server is on the same machine where Nightwatch is running, it can be started/stopped directly. All you need is to configure the server path in the configuration file.

Running Selenium Manually

To run the Selenium Server manually, you can run the command

java -jar selenium-server-standalone-{VERSION}.jar

Configuration

The Nightwatch test runner expects a configuration file to be passed, using by default a nightwatch.json file from the current directory. A nightwatch.conf.js will also be loaded by default if found. But by precedence, nightwatch.conf.js will be loaded by default if both the configuration files are found to be present within the current directory.

This is how the basic configuration looks for Nightwatch:

{
  "src_folders" : ["tests"],
  "output_folder" : "reports",
  "live_output" : true,

  "selenium" : {
   "start_process" : true,
   "server_path" : "lib/selenium-server-standalone-3.0.0.jar",
   "log_path" : "logs",
   "port" : 4444,
   "cli_args" : {
    "webdriver.chrome.driver" : "bin/chromedriver",
    "webdriver.gecko.driver": "bin/geckodriver"
   }
}

Basic Settings

Name Description
src_folders An array of folders where the logic for automation is implemented.
output_folder The location where JUNIT XML files report files will be saved.
globals_path Location of an external global module which will be loaded and made available to the test as globals on the client side.
Globals can also be defined/overwritten inside a test_settings environment.
Selenium An object containing Selenium Server related configuration options.
test_settings This object contains all the test related options
live_output This option is mainly used to buffer the output in case of running parallel tests.
test_runner Specifies which test runner to use when running the tests. Values can be either default (built in Nightwatch runner) or mocha

Selenium Settings

The Selenium settings are important if you ought to execute the test scenarios in different browsers. The Selenium settings object will help in starting the browser automatically and take care of executing the required browser drivers when required.

Name Description
start_process Use to start the Selenium server automatically.
server_path Relative path to the Selenium Server in the system.
log_path The location where the Selenium output.log fill will be placed. Defaults to the current directory. To disable Selenium logging, set this to false.
port The port to which Selenium server is listening to. By default, it is 4444.
cli_args List the CLI arguments to be passed to the Selenium process. Here you can set the various browser drivers, such as GeckoChromeDriver etc.

The Selenium settings look something like this in the Nightwatch.json configuration file:

"selenium" : {
   "start_process" : true,
   "server_path" : "lib/selenium-server-standalone-3.0.0.jar",
   "log_path" : "logs",
   "port" : 4444,
   "cli_args" : {
    "webdriver.chrome.driver" : "bin/chromedriver",
    "webdriver.gecko.driver": "bin/geckodriver"
   }
 }

Test Settings

This is how the test_settings object would look:

"test_settings" : {
   "default" : {
    "launch_url" : "http://localhost",
    "selenium_port" : 4444,
    "selenium_host" : "localhost",
    "silent" : true,
    "screenshots" : {
     "enabled" : true,
     "path" : "screenshots",
     "on_failure" : true
    },
    "desiredCapabilities" : {
     "browserName" : "firefox",
     "marionette" : "true",
     "javascriptEnabled": true,
     "acceptSslCerts": true
    },
    "acceptSslCerts" : false,
    "use_xpath" : true
 }

Writing Tests

Using the preferred CSS selector model to locate elements on a page, Nightwatch makes it very easy to write automated End-to-End tests.

Create a separate folder for tests in your project, e.g.: tests. Each file inside it will be loaded as a test by the Nightwatch test runner. For example

'Title and Body section' : function(browser){
   browser.url('http://stage.cgu.iagdev.net/personal')
   browser.useCss().waitForElementVisible('body',2000)
   browser.assert.title('Personal Insurance - Make A Claim Online | 
   CGU Insurance')
   browser.end()
 }
Remember to always call the .end() method in order to finish executing 
the tests and that Selenium can terminate the respective browser session.

A test can have multiple steps, if needed:

Follow the codebase

module.exports = {
  'step one' : function (browser) {
    browser
      .url('http://www.google.com')
      .waitForElementVisible('body', 1000)
      .setValue('input[type=text]', 'nightwatch')
      .waitForElementVisible('button[name=btnG]', 1000)
  },

  'step two' : function (browser) {
    browser
      .click('button[name=btnG]')
      .pause(1000)
      .assert.containsText('#main', 'Night Watch')
      .end();
  }
};

Using XPath Selectors

Nightwatch also supports XPath selectors. To switch to XPath instead of CSS selectors as the locate strategy, in your test, call the function useXpath(). To switch back to CSS, call the function useCss() . Please see the example below.

this.demoTestGoogle = function (browser) {
  browser
    .useXpath() // every selector now must be xpath
    .click("//tr[@data-recordid]/span[text()='Search Text']")
    .useCss() // we're back to CSS now
    .setValue('input[type=text]', 'nightwatch')
};

BDD Expect Assertions

Nightwatch has introduced the the expect assertions library, which is a part of the Expect api from the Chai framework from version v0.7 onwards. Here is an example:

// expect element  to be present in 1000ms
client.expect.element('body').to.be.present.before(1000);

Using before[Each] and after[Each] Hooks

Nightwatch provides the standard before / after and beforeEach / afterEach hooks to be used in the tests. The before and after hooks will run before and after the test suite is executed where as beforeEach and afterEach will execute before and after each function or each test case. Here is an example:

module.exports = {
  before : function(browser) {
    console.log('Setting up...');
  },

  after : function(browser) {
    console.log('Closing down...');
  },

  beforeEach : function(browser) {

  },

  afterEach : function() {

  },

  'step one' : function (browser) {
    browser
     // ...
  },

  'step two' : function (browser) {
    browser
    // ...
      .end();
  }
};

Using Asynchronous before[Each] and after[Each] hooks

All the before[Each] and after[Each] methods can also perform asynchronous operations, in which case they will require the callback passed as the second argument. Here is an example:

module.exports = {
  beforeEach: function(browser, done) {
    // performing an async operation
    setTimeout(function() {
      // finished async duties
      done();
    }, 100);
  },

  afterEach: function(browser, done) {
    // performing an async operation
    setTimeout(function() {
      // finished async duties
      done();
    }, 200);
  }
};

Controlling the done Invocation Timeout

By default, the done invocation timeout is set to 10 seconds (2 seconds for unit tests). In some cases, this might not be sufficient and to avoid a timeout error, you can increase this timeout by defining an asyncHookTimeoutproperty (in milliseconds) in your external globals file.

Explicitly Failing the Test

Failing the test intentionally in a test hook is achievable by simply calling done with an Error argument:


module.exports = {
  afterEach: function(browser, done) {
    // performing an async operation
    performAsync(function(err) {
      if (err) {
        done(err);
      }
      // ...
    });
  }
};

How to Run Your Test Cases Using Nightwatch

The following test cases or test suites can be executed using Nightwatch using the following command nightwatch --test tests/demotest.js where demotest.js is the required js file.

Test Reports Generated

By default, the test reports generated by Nightwatch are in XML format. If you want your reports to be generated in HTML format, install the library nightwatch-html-reporter using the command npm install -g nightwatch-html-reporter. Now all you need to do is run the command nightwatch-html-reporter -d and this library will generate you the HTML report for the corresponding XML report in your Nightwatch report directory. For further information on nightwatch-html-reporter, follow this link.

To further understand Nightwatch, here is my code base in GitHub. You can have a look in my GitHub repo.

The DevOps Zone is brought to you in partnership with Sonatype Nexus.  See how the Nexus platform infuses precise open source component intelligence into the DevOps pipeline early, everywhere, and at scale. Read how in this ebook

Topics:
devops ,nightwatch ,test automation ,browser testing

Published at DZone with permission of Soumyajit Basu. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}