DEV Community

Cover image for Nightwatch.js Tutorial For Test Automation Beginners – With Examples
ramitd1995
ramitd1995

Posted on • Originally published at lambdatest.com

Nightwatch.js Tutorial For Test Automation Beginners – With Examples

Selenium is a widely used tool for automated browser testing. Being an open-source framework allowed Selenium to be compatible with multiple test automation frameworks for different programming languages and if we talk about Automation testing with Selenium and JavaScript, there is a particular framework that never fails to take the spotlight and that is the Nightwatch.js. This is why I decided to come up with Nightwatch.js tutorial for beginners.

In this blog post, we will deep dive into a step by step Nightwatch JS tutorial to perform testing with Selenium and JavaScript for automated browser testing. We will explore how we can install and setup Nightwatch JS and look into details about its configuration and the important files and folder structure. Later we will also look at executing our first Nightwatch.js test automation script and what are some of the issues that we might encounter, along with their resolutions. Let’s kickstart this Nightwatch.js tutorial for beginners with a basic introduction.

What Is Nightwatch.js?

Powered by Node.js, Nightwatch.js is an open-source automated testing framework that aims at providing complete E2E (end to end) solutions to automate testing with Selenium Javascript for web-based applications, browser applications, and websites. This framework relies on Selenium and provides several commands and assertions within the framework to perform operations on the DOM elements. It internally uses the powerful W3C WebDriver API or the Selenium WebDriver and simplifies writing end to end automated tests in Node.js and effortlessly sets up for Continuous Integration.

Why Nightwatch.js Is So Popular?

Before we deep dive to executing test scripts in this Nightwatch.js tutorial for beginners. It is important to understand the reasons behind the popularity of Nightwatch.js. Nightwatch.js facilitates an end to end functional browser testing in a pure node.js environment which enables testing of web applications independent from third party software. The key purpose of lightweight and robust automated testing frameworks such as Nightwatch.js is to enable a single integrated solution for application testing. Since Nightwatch JS is built on Node.js, it has some major advantages over any other Selenium automation testing tool. This automated browser testing powered by Nightwatch.js eliminates the dependency factor upon third party software consequently enhancing data integrity among diverse system components.

Nightwatch JS provides the following out of the box features:

➝   In Built Test Runner: It comes with an inbuilt command-line test runner suite with Grunt support for executing the automated tests.

➝   Test Strategy: It has the feature to execute the tests efficiently and can be performed in many ways such as parallelly, sequentially or in groups, and tags.

➝   Cloud Services: A good support for Cross Browser Testing with Selenium JavaScript by providing integration with the cloud-based Selenium testing providers like LambdaTest.

➝   Selenium Server: Ability to automatically control the standalone Selenium server with JUnit XML reporting built in.

➝   Assertions, CSS, and XPath: Several commands and assertions for DOM operations, CSS and XPath selectors and can be used to identify the elements on the page. This makes the framework flexible and easy to extend especially while implementing the application-specific commands and assertions.

➝   Continuous Integration: It offers good support for Continuous Integration and hence can be used to integrate the tests with the continuous build processing systems such as Jenkins, TeamCity, etc. and assist developers in building and testing software continuously.

Apart from all the above features that it provides, it is popular for having a clean and easy syntax, making it easier to write the tests efficiently and quickly by only making use of Node.js CSS selectors and XPath locator in Selenium

How does Nightwatch JS works?

Nightwatch communicates over a restful API protocol that is defined by the W3C WebDriver API. It needs a restful HTTP API with a Selenium JavaScript WebDriver server.

In order to perform any operation i.e. either a command or assertion, Nightwatch usually requires sending a minimum of two requests. It works as follows:

  • The first request locates the required element with the given XPath expression or CSS selector.
  • The second request takes the element and performs the actual operation of command or assertion.

Installation and Prerequisites For Nightwatch.js

There are some basic prerequisites that are required to get started with this Nightwatch JS tutorial for testing with Selenium and JavaScript.

  • Node.js: Nightwatch module is built on top of a Node.js, it indicates that Node.js is required to be installed on the system.
  • Node Package Manager (npm): Once Node.js installed , the node’s package manager i.e. npm can be leveraged to install the package which is the largest ecosystem of packages. Now, to install the latest version using the npm command line tool, the below command is executed (here ‘g’ is for installing globally):
$ npm install -g nightwatch

