E2E Testing with Nightwatch: Part One
Introduction
Welcome to E2E Testing with Nightwatch, Part One. In this part of the tutorial, I'll be focusing on the basics of Nightwatch and setting up the test environment.
You can find the source code to this tutorial here.
What is Nightwatch?
Nightwatch.js is an automated testing framework for web applications and websites, written in Node.js and using the W3C WebDriver API (formerly Selenium WebDriver).
It's a complete browser (End-to-End) testing solution that aims to simplify the process of setting up Continuous Integration and writing automated tests. Nightwatch can also be used for writing Node.js unit tests.
Why Nightwatch?
- Clean syntax:
Simple but powerful syntax enables you to write tests very quickly, using only JavaScript (Node.js) and CSS or Xpath selectors. - Built-in test runner:
Built-in command-line test runner can run the tests either sequentially or in parallel, together, by group, tags, or single. Grunt support is built-in. - Selenium server:
Controls the Selenium standalone server automatically in a separate child process — can be disabled if Selenium runs on another host. - Cloud services support:
Works with cloud testing providers, such as SauceLabs and BrowserStack. - CSS & Xpath support:
Either CSS or Xpath selectors can be used to locate and verify elements on the page or execute commands. - Continous Integration support:
JUnit XML reporting is built-in so you can integrate your tests in your build process with systems such as Teamcity, Jenkins, Hudson etc. - Easy to extend:
Flexible command and assertion framework makes it easy to extend implementation of your application specific commands and assertions.
Installation
First things first, install Node.js if you don’t have it yet. You can find the installation instructions on the Node.js project page. Once you have Node installed, you can take advantage of Node's package manager, npm, which happens to be the largest package ecosystem.
You would also be needing Java SDK if you do not already have it installed on your machine. You can download it from Oracle's site at Java SE Downloads. After installing, you would want to ensure that Java is available in your environment path. You can test this by simply typing java -version
in your terminal - this will print out the version of the installed Java on your machine.
Go to your terminal, create an empty directory, and navigate to it. Next, type npm init -y
or yarn init -y
. The -y
flag allows you to skip through the initialization questions. A package.json
file will be created at the root of the current directory.
Once you have a package.json
file, in the same directory, type npm install -g nightwatch
or yarn global add nightwatch
if you prefer yarn
. The -g
tells npm to install nightwatch
globally, which will allow you to run it in any directory.
Next, in order to be able to run the tests, we need to download the Selenium standalone server. This can be done manually from their website. For this tutorial, we'll be using npm to install it.
On your terminal, type npm install selenium-standalone --save-dev
or yarn add selenium-standalone -D
.
This command will install selenium-standalone and also save it to your package.json
file created earlier.
Modify your package.json
file by adding this "e2e-setup": "selenium-standalone install"
to the scripts
property. The package.json
should look more or less like this:
{
"name": "nightwatch",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "nightwatch",
"e2e-setup": "selenium-standalone install"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-preset-es2015": "^6.24.1",
"selenium-standalone": "^6.7.0"
}
}
Running npm run e2e-setup
or yarn run e2e-setup
on the terminal will download the latest version of selenium server, chromedriver, and geckodriver (this will be used for running tests in Chrome or Firefox browser).
Configuration
The test runner expects a configuration file to be passed, using a nightwatch.json
file from the current directory by default, if present. A nightwatch.conf.js
file will also be loaded by default, if found.
Nightwatch relies on nightwatch.json
as the configuration file for the test runs. It should be placed in the project's root directory because it specifies various configuration settings like test environments, test file paths, and selenium specific settings. This is what the configuration file looks like:
{
"src_folders" : ["tests"],
"output_folder" : "reports",
"custom_commands_path" : "",
"custom_assertions_path" : "",
"page_objects_path" : "",
"globals_path" : "",
"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"
}
}
}
}
Using both configuration files is also possible, with nightwatch.conf.js
always taking precedence if both are found.
Let's walk through the important parts of the nightwatch.json
configuration file.
src_folders
: An array of folders (excluding subfolders) where the tests are located.output_folder
: The location where the JUnit XML report files (XML reports, selenium log and screenshots) will be saved.page_objects_path
: Location(s) where page object files will be loaded from.globals_path
: Location of an external globals module which will be loaded and made available to the test as a propertyglobals
on the main client instance. Globals can also be defined/overwritten inside atest_settings
environment.selenium
: An object containing Selenium Server related configuration options. In our case, it's important to have thestart_process
set to true so that Selenium Server starts automatically. Also theserver_path
andwebdriver.chrome.driver
paths should have proper folder specified.test_settings
: This object contains all the test related options. The important bit in thedefault
environment is thedesiredCapabilities
object where we specifyfirefox
as thebrowserName
so that Nightwatch will run tests against it.
Adding ES6 to Nightwatch
In order to be able to write ES6 in Nightwatch, you need to install babel-preset-es2015
preset, babel-cli
, and add-module-exports
plugin, and add them to a .babelrc
config file.
On the terminal, type npm i babel-plugin-add-module-exports babel-preset-es2015 -D
or yarn add babel-plugin-add-module-exports babel-preset-es2015 -D
.
The .babelrc
file looks like this:
{
"presets": ["es2015"],
"plugins": [
"add-module-exports"
]
}
After doing that, you need to add a nightwatch.conf.js
file to the root of your project. The file should contain these lines:
require('babel-core/register');
const fs = require("fs");
module.exports = ((settings) => {
const seleniumServerFileName =
fs.readdirSync("node_modules/selenium-standalone/.selenium/selenium-server/");
settings.selenium.server_path += seleniumServerFileName;
return settings;
})(require("./nightwatch.json"));
Nightwatch uses the additional code to get the selenium server executable dynamically. This would override the server_path
specified in the nightwatch.json
config file.
If you prefer to use the nightwatch.json
config file to get the selenium server, remember to change this line: "server_path" : "node_modules/selenium-standalone/.selenium/selenium-server/"
in your nightwatch.json
to this: "server_path" : "node_modules/selenium-standalone/.selenium/selenium-server/x.x.x-server.jar"
where x.x.x
is the version of selenium server installed. Your nightwatch.conf.js
file should then look like this:
module.exports = ((settings) => {
return settings;
})(require("./nightwatch.json"));
Summary
In this tutorial you've learned how to:
Install Nightwatch.js and its dependencies and configure the test environment.
In the second part of the tutorial, we'll dive into writing actual tests. Part Two
Kindly hit the like button if you find this article useful.
You can find me on Twitter @codejockie