author-pic

Dikshita Shirodkar

Structure Nightwatch.js and perform execution within Docker


Published on July 21, 2021

My last post talked about How to build Docker Image for ubuntu 20.04. Now it's time to dive into structuring Nightwatch.js and executing the tests within Docker container.

Introduction to Nightwatch.js?

Nightwatch.js is a popular framework which can be integrated and easy to use E2E testing solution for web applications and websites, which uses javascript and W3C webdriver API.

Why Nightwatch.js?

Nightwatch offers different advantages out of various tools available in the market, like:


1. NightwatchJS API's are much faster than any automation tool
2. Built-in test runners
3. Continuous integration
4. Easy to extend, allows you to write my own custom commands and assertions
5. Chain of commands
6. Light weight
7. Nightwatch JS is built on Node.js, it has some major advantages over any other Selenium automation testing tool

Installation of Nightwatch.js

Note: Before we start installing the Nightwatch.js related packages, make sure we install the npm tool, which is the node package manager.


Step 1. Initialize the project, by running command:

npm init


Step 2. Install nightwatch

npm install nightwatch --save -dev

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 needs to be present in the root directory.

Also, add a new script to your package.json, to run your e2e test:

{
  "scripts": {
    "test": "nightwatch"
  }
}


Step 3. Install chromediver

npm install i chromedriver --save -dev


Step 4. Now, lets update nightwatch.conf.js file in the root structure to:

module.exports = {
  src_folders: ["tests"],
  page_objects_path: ["page-objects"],

  webdriver: {
    start_process: true,
    server_path: "node_modules/.bin/chromedriver",
    port: 9515,
  },

  // Will take screenshots on any test failures
  test_settings: {
    default: {
      screenshots: {
        enabled: true,
        path: "tests_output/screenshots",
        on_failure: true,
      },

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

Note: For more details w.r.t nightwatch.conf.js you can refer to this link. for adding adiditional configurations.

As you see above, we have defined couple of configuration within nightwatch.conf.js. Let's create the folders structure respective to the configuration in the root

test-NightwatchJS
│
└───page-objects
│   │   gitPage.js
│   │
└───tests
│   │  git.js
│
└───tests_output
│   │
│   └───screenshots
│       │   img1.png

Let's write our first test using Nightwatch.js


1. Add below code inside gitPage.js

const { browser } = require("nightwatch")

module.exports = {
  elements: {
    email: "#user_email",
    heading: {
      selector:
        '//h1[@class="h1-mktg color-text-white mb-3 position-relative z-2"]',
      locateStrategy: "xpath",
    },
  },
  commands: [
    {
      openUrl() {
        return this.api.url("https://github.com/")
      },
      setEmail(email) {
        return this.assert
          .visible("@email", "Email field is displayed")
          .click("@email")
          .setValue("@email", email)
      },
      verifyHeading(expectedText) {
        return this.assert
          .visible("@heading", "heading is displayed")
          .getText("@heading", function(result) {
            this.assert.equal(result.value, expectedText)
          })
      },
    },
  ],
}

This is basically is a simple test to open the url and enter the email in the email Box and finally match the heading of the page using assertions.


2. Add below tests within gitLogin.js

const { browser } = require("nightwatch")

module.exports = {
  "First test execution": function(browser) {
    const git = browser.page.gitPage()

    git
      .openUrl()
      .page.gitPage()
      .setEmail("hello")
  },

  "Second test execution": function(browser) {
    const git = browser.page.gitPage()

    git.verifyHeading("Where the world builds software")
  },
}

Here, we are calling the functions defined in the gitPage.js and passing the necessary arguments.


3. Finally, execute the test:

npm run nightwatch

$  test-NightwatchJS npm test

> test-nightwatchjs@1.0.0 test /Users/WORK/test-NightwatchJS
> nightwatch


[Git Test] Test Suite
=====================
ℹ Connected to localhost on port 9515 (2048ms).
  Using: chrome (91.0.4472.114) on Mac OS X platform.

✔ Running First test execution:

✔ Email field is displayed (64ms)

OK. 1 assertions passed. (3.524s)
✔ Running Second test execution:

✔ heading is displayed (24ms)
✔ Passed [equal]: Where the world builds software == Where the world builds software

OK. 2 assertions passed. (59ms)

OK. 3  total assertions passed (6.176s)

Voila 😎, you just execute your first e2e test using Nightwatch.js

Why tests?

There should be some gap between development and production for testing, so that we avoid suprises like issues during a deployment which can be due to rushy fix pushed, dropping the quality for the end users. Another main reason to run tests is because it imitate's the actual user's behavior using the site.

Why Execute within Docker?

We have a main challenge to maintain and test the stability of our test. Hence we reqiure a environment close to production. Since we develop the automations scripts on our machine, but the end goal is to run the scripts on the production environment whose configuration could be different from yours. This is when we see error occuring in our test scripts, so to avoid and eliminate such last minute suprises, which can take ample amount of time, we need a environment with similar configuration like Prod.

That's where Docker comes into picture, solving all the problems. Docker creates a isolated world (containerized) with all the external configurations, required to build the environment.

Setting up Docker with Nightwatch.js

As we learnt in the previous blog to create and access a container (Ubuntu 20.04 machine) using docker.compose.yaml. We will following the same steps to access that existing container.

Now install the dependencies required for NightwatchJS setup in the container. I have tried to minimize the human effort by adding all the require dependencies in a shell file, executing this shell file, will automatically install all the dependecies within that container.

This file also includes instruction to install application level dependencies: such as navigating to the Nightwatch directory, installing the packages of Nightwatch and running of the e2e tests.

#!/bin/bash

## Installing environment level dependencies
apt update
DEBIAN_FRONTEND=noninteractive apt install npm -y
apt install curl
curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install v14.17.0
nvm use v14.17.0
apt install vim
apt install wget -y
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb -P /tmp
apt install /tmp/google-chrome-stable_current_amd64.deb

## Installing application level dependencies
cd /root/test-NightwatchJS # Navigate to the nightwatch folder structure
npm install # Install nightwatch related dependencies
npm run test # Run the nightwatch tests
/bin/bash

Thanks for reading! 🙂

Share on Twitter