The below command will place the Nightwatch executable (‘–save-dev’) in our ./node_modules/.bin folder

$ npm install --save-dev nightwatch
  • Java – SDK: Selenium requires Java for its remote Selenium Server. Since Nightwatch relies upon the Selenium WebDriver API and also requires a Selenium WebDriver Server, hence there is also a need to install the Java Development Kit (JDK 7+) on the system and configure the JAVA environment.
  • Selenium Server: It requires a Selenium standalone server package JAR which can be downloaded from the Selenium downloads page. Once downloaded, it needs to be placed in the bin folder of the project and the selenium server can be started using the command:

selenium-server-standalone-{version}.jar
  • Chrome Driver: Lastly, it requires a Chrome Driver, which is a standalone server that implements the W3C Web Driver wire protocol for Chromium. This executable also needs to be placed inside the same bin folder.
$ npm install --save-dev chromedriver</pre>

Configuring and Setting up Nightwatch.js

Now, that we have covered the basics in detail, it is now time to deep dive in automation testing with Selenium and JavaScript through this Nightwatch.js tutorial for beginners. Nightwatch.js offers an in-built test runner which expects a JSON configuration file to be passed. The default configuration file is nightwatch.json which should be present in the project’s root directory. Alternatively, the nightwatch.conf.js configuration file can also be used and will be loaded from the root directory of the project.

Note: If both the configuration files are present in the directory, the nightwatch.conf.js is given precedence as it provides us with a little more flexibility and can have comments in the file.

You can even declare specific test details under this configuration file such as test environments, Selenium specific settings, etc. This is how a nightwatch.json configuration file looks like for testing with Selenium and JavaScript.

{
  "src_folders" : ["tests"],
  "output_folder" : "reports",
  "custom_commands_path" : "",
  "custom_assertions_path" : "",
  "page_objects_path" : "",
  "globals_path" : "",
  "test_workers": {
    "enabled": true,
    "workers": "auto"
  },
  "selenium" : {
    "start_process" : true,
    "server_path" : "node_modules/selenium-standalone/.selenium/selenium-server/",
    "log_path" : "./reports",
    "host": "127.0.0.1",
    "port" : 4444,
    "cli_args" : {
      "webdriver.chrome.driver" : "",
      "webdriver.gecko.driver" : "",
      "webdriver.edge.driver" : ""
    }
  },

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

    "chrome" : {
      "desiredCapabilities": {
        "browserName": "chrome"
      }
    },

    "edge" : {
      "desiredCapabilities": {
        "browserName": "MicrosoftEdge"
      }
    }
  }
}

Let us have a close look at the structure of the nightwatch.json configuration file.

  • src_folders: This is directory indicates the location that contains the test suites
  • output_folder: This is directory indicates the location that contains and saves the test reports i.e. JUnit report files, XML reports, test logs, selenium log, screenshots, video logs, network logs, etc.
  • globals_path: This indicates the file path where all the global parameters used in the test suite are initialized. These are loaded and presented to the tests as a global property and can also be modified inside a test_settings environment.
  • test_workers: This property defines whether or not we want to run the test suites in parallel. If enabled is set to true it indicates that parallelization is allowed for the testing strategy.
  • page_objects_path: This indicates the location where the page object file is supposed to be loaded from.
  • selenium: This contains all the information and customization related to Selenium Server configuration. It additionally contains the server_path and webdriver.chrome.driver which indicates the path to the selenium server and the chrome driver respectively. Also, if the start_process parameter is set to true it points out the Selenium Server to start automatically.
  • test_settings: This contains all the important information related to tests and options to configure them. It allows us to define and customize the test environments.

Execution of The First Script on A Local Selenium WebDriver Setup

We will start the automation testing in Nightwatch.js tutorial for beginners with an example where the test script that we are going to execute will search Nightwatch on Google and then check the Nightwatch JS documentation on the website.

module.exports = {
  'NW test on Google' : function (client) {
    client
      .url('http://www.google.com')
      .waitForElementVisible('body', 1000)
      .assert.title('Google')
      .assert.visible('input[type=text]')
      .setValue('input[type=text]', 'Nightwatch JS')
      .waitForElementVisible('button[name=btnG]', 1000)
      .click('button[name=btnG]')
      .pause(1000)
      .assert.containsText('ol#rso li:first-child',
        'Nightwatch.js | Node.js powered End-to-End testing framework')
      .end()
  }
}

