What is Nightwatch.js?
Contents
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 browser (End-to-End) testing solution which aims to simplify the process of setting up a Continuous Integration and writing automated tests. nightwatch.js can also be used to write Node.js unit tests. nightwatch.js gives the flexibility of using javascript to automate the required scenarios similar to using WebDriver.
Mode of operation
nightwatch.js 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.js work flow.
nightwatch.js 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.js in your system.
- To install nightwatch respective to your project or within your project directory, just run this 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 like 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 are 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 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 Gecko , ChromeDriver etc. |
The Selenium settings looks 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
Below are a number of settings that will be passed to the Nightwatch instance. You can define multiple sections (environments) of test settings so you could overwrite specific values per environment.
A "default" environment is required. All the other environments are
inheriting from default and can overwrite settings as needed.
Name | Description |
launch_url | A url which can be used later in the tests as the main url to load. Can be useful if your tests will run on different environments, each one with a different url. |
selnium_host | The hostname/IP on which the selenium server is accepting connections. |
selenium_port | The port number on which the selenium server is accepting connections. The port number by default is 4444 . |
Silent | Whether to show extended Selenium logs |
Screenshots | Selenium generates screenshots when command errors occur. With on_failure set to true, also generates screenshots for failing or errors caused by tests. These are saved on the disk. |
desiredCapabilities | An object which will be passed to the Selenium WebDriver when a new session will be created. You can specify browser name for instance along with other capabilities. |
use_xpath | Use xpath as the default locator strategy |
output_folder | Define the location where the JUnit XML report files will be saved. This will overwrite any value defined in the Basic Settings section. If you’d like to disable the reports completely inside a specific environment, set this to false . |
This is how the test_settings
object would look like
"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('https://stage.cgu.iagdev.net/personal browser.useCss().waitForElementVisible('body',2000) browser.assert.title('Personalurance - 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 supports xpath selectors also. 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 as 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.
The done
function must be called as the last step when the async operation completes. Not calling it will result in a timeout error.
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 asyncHookTimeout
property (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.JS
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. Now 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 the link
https://github.com/jls/nightwatch-html-reporter
To further understand nightwatch here is my code base in GitHub. You can have a look in my GitHub repo.
I hope i am able to give best nightwatch js tutorial. Kindly provide your comments
Soumyajit is 5+ years experienced Software professional with his prime focus on automation technologies based on quality development and takes interest in the CI/CD processes. He provides help in developing the QA process in an organization with his skills in automation for the web platform. His focus is on improving the delivery process for an ongoing project and connects the dot to help out with a successful deployment. He has experience in working on analytics, e-commerce, and the ad-tech domain.
Besides being a professional he takes an immense interest in learning new skills and technologies. He is a research guide author/writer at Dzone and Web Code Geeks. He also maintains a blog platform of his own where he likes to keep up his technology junks.