Nightwatch.js is an awesome, lightweight, Node.js based, End-to-End (E2E) testing framework. Cucumber.js is a JavaScript implementation of Cucumber, my favorite Domain Specific Language (DSL) driven testing framework. When I found out that Github user mucsi96 wrote a plugin that uses Nightwatch with Cucumber.js, aptly named Nightwatch-Cucumber, I decided to give it a try.
I am happy to report I have made the switch and it’s now my go-to framework for writing comprehensive automated testing suites. Some pros I found were:
- It’s all JavaScript (sort of) : Aside from the Cucumber files, which are written in the Gherkin DSL, there’s no need for cross-language dependencies. This means no Ruby, no gems, no LOCK file. All JS; all the time.
- Configuration is robust: Nightwatch provides a slew of configuration options that allow for extreme customization of how you run your tests and what type of data you receive back.
- It provides cloud service support: Nightwatch integrates with services like SauceLabs and Browserstack.
In this post, I’m going to get you started with the basics of setting up Nightwatch-Cucumber on your own machine. We’ll set up the configuration file, write a Cucumber feature, and provide the step definitions to make the feature executable. Let’s get started!
Setup
You’re going to need to install a few things — starting with Nightwatch.js and Cucumber.js. We can do this with NPM. If you don’t feel like installing this all yourself, you can clone the git repository that we’ll be using as an example here, and just follow along.
npm install cucumber nightwatch --save
After this we’ll need to install the module for Nightwatch-Cucumber itself, as well as our Selenium server:
npm install nightwatch-cucumber selenium-server --save
This is going to give you all the necessary stuff under the hood to easily use the Cucumber language with the Nightwatch JS framework. It’s also going to allow you set up Selenium Server options in your conf.js file via the Selenium Server library. We’ll get to this soon. Once this is all done, we’re ready to begin creating the three files necessary to run Nightwatch.
The Config
Nightwatch requires three files to run properly:
- A configuration file
- A file containing our step definitions
- A file with our Cucumber features
We’ll start with the configuration file called nightwatch.conf.js
var seleniumServer = require('selenium-server') var phantomjs = require('phantomjs-prebuilt') var nightwatchCucumber = require('nightwatch-cucumber') // Handles the runner, location of feature files and step definitions, // and closing of nightwatch var nightwatchCucumberConf = { runner: 'nightwatch', featureFiles: 'features', stepDefinitions: 'step_definitions', closeSession: 'afterFeature' } module.exports = { // Loads nightwatch-cucumber configuration into main nightwatch.js conf src_folders: [nightwatchCucumber(nightwatchCucumberConf)], custom_commands_path: '', custom_assertions_path: '', page_objects_path: '', live_output: false, disable_colors: false, // Sets configuration for Selenium Server selenium: { start_process: true, server_path: seleniumServer.path, host: '127.0.0.1', port: 4444 }, // Sets config options for different testing environments defined by the user test_settings: { default: { launch_url: 'https://moduscreate.com', silent: true, desiredCapabilities: { browserName: 'chrome', javascriptEnabled: true, acceptSslCerts: true }, 'screenshots': { enabled: true, on_error: true, on_failure: true, path: '/screenshots' } }, firefox: { desiredCapabilities: { browserName: 'firefox', javascriptEnabled: true, acceptSslCerts: true } } } }
That’s a lot of code, but the important parts to take away are the nightwatchCucumberConf
, the src_folders
, the selenium settings, and test_settings.
You can read more about what these do in the comments above the code. In short, this file will set our test runner, define where our feature and step definition files live, configure our selenium server, and specify which browser environments we want to use. Cucumber-Nightwatch uses Nightwatch.js as the default runner, but Github user mucsi96 gives a great setup guide on using Cucumber.js as your runner instead if you feel inclined. You can also check out the Nightwatch.js official documentation for a full list of config options, including some of the ones you see being used above. With this file done, we can move to creating feature files with Cucumber.
Features
This guide assumes you’re familiar with Cucumber and the Gherkin language syntax. If you aren’t, I highly recommend you check out the Cucumber.io docs as well as this awesome blog post by our own Mallory Mooney on writing Cucumber features. In our feature file (/tests/nightwatch/features/modus_website/modusAbout.feature
) we have a simple feature with one test scenario.
Feature: Modus About Page To establish that our website has an About Page As a user, I want to ensure that our Home page has a link to the about page Scenario: Verify About Page Link Given I open the Modus Create home page And the title is "Modus Create - HTML5 Application Development & Training" Then the About Page link exists
This is pretty straight forward — the test will open a browser to the Modus Create page, expect the title to match a certain string, and then confirm that a link for the ‘About’ page exists in the view.
On it’s own, this code won’t actually test anything. In fact, due to Cucumber’s design patterns, when you try to run the tests, it will tell you that you are missing step definitions for each of your Scenario’s steps. Cucumber will even give you the definition to implement, minus the code to execute.
That looks something like this:
Isn’t that awesome? You can now copy and paste that exact code for the first line of your scenario, and fill it in with your own assertions. Let’s take a look at what those files look like.
Step Definitions
As stated previously, step definitions take our Cucumber features and turn them into executable Javascript that we can use to assert against our testing environments. The above example only accounts for one step in our Scenario, but each line needs a definition. Let’s take a look at the step definition file for modusAbout.feature
.
module.exports = function() { this.Given(/^I open the Modus Create home page$/, function(callback) { this .url(this.launch_url) .waitForElementVisible('body', 1000) callback(null, 'pending'); }) this.Then(/^the title is "([^"]*)"$/, function(title, callback) { this.assert.title(title); callback(null, 'pending'); }) this.Then(/^the About Page link exists$/, function(callback) { this.assert.elementPresent('a[href="/about"]') callback(null, 'pending'); }) }
Using RegEx matching, these files will take in our plain English Gherkin syntax, and execute the code inside against our testing environment. Make sure to include your callback functions, as Nightwatch is Node based and code executes asynchronously. For a full list of Nightwatch methods, check out their documentation.
With these files configured and set up, we’re ready to run our first test!
Running
If you installed Nightwatch globally, you can run it from your directory where the conf file lives, simply by typing the command:
nightwatch
If you only installed it locally however, you’ll need to run it from:
node_modules/.bin/nightwatch
If everything runs correctly, you should get a nice output that looks something like this
Nightwatch-Cucumber also generates a nicely formatted HTML report of the test by default. It’s generated in reports/index.html
and looks like this:
Conclusion
Nightwatch-Cucumber is a great module for linking the accessibility of Cucumber.js with the robust testing framework of Nightwatch.js. Together they can not only provide easily readable documentation of your test suite, but also highly configurable automated user tests for your project, all while keeping everything in JavaScript (which we love). Do you use Nightwatch or Cucumber in your projects? What features (no pun intended) do you find most appealing? Let us know in the comments!
Andrew Owen
Related Posts
-
Writing Cucumber Features:Which Approach is Better?
Cucumber is an awesome tool that can help your team create living documentation for your…
-
Using Cucumber to write BDD tests for an Extjs 5 App
In my previous blog I wrote about how you can get started with writing end…