We are free to modify the nightwatch.json configuration file and the global module file i.e nightwatch.globals.js as per our needs but it should look something similar to the below file.

{
  "src_folders" : ["./tests"],
  "output_folder" : "./reports",
  "globals_path" : "nightwatch.globals.js",
  "test_workers": {
    "enabled": true,
    "workers": "auto"
  },
  "selenium" : {
    "start_process" : true,
    "server_path" : "./node_modules/selenium-server-standalone-jar/jar/selenium-server-standalone-3.141.59.jar",
    "log_path" : "nw/logs",
    "host" : "127.0.0.1",
    "port" : 4444,
    "cli_args" : {
      "webdriver.chrome.driver" : "./node_modules/chromedriver/bin/chromedriver",
      "webdriver.ie.driver" : ""
    }
  },
  "test_settings" : {
    "default" : {
      "launch_url" : "http://google.com",
      "selenium_port"  : 4444,
      "selenium_host"  : "localhost",
      "silent": true,
      "screenshots" : {
        "enabled" : true,
        "path" : ""
      },
      "desiredCapabilities": {
        "browserName": "chrome",
        "javascriptEnabled": true,
        "acceptSslCerts": true
      }
    },
    "french" : {
      "launch_url" : "http://google.fr",
      "desiredCapabilities": {
        "browserName": "firefox",
        "javascriptEnabled": true,
        "acceptSslCerts": true
      }
    }
  }
}

It is important to add the below section in the package.json file to execute the tests folder

scripts": {
    "test": "./node_modules/.bin/nightwatch -e firefox,edge,safari test"
  },

The final thing we are required to do is to execute the tests from the base directory of the project using the command:

npm test

This command with validate the tests and dependencies and then execute the test suite, which will open up Chrome and then Google the given search string. Below is a screenshot of the test execution that shows up the search result on Google.

nightwatch_js

Parallel Testing With Nightwatch.js In Local Selenium WebDriver

We have made our configuration to execute the tests in parallel by enabling the test_workers to true. So, we are just required to add one new test in the test folder and the framework will execute both the test in parallel.

The second test will search Node.js on google and check out the Node.js documentation.

module.exports = {
  'NJS test on Google' : function (client) {
    client
      .url('http://www.google.com')
      .waitForElementVisible('body', 1000)
      .assert.title('Google')
      .assert.visible('input[type=text]')
      .setValue('input[type=text]', 'node.js')
      .waitForElementVisible('button[name=btnG]', 1000)
      .click('button[name=btnG]')
      .pause(1000)
      .assert.containsText('ol#rso li:first-child',
        'Node.js')
      .end()
  }
}

Now we will observe that two different tests will be executed at the same time in two different Chrome browsers. Below is a screenshot of the test execution that shows up the search result on Google.

Picture1

Challenges Around Infrastructure Structure Setup for Automated Testing

Selenium leads the market in web automation testing by offering great support for testing frameworks and automated browser testing. On the contrary, there are some pain points that an automation tester may encounter while leveraging Selenium JavaScript testing using an in-house Selenium infrastructure.

Test Coverage During Cross Browser Testing

When we perform cross browser testing on our in-house hosted web application setup, we tend to eliminate any of the issues with the user interface and are able to make certain changes if required and then migrate the code in live setup for web traffic. All this is fine, but one concern that arises is the test coverage. This is mainly because the testing can only be performed on the browsers that are installed locally in the system. There is a need to perform the test on all the important browsers for successful cross browser testing. Sometimes, testing on some old browsers or browser versions is also required for a specific set of users and operating systems. So you need to test over different combinations of browsers and operating systems, and that is not feasible with a local inhouse Selenium infrastructure.

Cost Incurred During Local Infrastructure Setup

There is always an infrastructure cost when performing certain automated tests and when having a local in-house selenium setup.

  • There is a need to configure a separate test environment to execute all the test cases.
  • Different types of devices such as desktop, mobile, tablets, etc. are required and should be a part of the test strategy.
  • A device lab setup with has all the required devices can also be invested in but this is not a good choice for startups or small scale organizations as they may refrain from huge invested initially.
  • As an automated test may increase in number during the testing phase, hence it requires the system to be scalable enough to handle this scenario.

Alternatively, a virtual machine or simulator can be used to perform automation testing in a local setup for hosted web-applications, but these again require proper maintenance, impacts system performance and are time-consuming.

Why Cloud-Based Selenium Grid Is A Good Call to Make?

