How to Automate Tests With Cucumber and Nightwatch.js
Set up Cucumber with Nightwatch.js, write Gherkin features and JavaScript steps, configure browser sessions, and run the suite locally or remotely.
Nightwatch.js can run Cucumber.js as an integrated alternative test runner. Install Cucumber in the same project as Nightwatch, configure the runner to find your .feature files and JavaScript step definitions, then run the suite with the Nightwatch CLI. This guide builds a minimal runnable structure, explains browser startup and reporting choices, and covers local and remote execution.
1. Create the project and install dependencies
Start in an existing Nightwatch project, or create a directory for one. Nightwatch’s Cucumber integration guide specifies Cucumber.js 7.3 or later for the documented integration. Check the installed Nightwatch and Cucumber versions together before pinning versions; the guide’s stated requirement is not a guarantee about every future release.
npm init -y
npm install --save-dev nightwatch @cucumber/cucumber
If Nightwatch is already installed, add only Cucumber:
npm install --save-dev @cucumber/cucumber
Keep the feature files and step definitions in separate directories so the test scenarios remain readable and the browser actions stay reusable. This example uses:
tests/
features/
homepage.feature
step_definitions/
homepage.js
nightwatch.conf.js
Use the versions supported by your project and consult the Nightwatch Cucumber integration guide when adapting the setup. The guide documents Cucumber.js 7.3 or higher.
2. Configure Nightwatch to use Cucumber
Set test_runner.type to cucumber, point feature_path at your feature files, and use src_folders for the step-definition directory. Save this as nightwatch.conf.js in the project root:
module.exports = {
test_runner: {
type: 'cucumber',
options: {
feature_path: 'tests/features/*.feature',
auto_start_session: true,
parallel: 2
}
},
src_folders: ['tests/step_definitions'],
test_settings: {
default: {
desiredCapabilities: {
browserName: 'chrome'
}
}
}
};
The feature_path glob must match where the feature files actually live. The guide also allows feature files and step-definition paths to be passed through src_folders or as CLI arguments. If your existing Nightwatch configuration already defines environments, capabilities, or driver settings, retain those project-specific settings and add the Cucumber runner configuration.
Nightwatch looks for a configuration file in the working directory by default. Recognized names include nightwatch.conf.js, nightwatch.conf.cjs, nightwatch.conf.ts, and nightwatch.json. Use --config to select a different file. See the configuration reference.
3. Write a Gherkin feature and JavaScript steps
A feature file describes behavior in terms of a user-visible outcome. The example below checks that a page title is available after the browser opens a page:
Feature: Homepage
Scenario: The homepage has a title
Given I open the homepage
Then the page title should contain "Example Domain"
Put the matching step definitions in tests/step_definitions/homepage.js. Nightwatch’s Cucumber integration exposes the Nightwatch client as this.client in step definitions:
const { Given, Then } = require('@cucumber/cucumber');
const assert = require('node:assert/strict');
Given('I open the homepage', async function () {
await this.client.url('https://example.com');
});
Then('the page title should contain {string}', async function (expected) {
const title = await this.client.title();
assert.ok(title.includes(expected), `Expected title to include "${expected}", got "${title}"`);
});
Use the Nightwatch browser commands and the assertion style your project has standardized on. Keep step text focused on the behavior under test; a step should not become a long description of every low-level browser operation.
4. Run the Cucumber suite
With src_folders and feature_path configured, run the suite from the project root:
npx nightwatch
You can pass a step-definition path to the CLI as shown in Nightwatch’s integration examples:
npx nightwatch tests/step_definitions
For a different configuration file, use Nightwatch’s --config option:
npx nightwatch --config nightwatch.ci.conf.js
Check npx nightwatch --help for the options supported by the installed version. The integration guide demonstrates passing Cucumber options such as parallel workers and formatter settings through the Nightwatch CLI.
5. Choose browser startup and scenario hooks
For ordinary scenarios, leave auto_start_session: true. Nightwatch starts the browser session automatically, which keeps the feature steps focused on actions and assertions.
Set auto_start_session: false when a scenario must change capabilities or perform setup before the browser launches. In a Cucumber hook, use the Nightwatch client, configure it, and then call launchBrowser(). Follow the integration guide’s lifecycle pattern and make sure the browser is closed during teardown if your hook setup does not return the browser in the expected Nightwatch-managed form.
const { Before, After } = require('@cucumber/cucumber');
Before(async function () {
// Configure the Nightwatch client before starting the session when needed.
this.browser = await this.client.launchBrowser();
});
After(async function () {
// Close the session here if your lifecycle setup requires explicit teardown.
// Use the teardown command appropriate to the installed Nightwatch version.
});
Hook APIs and the exact capability-setting pattern depend on the installed Nightwatch and Cucumber versions. Use the official integration example as the version-matched reference before copying a capability mutation into a project. The important lifecycle points are to disable automatic startup when setup must happen first, launch after configuration, and close sessions reliably.
6. Run locally, in CI, or against a remote browser
Start with a local browser while validating the integration. Nightwatch can manage supported local WebDriver processes when configured for them. For Selenium Grid or a cloud browser service, configure a Selenium connection and the appropriate remote environment. Nightwatch’s environment documentation names BrowserStack and Sauce Labs as examples of providers; current provider pricing and feature details should be checked directly with those services.
| Execution choice | Useful when | What to configure |
|---|---|---|
| Local browser | You are developing the suite or need a short feedback loop. | Browser availability and Nightwatch’s local driver management settings. |
| CI browser | Tests need to run on each change in a build pipeline. | Browser installation or managed driver setup, CI environment variables, and a stable test command. |
| Remote Selenium or cloud | You need browser and operating-system coverage beyond the local machine. | Selenium connection settings, remote capabilities, credentials, and provider-specific concurrency limits. |
Nightwatch keeps environments under test_settings, with a default environment and named alternatives. Select the target environment using the CLI options supported by your installed version. Review the Nightwatch documentation and the current configuration reference for the setup that matches your driver and environment. Local and remote execution differ in setup and driver maintenance, available browser coverage, CI integration, parallel capacity, and service cost; measure these against your suite and team needs rather than assuming one is always faster.
7. Configure parallel runs, tags, and formatters
Parallel execution
The runner accepts a parallel worker setting. This configuration uses two workers:
test_runner: {
type: 'cucumber',
options: {
feature_path: 'tests/features/*.feature',
parallel: 2
}
}
You can also pass --parallel 2 as demonstrated in Nightwatch’s guide. Parallelism can reduce elapsed time when scenarios are independent and your browser environment has enough capacity. It can also expose shared state, account collisions, or resource limits. Use isolated test data and increase worker count only as far as the environment can support.
Tags
Tag scenarios in Gherkin and filter them with the Cucumber tag expression supported by your installed versions. Nightwatch’s vendor boilerplate demonstrates a command in this shape:
npx nightwatch --tags "@nightwatch and @cucumber"
Verify the exact CLI behavior with your installed Nightwatch and Cucumber versions. Keep tags meaningful—for example, to identify a suite or execution group—so that filtered runs remain understandable.
Formatters and output
The integrated runner delegates reporting to the Cucumber CLI. Nightwatch’s own reporters, including its JUnit XML reporting and global custom reporter, are unavailable in this mode. Use a Cucumber formatter instead. The guide says the progress formatter is the default and describes forwarding --format and --format-options through Nightwatch.
npx nightwatch --format progress
Formatter packages and accepted options can change with Cucumber releases. Confirm the formatter is installed and its output settings match the CI system that will consume the report. See the Cucumber integration guide.
8. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Nightwatch reports that no tests or features were found. | feature_path does not match the files, or the command is running from a different working directory. |
Check the path relative to the config file and working directory, confirm the files end in .feature, and pass the intended path explicitly if needed. |
| Steps are undefined. | The step-definition directory is missing from src_folders or was not supplied to the CLI. |
Point src_folders at the directory containing the JavaScript steps. Check that the step text and definition pattern match exactly. |
| Cucumber cannot be loaded or the runner fails during startup. | Cucumber is not installed in the Nightwatch project, or the installed versions do not match the integration’s expectations. | Install @cucumber/cucumber as a development dependency in the project and review the Nightwatch guide’s stated Cucumber 7.3+ requirement alongside your installed versions. |
| The browser session starts before setup can modify it. | Automatic startup is enabled. | Set auto_start_session: false, perform setup in a Cucumber hook through this.client, then launch the browser as documented. |
| Nightwatch reporter configuration has no effect. | The integrated Cucumber runner uses Cucumber reporting. | Configure a Cucumber formatter and verify its output options against the installed Cucumber version. |
| Remote session creation fails. | The Selenium endpoint, credentials, or remote capabilities are missing or do not match the target environment. | Check the remote environment configuration and provider instructions; keep secrets in CI environment variables rather than committing them. |
| Parallel runs fail intermittently while serial runs pass. | Scenarios may share accounts or mutable data, or the browser environment may not have capacity for the selected worker count. | Isolate scenario data and reduce parallel workers until the remote or local environment can sustain the load. |
| A run hangs or leaves browser processes open. | A hook failed to complete teardown, or an asynchronously launched session was not closed. | Review hook error paths and ensure every started session is closed using the lifecycle supported by the installed Nightwatch version. |
9. Performance, reliability, and cost
- Keep steps focused. Reusable steps reduce duplicated browser work and make failures easier to diagnose.
- Use parallelism deliberately. More workers can shorten wall-clock time, but only when the browser capacity and test data isolation support them.
- Stabilize the environment. Pin project dependencies according to your compatibility policy, keep browser and driver setup consistent in CI, and verify behavior when upgrading Nightwatch or Cucumber.
- Budget remote execution. Cloud and Grid costs depend on provider terms and usage; this guide’s research does not establish current service prices. Check provider pricing and concurrency limits directly.
- Make reports actionable. Choose a Cucumber formatter whose output your local workflow or CI can retain and inspect. Nightwatch reporters are not available through the integrated runner.
10. Or skip the browser setup
If the task is to capture a page for documentation, a visual check, or an AI workflow rather than exercise browser behavior, ScreenshotNeo can return a screenshot or PDF from one API request. Read the ScreenshotNeo API documentation for parameters and response details.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
- Cookie banners are accepted and removed before capture, along with supported newsletter popups and chat widgets.
- Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers identify the page verdict and billing status.
- An MCP server lets AI agents using Claude, Cursor, or another MCP client call screenshot and PDF tools.
- 1,000 screenshots per month are free with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free plan and get 1,000 screenshots a month with no card.
11. FAQ
Can I use Cucumber feature files with Nightwatch’s regular test runner?
This setup uses Nightwatch’s integrated Cucumber runner as an alternative test runner. Configure test_runner.type as cucumber to use it.
Do I need to install Cucumber globally?
No. The integration guide instructs you to install @cucumber/cucumber in the same project as Nightwatch.
Can I use Nightwatch’s JUnit reporter with this runner?
No. In the integrated Cucumber mode, reporting is delegated to the Cucumber CLI, so use a Cucumber formatter.
When should I turn off automatic browser startup?
Turn it off when a hook must change capabilities or control setup before the browser launches. Otherwise, automatic startup is the standard path.


