This module enables to use a BDD-style approach for cross-browser testing:
- Describe user stories in Cucumber using Gherkin syntax
- Map them to browser operations and assertions in Nightwatch.js
- Run using either real browser, headless browser or cloud based WebDriver services such as SauceLabs or BrowserStack
This plugin allows to run tests in two modes:
- Nightwatch.js as runner (default)
- Cucumber.js as runner
First you need to have Nightwatch.js and Cucumber.js to be installed locally.
$ npm install --save-dev nightwatch cucumber
If you are new to Nightwatch.js you can read the developer guide.
Install nightwatch-cucumber
$ npm install --save-dev nightwatch-cucumber
In project root create a JavaScript configuration file for Nightwatch.js. Use nightwatch.conf.js
instead of nightwatch.json
. More details
// nightwatch.conf.js
module.exports = {
...
}
Add nightwatch-cucumber
to src_folders
in configuration file.
// nightwatch.conf.js
var nightwatchCucumber = require('nightwatch-cucumber')({
/* configuration */
})
module.exports = {
src_folders: [nightwatchCucumber],
...
}
For more examples check out the test folder
By default feature files are located in features
folder. You can change this using configuration object.
# features/google.feature
Feature: Google Search
Scenario: Searching Google
Given I open Google's search page
Then the title is "Google"
And the Google search form exists
Step definitions files are located in features/step_definitions
folder by default.
All step definitions will run with this
set to Nightwatch.js client or browser object
// features/step_definitions/google.js
module.exports = function() {
this.Given(/^I open Google's search page$/, function() {
this
.url('http://google.com')
.waitForElementVisible('body', 1000)
})
this.Then(/^the title is "([^"]*)"$/, function(title) {
this.assert.title(title)
})
this.Then(/^the Google search form exists$/, function() {
this.assert.visible('input[name="q"]')
})
}
For more examples check out the test folder
If you have installed nightwatch
with -g
(global) option you can run the tests by executing
nightwatch
In other case you can run the tests by executing
node_modules/.bin/nightwatch
HTML report generation is enabled by default. It's default location is reports/index.html
. You can disable or change this using configuration object.
You can use feature background to avoid copying and pasting of steps. The background runs before each scenario after beforeScenario hooks.
Feature: Feature background example
Background:
Given there are 10 cucumbers
Scenario: eating
When I eat 3 cucumbers
Then I should have 7 cucumbers
Scenario: adding
When I add 1 cucumbers
Then I should have 11 cucumbers
You can use scenario outlines to avoid copying and pasting of scenarios.
Scenario Outline: eating
Given there are <start> cucumbers
When I eat <eat> cucumbers
Then I should have <left> cucumbers
Examples:
| start | eat | left |
| 12 | 5 | 7 |
| 20 | 5 | 15 |
For making you tests more readable and maintainable you can use the Page Object pattern. Nightwatch reads the page objects from the folder (or folders) specified in the page_objects_path
configuration property. More details. Add the following line to Nightwatch.js configuration file.
// nightwatch.conf.js
var nightwatchCucumber = require('nightwatch-cucumber')({
/* configuration */
})
module.exports = {
src_folders: [nightwatchCucumber],
page_objects_path: 'page-objects',
...
}
//page-objects/yahoo.js
module.exports = {
url: 'http://yahoo.com',
elements: {
body: 'body',
searchBar: 'input[name="p"]'
}
}
Now we can use page objects from step definitions
//step-definitions/yahoo.js
module.exports = function() {
this.Given(/^I open Yahoo's search page$/, function() {
var yahoo = this.page.yahoo()
yahoo
.navigate()
.waitForElementVisible('@body', 1000)
})
this.Then(/^the Yahoo search form exists$/, function() {
var yahoo = this.page.yahoo()
yahoo.assert.visible('@searchBar')
})
}
You can selectively run features based on groups. To group features together just place them in the same sub-folder. The folder name is the name of the group.
You can use Nightwatch CLI --group
, --skipgroup
flags. More details
You can selectively run features based on tags. More details
# google.feature
@google @search
Feature: Google Search
Scenario: Searching Google
Given I open Google's search page
Then the title is "Google"
And the Google search form exists
$ node nightwatch.js --tag google
You can also skip features based on tags
node nightwatch.js --skiptags google
These hooks can be provided using Nightwatch external globals. External globals file is specified in the globals_path
property of nightwatch.conf.js
. More details
// nightwatch.conf.js
var nightwatchCucumber = require('nightwatch-cucumber')({
/* configuration */
})
module.exports = {
src_folders: [nightwatchCucumber],
globals_path: 'globals-module.js',
...
}
// globals-module.js
module.exports = {
before : function(cb) {
console.log('Runs before all features')
cb()
},
beforeEach : function(browser, cb) {
console.log('Runs before each feature')
cb()
},
after : function(cb) {
console.log('Runs after all features')
cb()
},
afterEach : function(browser, cb) {
console.log('Runs after each feature')
cb()
}
}
These hooks can be provided using configuration object.
// nightwatch.conf.js
var nightwatchCucumber = require('nightwatch-cucumber')({
beforeScenario: function(browser, cb) {
console.log('Runs before each scenario')
cb()
},
beforeStep: function(browser) {
console.log('Runs before each step')
},
afterScenario: function(browser, cb) {
console.log('Runs after each scenario')
cb()
},
afterStep: function(browser) {
console.log('Runs after each step')
}
})
module.exports = {
src_folders: [nightwatchCucumber],
...
}
This plugin provides three ways of closing Selenium sessions. This enables reuse of session and prevents browser restarts. This can be controlled in configuration using closeSession
property. Possible values are:
afterScenario
afterFeature
defaultnever
The default configuration object is.
{
runner: 'nightwatch',
featureFiles: 'features',
stepDefinitions: 'features/step_definitions',
closeSession: 'afterFeature',
htmlReport: 'reports/index.html'
}
Default configuration could be overwritten in the following way.
// nightwatch.conf.js
var nightwatchCucumber = require('nightwatch-cucumber')({
runner: 'cucumber'
})
module.exports = {
src_folders: [nightwatchCucumber],
...
}
First you need to have Nightwatch.js and Cucumber.js to be installed locally.
$ npm install --save-dev nightwatch cucumber
If you are new to Nightwatch.js you can read the developer guide.
Install nightwatch-cucumber
$ npm install --save-dev nightwatch-cucumber
In project root create a configuration file for Cucumber.js. More details
// cucumber.js
var nightwatchCucumber = require('nightwatch-cucumber')({
/* configuration */
runner: 'cucumber'
})
module.exports = {
default: '--require ' + nightwatchCucumber + ' --require features'
}
In project root create a JavaScript configuration file for Nightwatch.js. Use nightwatch.conf.js
instead of nightwatch.json
. More details
// nightwatch.conf.js
module.exports = {
...
}
For examples check out the test folder
If you have installed cucumber
with -g
(global) option you can run the tests by executing
cucumberjs
In other case you can run the tests by executing
node_modules/.bin/cucumberjs
Anyone and everyone is welcome to contribute.
Thanks for assistance and contributions:
Igor Zalutski (@ZIJ), Daniele Campogiani (@dcampogiani), Simranjeet Singh (@RSsimranjeetsingh), Shashi Shekhar Singh (@singhshashi), Alex Murphy, Ben Grabham, Jean-Baptiste Blanchet (@jbblanchet), Vincent Spiewak (@vspiewak), Fabio Quinzi (@FabioQ), Alfredo Moretta (@Alfredo81), Jeffrey Effendy (@jeffrey-effendy) Lawrence (@ldabiralai)
See CHANGELOG.md
This software is released under the terms of the MIT license.