When it comes to automated browser testing then cloud-based Selenium Grid is a good call. A cloud-based infrastructure will help you with access to hundreds of browsers + operating system combinations, hosted on the provider’s cloud server. That way, you can be free from the hassle of maintaining your Selenium Grid as you get to run your test with zero-downtime. Another benefit of using a testing cloud is that it provides an adaptive environment that is already set up with frameworks so that the users can execute the tests using any framework of their choice as per the requirement.

Also, The testing cloud is highly scalable and provides us the privilege to use the infrastructure as per needed to run any number of tests in parallel or at the same time. Hence, when adopting a cloud testing strategy there is just a need to modify your test scripts, but the infrastructure setup used to execute the tests remains the same.

Which Cloud-Based Selenium Grid Should You Go For?

LambdaTest is trusted by 100,000 companies throughout the globe as a reliable online Selenium Grid provider to fulfill their cross browser testing needs.Using LambdaTest, you can perform both automated browser testing with a cloud-based Selenium Grid of 2000+ real browsers for both mobile and desktop to help you gain the maximum test coverage during the automated browser testing.

Our Selenium Grid allows you to execute automation test scripts in Selenium on various programming platforms such as Java, JavaScript, PHP, Python, Ruby, C# and other languages that provide bindings with Selenium.

You can also choose to integrate with a variety of CI/CD tools such as Jenkins, Travis CI, and more for continuous testing in DevOps.

You can even leverage parallel testing with Selenium automation testing, along with our open Selenium API to help you extract test reports of your Selenium script execution over LambdaTest, in an effortless manner. Let us try and execute the above test case using the remote WebDriver for LambdaTest Selenium Grid.

Execute Nightwatch.js Script Using Remote Selenium Grid

Executing test scripts on the LambdaTest Selenium Grid with Nightwatch.js is pretty simple and straightforward and will be the focus of further sections in this Nightwatch.js tutorial for automation testing with Selenium and JavaScript. we can use our existing local test script and configuration files by changing a few lines of code. To begin first we would need to invoke Selenium remote Webdriver instead of our previous local browser web driver. Also, since now we are using a remote web driver with LambdaTest, we have the flexibility to define the browser environment where we would want to execute our tests. We can do that by passing browser and environment details to the LambdaTest Selenium grid via the desired capabilities class. LambdaTest provides us with the Capabilities Generator to select and pass the browser details and environment specifications with various combinations to choose from.

lambdatest_desired_capability

Visit LambdaTest Selenium Desired Capabilities Generator

So, in our case the desiredCapabilities class in nightwatch.json configuration file will look similar as below:


"desiredCapabilities": {
        "build" : "Nightwatch-Selenium-Test",
        "name" : "Nightwatch-Selenium-Test",
        "platform" : "Windows 10",
        "browserName" : "Firefox",
        "version" : "71.0",
        "selenium_version" : "3.4.0",
        "geoLocation" : "IN"
    }

Next, we would also need to generate our access key token which is like a secret key to connect to our platform and execute the tests on LambdaTest. This access key is unique and can be copied or regenerated from the profile section of our account.

Alternatively, we can also get the access key, username and hub details from the Automation dashboard as well.

lambdatest-tunnel

Below is the nightwatch.conf.js file where we need to declare the user configuration for an access key, username, host, and port for the test.

module.exports = (function(settings) {
  console.log(settings["test_settings"]["default"]["username"])
  if (process.env.LT_USERNAME) {
    settings["test_settings"]["default"]["username"] = process.env.LT_USERNAME;
  }
  if (process.env.LT_ACCESS_KEY) {
    settings["test_settings"]["default"]["access_key"] = process.env.LT_ACCESS_KEY;
  }
  if (process.env.SELENIUM_HOST) {
    settings.selenium.host = process.env.SELENIUM_HOST;
  }
  if (process.env.SELENIUM_PORT) {
    settings.selenium.host = process.env.SELENIUM_PORT;
  }
  return settings;
})(require('./nightwatch.json'));

Now, since we are using LambdaTest, we would like to leverage it and execute our tests on different browsers and operating systems. Here, we would be using three different browsers i.e, Microsoft Edge, Mozilla Firefox and Apple Safari and operating systems like Windows 10 and macOS 10.13.

So after making the required changes our final configuration files will look like below.

