Using with Cucumber

Getting Started

Before diving in technical steps we highly recommend to check out the Cucumber introduction page. If you like video tutorials we recommend checking out tutorial created by Domenico Gemoli

Step 1 - Installing dependencies

Let's start with installing all the dependencies. First we need to have Nightwatch.js and Cucumber.js to be installed locally. If you are new to Nightwatch.js you can read the developer guide. Also we need some browser WebDriver. In this example we are going to test using Google Chrome browser. So we are installing the ChromeDriver. We use cucumber-pretty to make the output more verbose.

 
$ npm install --save-dev nightwatch-api nightwatch cucumber chromedriver cucumber-pretty

Step 2- Configuring Nightwatch.js

Nightwatch.js requires a configuration to be able to start the correct WebDriver with the needed parameters. Create a JavaScript configuration file in the project root folder. We use nightwatch.conf.js instead of nightwatch.json for more flexibility. In the configuration file we provide the port we are going to use, set the browser name to "Chrome" and provide path for installed ChromeDriver. We don't need to specify src_folders as test are running using Cucumber. Check out Nightwatch docs where all options are documented. Please note that not all of them are supported here.

nightwatch.conf.js
const chromedriver = require('chromedriver');

module.exports = {
  test_settings: {
    default: {
      webdriver: {
        start_process: true,
        server_path: chromedriver.path,
        port: 4444,
        cli_args: ['--port=4444']
      },
      desiredCapabilities: {
        browserName: 'chrome'
      }
    }
  }
};

Step 3 - Configuring Cucumber

Cucumber also needs some configuration. Create a JavaScript configuration file called cucumber.conf.js in the project root folder. This file is responsible for setting up the default timeout, starting the WebDriver and creating the session.

cucumber.conf.js
const { setDefaultTimeout, AfterAll, BeforeAll } = require('cucumber');
const { createSession, closeSession, startWebDriver, stopWebDriver } = require('nightwatch-api');

setDefaultTimeout(60000);

BeforeAll(async () => {
  await startWebDriver();
  await createSession();
});

AfterAll(async () => {
  await closeSession();
  await stopWebDriver();
});

Step 4 - Writing a feature file

Let's create our first feature file under features folder called google.feature.

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 5 - Writing step definitions

For Cucumber to be able to understand and execute the feature file we need to create matching step definitions for every feature step we use in our feature file. Create a step definition file under step-definitions folder called google.js.

step-definitions/google.js
const { client } = require('nightwatch-api');
const { Given, Then, When } = require('cucumber');

Given(/^I open Google's search page$/, () => {
  return client.url('http://google.com').waitForElementVisible('body', 1000);
});

Then(/^the title is "([^"]*)"$/, title => {
  return client.assert.title(title);
});

Then(/^the Google search form exists$/, () => {
  return client.assert.visible('input[name="q"]');
});

Step 6 - Creating npm script

For convenience we are creating an npm script in our package.json to be able to execute the test with a short command. You can choose any name for it.

package.json
{
  ...
  "scripts": {
    "e2e-test": "cucumber-js --require cucumber.conf.js --require step-definitions --format node_modules/cucumber-pretty",
    ...
  }
  ...
}

Step 7 - Run the tests

We are ready to run our first test.

 
$ npm run e2e-test

> nightwatch-api-test@1.0.0 e2e-test /home/igor/test/nightwatch-api-test
> cucumber-js --require cucumber.conf.js --require step-definitions --format node_modules/cucumber-pretty


Feature: Google Search

  Scenario: Searching Google
    Given I open Google's search page
 Element <body> was visible after 96 milliseconds.
    Then the title is "Google"
 Testing if the page title equals "Google"  - 18 ms.
    And the Google search form exists
 Testing if element <input[name="q"]> is visible  - 98 ms.

1 scenario (1 passed)
3 steps (3 passed)
0m02.263s

For more examples check out the the cucumber-example or cucumber-selenium-example projects.

Executing individual feature files or scenarios

Single feature file

 
npm run e2e-test -- features/google-search.feature

