How to automate tests for your website using Nightwatch.js ? - Part 1- Setting up nightwatch
Tags: testing, nightwatch, javascript, qa
Published: 2021-12-03 12:45:47

Testing is an essential part of any software project, it helps you ensure that your product has the best quality and  avoid regressions. Manual testing can be effective but, it's time-consuming and has less test coverage. Automated testing, on the other hand, can provide a wide range of coverage in less amount of time and is very applicable for large-scale projects with lots of functionality. In this blog, we're going to write end to end tests for a simple `todo` app using  `Nightwatch.js`

Powered by Node.js, Nightwatch.js is an open-source end-to-end test automation tool for web-based applications, browser applications, and websites. For further information and guide in Nightwatch.js, you can visit their [official website](https://nightwatchjs.org/) 


In this blog, we are going to follow Behaviour Driven Development(BDD) approach, if you don't know what it means or want to learn more about it you can read these blogs
- [The beginner's guide to BDD](https://inviqa.com/blog/bdd-guide)
- [Behaviour-Driven Development](https://cucumber.io/docs/bdd/)
- [Introducing BDD](https://dannorth.net/introducing-bdd/)

## Prerequisites
*Note: The commands and setup is Ubuntu-specific*
1. Node.js installed - `sudo apt install nodejs`
2. We will be using docker to run the selenium server so you need to set up docker. You can setup docker in ubuntu with the help of this [blog](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04)
3. If you don't want to set up docker, alternatively you can run selenium in the following ways, but I highly recommend using docker and this blog will be more focused on running selenium via docker.
 - install java `sudo apt install default-jdk`
 - [Download](https://www.selenium.dev/downloads/) the latest 
   stable version of selenium server.
 - [Download](https://chromedriver.chromium.org/) the latest 
   stable version of chrome driver
 - Unzip the chromedriver `unzip <name-of-zip-file>`
 - Once the file is unzipped you need to place both `selenium 
   server` and `chromedriver` in the same folder.

## Setting up Nightwatch
For this blog we are going to use a simple react todo app, you can clone it from [github](https://github.com/SwikritiT/todo) or if you have your own project you can follow this blog to set up tests there too.

- Go inside your project and install `nightwatch,nightwatch-api and cucumber`

  ```
    npm install --dev nightwatch-api nightwatch @cucumber/cucumber 
  ```
- Install `selenium-server`, `chromedriver` . If you're not using docker and using external `selenium-server` and `chrome-driver` you can opt-out of this step.
```
npm install selenium-server --save-dev  
npm install chromedriver --save-dev    
```

After this, your `package.json` should look something like this (versions may vary).
```
 "devDependencies": {
    "@cucumber/cucumber": "^8.0.0-rc.1",
    "chromedriver": "^96.0.0",
    "nightwatch": "^1.7.12",
    "nightwatch-api": "^3.0.2",
    "selenium-server": "^3.141.59"
  }
```

- In the `root` level create a folder `tests`. Our folder structure will look something like this. I'll explain more about it later.
```
tests
 ┗ acceptance
 ┃ ┣ feature
 ┃ ┃ ┗ todo.feature
 ┃ ┣ stepDefinitions
 ┃ ┃ ┗ todoContext.js
 ┃ ┗ cucumber.conf.js
```
- Create a file named `nightwatch.conf.js` in the root level. In this file we will be adding our configuration. You can configure it as you like by consulting the official documentation of [nightwatch](https://nightwatchjs.org/guide/configuration/overview.html) or you can use the configuration below
```
const LAUNCH_URL = process.env.LAUNCH_URL || 'http://localhost:3000';
module.exports = {
    src_folders : ['tests'],
    test_settings: {
        default: {
            launch_url: LAUNCH_URL,
            globals: {},
            selenium: {
                start_process: false,
                host: 'localhost',
                port: 4444,
            },
            desiredCapabilities: {
                browserName: 'chrome',
            },
        },
    },
};

```
Here `LAUNCH_URL` is the index URL of your project, in our case
`localhost:3000`, you can pass this as an environment variable too. We need to specify `src_folders` which is the folder where your tests reside, in our case `tests`.

If you're not using docker you can use the following configuration:
```
const LAUNCH_URL = process.env.LAUNCH_URL || 'http://localhost:3000';
module.exports = {
    src_folders: ['tests'],
    test_settings: {
        default: {
            selenium_host: '127.0.0.1',
            launch_url: LAUNCH_URL,
            globals: {},
            desiredCapabilities: {
                browserName: 'chrome',
                javascriptEnabled: true,
                chromeOptions: {
                    args: ['disable-gpu'],
                    w3c: false
                }
            }
        }
    }
}
```
- Create `cucumber.conf.js` file inside the `tests/acceptance` folder and add the following configuration
```
const {setDefaultTimeout, BeforeAll, Before, AfterAll, After} = require('@cucumber/cucumber')
const {startWebDriver, stopWebDriver, createSession, closeSession} = require('nightwatch-api')

setDefaultTimeout(60000)

BeforeAll(async function (){
    await startWebDriver({})
})

Before((async function(){
    await createSession({})
}))

AfterAll(async function(){
    await stopWebDriver()
})

After(async function(){
    await closeSession()
})

```
In this file, we specify before and after hooks that will run before and after every test scenario.

We are done setting up `nightwatch.js`. In the next blog, we will learn how to write tests, run selenium server, and run tests.