{
  "src_folders" : ["./tests"],
  "output_folder" : "./reports",
  "globals_path" : "nightwatch.globals.js",
  "test_workers": {
    "enabled": true,
    "workers": "auto"
  },
  "selenium" : {
    "start_process" : false,
    "server_path" : "",
    "log_path" : "",
    "host" : "hub.lambdatest.com",
    "port" : 80,
    "cli_args" : {
    "webdriver.chrome.driver" : "",
    "webdriver.ie.driver" : "",
    "webdriver.firefox.profile" : ""
    }
  },
  "test_settings" : {
    "default" : {
    "launch_url" : "http://google.com",
    "selenium_port"  : 80,
    "selenium_host"  : "https://lambdatest.com",
    "silent": false,
    "screenshots" : {
        "enabled" : true,
        "path" : ""
    },
    "username" : "irohitgoyal",
    "access_key" : "UZwDAcLTJQpE1Bl23n2CxBspq4NEoLouBXlORVUS3ilzinRt4k",

    "skip_testcases_on_fail": false,

    "desiredCapabilities": {
       "build":"Nightwatch-Selenium--Test",
    "platform" : "Windows 10",
    "browserName" : "Chrome",
        "version" : "78.0",
        "selenium_version" : "3.13.0",
    "visual":true,
        "video":true,
        "console":true,
        "geoLocation" : "IN",
        "chrome.driver" : "78.0",
        "network":true
    }
    },
    "chrome": {
    "desiredCapabilities": {
        "platform": "Windows 10",
        "browserName": "chrome",
        "version": "78.0"
    }
    },
    "safari" : {
    "desiredCapabilities": {
        "platform": "macos 10.13",
        "browserName": "safari",
        "version": "11.0"
    }
    },
    "firefox" : {
    "desiredCapabilities": {
        "platform": "win10",
        "browserName": "firefox",
        "version": "60"
    }
    },
    "edge" : {
    "desiredCapabilities": {
        "platform": "Windows 10",
        "browserName": "MicrosoftEdge",
        "version": "17.0"
    }
    },
    "french" : {
    "launch_url" : "http://google.fr",
    "desiredCapabilities": {
        "browserName": "firefox",
        "javascriptEnabled": true,
        "acceptSslCerts": true
    }
    }
  }
}

Now, it is important to add the below section in the scripts class as arguments in package.json file to specify the desired capabilities environments we would want our tests to execute on.

scripts": {
    "test": "./node_modules/.bin/nightwatch -e firefox,edge,safari test"
  },

The final thing we are required to do is to execute the tests from the base directory of the project using the command:

npm test

This command with validate the tests and dependencies and then execute the test suite, which will run our tests and open the Edge, Firefox and Safari browsers on the environment specified and then Google the given search string. Below we have a screenshot that shows our Nightwatch code running over different browsers using LambdaTest Selenium Grid.

Nightwatch_3

As you can notice, the script was run in parallel across Mozilla Firefox, Safari, Google Chrome, and Edge browsers. The results will be displayed on the command line interface that we used to execute the test and also will be captured in detail on the interactive LambdaTest automation dashboard. LambdaTest dashboard will help us consolidate all the details of the test and we can view all our text logs, screenshots and video recording for all our Selenium tests performed.

That Is All For This Nightwatch.js Tutorial

In this Nightwatch.js tutorial for beginners, we have covered various aspects of automation testing with Selenium Javascript. We are now clear about the approach for an end to end automation testing with Selenium JavaScript using Nightwatch.js. We are aware of all the prerequisites required for setting up Nightwatch.js. It automates the entire test suite quickly with minimal configuration and is readable as well as easy to update. The best feature provided by Nightwatch.js framework is the parallel testing of cases that proves to be time-efficient. The test results can directly be read from the terminal and also stored at a specified output folder.

At an initial stage, adopting a new approach for automated browser testing becomes stumbling blocks for many but using cloud platforms such as LambdaTest makes the process easier and allows us to leverage the full benefits of Selenium automation testing. How was this Nightwatch.js tutorial for you? Let me know in the comment section below. Happy testing!

Top comments (1)

Collapse
 
otomer profile image
Tomer Ovadia

Thank you @ramitd1995 , that's a nice tutorial!
Felt like also promoting another great tutorial I went through (dev.to/aberonni/end-to-end-testing...) and helped with my first steps with Nightwatch, it does simplify the installation process and explains few more important concepts such as Page Objects, Debugging, CI, Remote Testing and Visual Regression