Multiple feature files

 
npm run e2e-test -- features/google-search.feature features/duckduckgo-search.feature

Glob pattern

 
npm run e2e-test -- features/**/*.feature

Feature directory

 
npm run e2e-test -- features/dir

Scenario by its line number

 
npm run e2e-test -- features/my_feature.feature:3

Scenario by its name matching a regular expression

 
npm run e2e-test -- --name "topic 1"

Feature and Scenario Tags

You can selectively run features and scenarios based on tags. More details

 
# google.feature

@google
Feature: Google Search

@search
Scenario: Searching Google

  Given I open Google's search page
  Then the title is "Google"
  And the Google search form exists
 
npm run e2e-test -- --tags @google

or for multiple tags

 
npm run e2e-test -- --tags "@google or @duckduckgo"
npm run e2e-test -- --tags "(@google or @duckduckgo) and @search"

You can also skip features or scenarios based on tags

 
npm run e2e-test -- --tags "not @google"
npm run e2e-test -- --tags "not(@google or @duckduckgo)"

Custom Reporters

You can provide multiple reporters (formatters) for Cucumber. To generate an HTML view of your test reports, you can use cucumber-html-reporter.

Step 1 - Installing dependencies

 
$ npm install --save-dev cucumber-html-reporter mkdirp

Step 2 - Configuring Nightwatch.js

HTML reports can contain screenshot images about the tested application in the state of feature step failure. This is a very handy feature as it provides immediate visual clue of possible problem and will simplify the debugging process. You can enable it in Nightwatch configuration file.

nightwatch.conf.js
module.exports = {
  test_settings: {
    default: {
      screenshots: {
        enabled: true,
        path: 'screenshots'
      }
      // ...
    }
    // ...
  }
};

Step 2 - Create a cucumber config file

We also need to extend the Cucumber configuration file with handling of screenshots and attaching them to the report. Also the html report generation can be configured here. This report is generated based on Cucumber builtin json report using different templates. We use a setTimeout as we want to run the generation after Cucumber finishes with the creation of json report. Unfortunately currently there is no separate hook in Cucumber for doing this.

cucumber.conf.js
const fs = require('fs');
const path = require('path');
const { setDefaultTimeout, After, AfterAll, BeforeAll } = require('cucumber');
const {
  createSession,
  closeSession,
  startWebDriver,
  stopWebDriver,
  getNewScreenshots
} = require('nightwatch-api');
const reporter = require('cucumber-html-reporter');

setDefaultTimeout(60000);

BeforeAll(async () => {
  await startWebDriver({ env: process.env.NIGHTWATCH_ENV || 'chromeHeadless' });
  await createSession();
});

AfterAll(async () => {
  await closeSession();
  await stopWebDriver();
  setTimeout(() => {
    reporter.generate({
      theme: 'bootstrap',
      jsonFile: 'report/cucumber_report.json',
      output: 'report/cucumber_report.html',
      reportSuiteAsScenarios: true,
      launchReport: true,
      metadata: {
        'App Version': '0.3.2',
        'Test Environment': 'POC'
      }
    });
  }, 1000);
});

After(function() {
  getNewScreenshots().forEach(file => this.attach(fs.readFileSync(file), 'image/png'));
});

For details on available options for report generation, see the Cucumber HTML Reporter documentation.

Step 3 - Update your npm scripts

package.json
{
   ...
   "scripts": {
       "e2e-test": "mkdirp report && cucumber-js --require cucumber.conf.js --require step-definitions --format node_modules/cucumber-pretty --format json:report/cucumber_report.json",
       ...
   }
   ...
}

Notice we have added the json formatter. This generates a JSON report which is used by cucumber-html-reporter to generate the HTML report. We use mkdirp to make sure report folder exists before running the test.

Step 4 - Run the tests

 
$ npm run e2e-test

When the test run completes, the HTML report is displayed in a new browser tab.

Example reports are available in the Cucumber HTML Reporter documentation.

For working example check out the cucumber-example in the repository.

Nightwatch API
v2.3.0