Nightwatch: because winter is coming…

(or more technically, a new[ish] way to write end-to-end tests)

Producing high quality software is just one thing we do here at Neosavvy, but ensuring that it STAYS high quality is another responsibility we consider when taking on a new project.

There are some great ways to keep an eye on your production and staging software environments out there. The go to these days seems to be Selenium based solutions, but at it’s core Selenium is a Java solution and 99% of client facing software is written in Javascript. It seems there are plenty of options out there these days, Capybara, Protractor, CasperJS and the list goes on.

Lately we have had a lot of interest on the team in Nightwatch which is similar in ways to some of the other libraries in that it exposes basic Selenium hooks to query a DOM by XPath or CSS selectors. The main difference I see so far is that it’s a bit easier to work with than previous Selenium hooks I have used, in that it doesn’t seem as promise based. A developer can also expose Page Objects al-la Martin Fowler circa 2013.

I want to help my colleagues get going on Nightwatch so I put together a few videos to show how to install it, some of the binaries I had to download to get selenium fired up, then a basic configuration. Finally a quick run of a simple test.

Installing nightwatch is dead simple.

npm install [-g] nightwatch

I fired up selenium in a separate tab, this seems worth doing as you will later want to run your tests in a concurrent / parallel setting so that we can run more tests faster. May as well emulate that from the start.

java -jar path/to/selenium-standalone-3.4.0.jar

If you need the binaries I found them here: http://www.seleniumhq.org/download/

Configuring Nigthwatch can be quite advanced, but I found the parameters below to be most useful for my needs.

{
"src_folders": ["tests"],
"output_folder": "reports",
"custom_commands_path": "",
"custom_assertions_path": "",
"page_objects_path": "./page_objects",
"globals_path": "",
"selenium": {
"start_process": false,
"cli_args": {
"webdriver.chrome.driver": "./bin/chromedriver"
}
},

"test_settings": {
"default": {
"launch_url": "http://google.com",
"selenium_port": 4444,
"selenium_host": "localhost",
"silent": true,
"screenshots": {
"enabled": false,
"path": ""
},
"desiredCapabilities": {
"browserName": "chrome",
"javascriptEnabled": true,
"acceptSslCerts": true,
"chromeOptions": {
"args": ["start-fullscreen"]
}
}
}
}
}

Finally getting it running is pretty darn simple too, here is a test you can use to make sure you have your setup working before you continue doing more complex things.

module.exports = {
'Demo test Google' : function (browser) {
browser
.url('http://www.google.com')
.waitForElementVisible('body', 1000)
.setValue('input[type=text]', 'nightwatch')
.waitForElementVisible('button[name=btnG]', 1000)
.click('button[name=btnG]')
.pause(2000)
.assert.containsText('#main', 'Night Watch')
.end();
}
};

Go, defend your app from unwarranted bugs and accidental downtime. I’ll work on some more advanced Nightwatch topics to share what I can figure out with you my illustrious reader.