DevConf.IN 2018
End-to-End testing made easy with Nightwatch
Ratan Kulshreshtha @RatanShreshtha
Hi, I'm Ratan Kulshreshtha
- IT Developer at Telstra India
- Pythonista and Djangonaut
- Linux User
- Love Vue.js
- Rustacean
- Twitter, GitHub: @RatanShreshtha
What And Why?
- End-to-End (E2E) testing solution for browser-based apps and websites.
- Based on Node.js and selenium
What?
Why?
- Testing is crucial
- Find Bugs
- Validation & verification
- Feedback
- E2E Testing lets you test and experiences an end user the complete system
Features
- Clean Syntax
- Built-in test runner
- Selenium server
- Cloud services support
- CSS & Xpath support
- Continous integration support
- Easy to extend
Getting Started
Pre-Requisites
Installation
$ npm install [-g] nightwatch
Add -g option to make nightwatch runner available globally in your system
Selenium Server Setup
$ # For sanity check
$ java -jar selenium-server-standalone-3.13.0.jar
Configuration
Test runner expects a configuration file to be passed, by default a nightwatch.json. A nightwatch.conf.js file will also be loaded by if found.
{
"src_folders" : ["tests"],
"output_folder" : "reports",
"custom_commands_path" : "",
"custom_assertions_path" : "",
"page_objects_path" : "",
"globals_path" : "",
"selenium" : {
"start_process" : false,
"server_path" : "",
"log_path" : "",
"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
}
},
"chrome" : {
"desiredCapabilities": {
"browserName": "chrome"
}
},
"edge" : {
"desiredCapabilities": {
"browserName": "MicrosoftEdge"
}
}
}
}
Writing Your First Test
Make a file 01_hello_world.js in tests directory
module.exports = {
tags: ['hello_world'],
'Hello, World!': function(browser) {
browser
.url('http://www.google.co.in') // Go to a url
.waitForElementVisible('body', 2000) // wait till page loads
.assert.title('Google') // Make sure Site title matches
.assert.visible('input[type=text]')
.setValue('input[type=text]', 'Hello, World!') // send values
.waitForElementVisible('input[name=btnK]', 1000)
.click('input[name=btnK]') // click on search button
.pause(4000)
.assert.containsText('#main', 'Hello, World!')
.end();
}
};
$ # If Installed globally
$ nightwatch -c ./nightwatch.json --env default
$ # If Installed locally
$ ./node_modules/nightwatch/bin/nightwatch -c nightwatch.json --env default
Running nightwatch
Test Results
Commands
clearValue click deleteCookie deleteCookies end getAttribute getCookie getCookies getCssProperty getElementSize getLocation |
getLocationInView getTagName getText getTitle getValue init injectScript isVisible maximizeWindow moveToElement pause |
resizeWindow saveScreenshot setCookie setValue submitForm switchWindow urlHash waitForElementNotPresent waitForElementNotVisible waitForElementPresent waitForElementVisible |
Assertions
attributeEquals containsText cssClassPresent cssClassNotPresent cssProperty elementPresent elementNotPresent |
hidden title urlContains value valueContains visible |
Data Driven Tests
To avoid hard-coding the values create a directory named data or any other directory for storing data.
Then specify the path to that folder inside the nightwatch.json file, as the globals_path property.
No Hardcoding
module.exports = {
url: 'https://www.google.co.in/',
searchKeyword: process.env.searchKeyword || 'DevConf.In 2018',
};
Make a .js file and export all the data
{
"src_folders": ["tests"],
"output_folder": "reports",
....
....
"globals_path": "data/google",
....
....
}
nightwatch.json
Then access the data as browser.globals in your tests.
module.exports = {
tags: ['google_data_driven'],
'Google DevConf.In 2018': function(browser) {
browser
.url(browser.globals.url) // Go to a url
.waitForElementVisible('body', 2000) // wait till page loads
.assert.title('Google') // Make sure Site title matches
.saveScreenshot('screenshots/google_home_page,png')
.assert.visible('input[type=text]')
.setValue('input[type=text]', browser.globals.searchKeyword)
.waitForElementVisible('input[name=btnI]', 1000)
.click('input[name=btnI]') // click on search button
.pause(5000)
.waitForElementVisible('body', 2000)
.assert.title('DevConf.IN | August 4-5, 2018 - Bengaluru, India')
.saveScreenshot('screenshots/DevConf_IN_home_page.png')
.end();
}
};
Use the data in tests
Customisation
Custom Commands
To make custom nightwatch command create a separate folder and defining your own commands inside there, each one inside its own file.
Then specify the path to that folder inside the nightwatch.json file, as the custom_commands_path property.
Custom Assertions
Nightwatch allows you to even define your own assertions, extending the available .assert and .verify namespaces.
Make a folder where you have your custom assertions then specify the path to that folder inside the nightwatch.json file, as the custom_assertions_path property.
{
"src_folders": ["tests"],
"output_folder": "reports",
"page_objects_path": "pages",
"custom_assertions_path": "custom-assertions",
"custom_commands_path": "custom-commands",
....
....
....
....
}
nightwatch.json
Demo
Let's Pray To Demo Gods
Resources
Thank You!
Questions And Feedback
End-to-End testing made easy with Nightwatch @ DevConf.IN 2018
By Ratan Kulshreshtha
End-to-End testing made easy with Nightwatch @ DevConf.IN 2018
- 828