Nightwatch.jsNightwatch.js

Browser automated testing done easy.

Write End-to-End tests in Node.js quickly and effortlessly that run against a Selenium/WebDriver server.

Browser Automation

Nightwatch.js is an easy to use Node.js based End-to-End (E2E) testing solution for browser based apps and websites. It uses the powerful W3C WebDriver API to perform commands and assertions on DOM elements.

Main Features

  • Clean syntax

    Simple but powerful syntax which enables you to write tests very quickly, using only Javascript (Node.js) and CSS or Xpath selectors.

  • Selenium server

    Controls the Selenium standalone server automatically in a separate child process; can be disabled if Selenium runs on another host.

  • CSS & Xpath support

    Either CSS or Xpath selectors can be used to locate and verify elements on the page or execute commands.

  • Easy to extend

    Flexible command and assertion framework which makes it easy to extend to implement your application specific commands and assertions.

  • Built-in test runner

    Built-in command-line test runner which can run the tests either sequentially or in parallel, together, by group, tags or single. Grunt support is built-in.

  • Cloud services support

    Works with cloud testing providers, such as SauceLabs and BrowserStack.

  • Continous integration support

    JUnit XML reporting is built-in so you can integrate your tests in your build process with systems such as Teamcity, Jenkins, Hudson etc.

Demo Test

The test below navigates to google.com and searches for "rembrandt van rijn", then verifies if the term first result is the Wikipedia page of Rembrandt.


module.exports = {
  'Demo test Google' : function (client) {
    client
      .url('http://www.google.com')
      .waitForElementVisible('body', 1000)
      .assert.title('Google')
      .assert.visible('input[type=text]')
      .setValue('input[type=text]', 'rembrandt van rijn')
      .waitForElementVisible('button[name=btnG]', 1000)
      .click('button[name=btnG]')
      .pause(1000)
      .assert.containsText('ol#rso li:first-child',
        'Rembrandt - Wikipedia')
      .end();
  }
};
Run and manage your Nightwatch tests with absolutely no hassle, no config, no nonsense.

Stay Updated

Follow @nightwatchjs on Twitter to receive updates or to get in touch.

Follow on Twitter

Getting Started

What is Nightwatch?

Nightwatch.js is an automated testing framework for web applications and websites, written in Node.js and using the W3C WebDriver API (formerly Selenium WebDriver).

It is a complete browser (End-to-End) testing solution which aims to simplify the process of setting up Continuous Integration and writing automated tests. Nightwatch can also be used for writing Node.js unit tests.

Nightwatch got its name from the famous painting The Night Watch by Dutch artist Rembrandt van Rijn. The masterpiece is prominently displayed in the Rijksmuseum, in Amsterdam - The Netherlands.

Overview of WebDriver

WebDriver is a general purpose library for automating web browsers. It was started as part of the Selenium project, which is a very popular and comprehensive set of tools for browser automation, initially written for Java but now with support for most programming languages.

Nightwatch uses the WebDriver API to perform the browser automation related tasks, like opening windows and clicking links for instance.

WebDriver is now a W3C specification, which aims to standardize browser automation. WebDriver is a remote control interface that enables introspection and control of user agents. It provides a platform and a restful HTTP api as a way for web browsers to be remotely controlled.

Theory of Operation

Nightwatch works by communicating over a restful HTTP api with a WebDriver server (typically the Selenium server). The restful API protocol is defined by the W3C WebDriver API. See below for an example workflow for browser initialization.

Theory of Operation

Most of the times, Nightwatch needs to send at least 2 requests to the WebDriver server in order to perform a command or assertion, the first one being the request to locate an element given a CSS selector (or Xpath expression) and the next to perform the actual command/assertion on the given element.

Install Node.js

From nodejs.org:

"Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices."

There are installation packages and instructions for most major Operating systems on its website nodejs.org. Remember to install also the npm tool, which is the node package manager and is distributed with the Node.js installer.

Install Nightwatch

To install the latest version using the npm command line tool, run the following:

$ npm install [-g] nightwatch

Add -g option to make nightwatch runner available globally in your system.

Selenium Server Setup

The most common WebDriver implementation is the Selenium Server. This allows you to manage multiple browser configurations in one place. However, you can also run the individual browser drivers directly, such as the ChromeDriver, more details are available in the Browser Drivers Setup section.

Selenium Server

Selenium Server is a Java application which Nightwatch uses to connect to the various browsers. It runs separately on the machine with the browser you want to test. You will need to have the Java Development Kit (JDK) installed, minimum required version is 7. You can check this by running java -version from the command line.

Download Selenium

Download the latest version of the selenium-server-standalone-{VERSION}.jar file from the Selenium downloads page and place it on the computer with the browser you want to test. In most cases this will be on your local machine and typically inside your project's source folder.

A good practice is to create a separate subfolder (e.g. bin) and place it there as you might have to download other driver binaries if you want to test multiple browsers.

Running Selenium Automatically

If the server is on the same machine where Nightwatch is running, it can be started/stopped directly by the Nightwatch Test Runner.

Running Selenium Manually

To run the Selenium Server manually, from the directory with the jar run the following:

$ java -jar selenium-server-standalone-{VERSION}.jar

Using Selenium

For viewing all the run-time options, run the previous command adding the -help:

$ java -jar selenium-server-standalone-{VERSION}.jar -help

Starting with Selenium 3, FirefoxDriver is no longer included in the package. Also, starting with version 48, Firefox is no longer compatible with FirefoxDriver which is shipped with Selenium 2.x. Firefox users are advised to use GeckoDriver for their testing. For more info, refer to the browser setup section.

More info about running the Selenium Server can be found here: https://github.com/SeleniumHQ/selenium/wiki/RemoteWebDriverServer


The test runner expects a configuration file to be passed, using by default a nightwatch.json file from the current directory, if present. A nightwatch.conf.js file will also be loaded by default, if found.

Let's create the nightwatch.json in the project's root folder and add this inside:

{
  "src_folders" : ["tests"],
  "output_folder" : "reports",
  "custom_commands_path" : "",
  "custom_assertions_path" : "",
  "page_objects_path" : "",
  "globals_path" : "",

  "selenium" : {
    "start_process" : false,
    "server_path" : "",
    "log_path" : "",
    "port" : 4444,
    "cli_args" : {
      "webdriver.chrome.driver" : "",
      "webdriver.gecko.driver" : "",
      "webdriver.edge.driver" : ""
    }
  },

  "test_settings" : {
    "default" : {
      "launch_url" : "http://localhost",
      "selenium_port"  : 4444,
      "selenium_host"  : "localhost",
      "silent": true,
      "screenshots" : {
        "enabled" : false,
        "path" : ""
      },
      "desiredCapabilities": {
        "browserName": "firefox",
        "marionette": true
      }
    },

    "chrome" : {
      "desiredCapabilities": {
        "browserName": "chrome"
      }
    },

    "edge" : {
      "desiredCapabilities": {
        "browserName": "MicrosoftEdge"
      }
    }
  }
}


Using both configuration files is also possible, with nightwatch.conf.js always taking precedence if both are found.

Example


module.exports = (function(settings) {
  settings.test_workers = false;
  return settings;
})(require('./nightwatch.json'));

Basic settings

Name type default description
src_folders string|array none An array of folders (excluding subfolders) where the tests are located.
output_folder
Optional
string tests_output The location where the JUnit XML report files will be saved.
custom_commands_path Optional string|array none Location(s) where custom commands will be loaded from.
custom_assertions_path Optional string|array none Location(s) where custom assertions will be loaded from.
page_objects_path
Optional
string|array none Location(s) where page object files will be loaded from.
globals_path
Optional
string none Location of an external globals module which will be loaded and made available to the test as a property globals on the main client instance.

Globals can also be defined/overwritten inside a test_settings environment.
selenium
Optional
object An object containing Selenium Server related configuration options. See below for details.
test_settings object This object contains all the test related options. See below for details.
live_output
Optional
boolean false Whether or not to buffer the output in case of parallel running. See below for details.
disable_colors
Optional
boolean false Controls whether or not to disable coloring of the cli output globally.
parallel_process_delay
Optional
integer 10 Specifies the delay(in milliseconds) between starting the child processes when running in parallel mode.
test_workers
Optional
boolean|object false Whether or not to run individual test files in parallel. If set to true, runs the tests in parallel and determines the number of workers automatically.
If set to an object, can specify specify the number of workers as "auto" or a number.

Example: "test_workers" : {"enabled" : true, "workers" : "auto"}
test_runner
Optional since v0.8.0
string|object "default" Specifies which test runner to use when running the tests. Values can be either default (built in nightwatch runner) or mocha.


Example: "test_runner" : {"type" : "mocha", "options" : {"ui" : "tdd"}}

Selenium settings

Below are a number of options for the selenium server process. Nightwatch can start and stop the Selenium process automatically which is very convenient as you don't have to manage this yourself and focus only on the tests.

If you'd like to enable this, set start_process to true and specify the location of the jar file inside server_path.

Name type default description
start_process boolean false Whether or not to manage the selenium process automatically.
start_session boolean true Whether or not to automatically start the Selenium session. This will typically be set to false when running unit/integration tests that don't interact with the Selenium server.
server_path string none The location of the selenium jar file. This needs to be specified if start_process is enabled.
E.g.: bin/selenium-server-standalone-2.43.0.jar
log_path string|boolean none The location where the selenium output.log file will be placed. Defaults to current directory.
To disable Selenium logging, set this to false
port integer 4444 The port number Selenium will listen on.
cli_args object none List of cli arguments to be passed to the Selenium process. Here you can set various options for browser drivers, such as:

  • webdriver.firefox.profile: Selenium will be default create a new Firefox profile for each session. If you wish to use an existing Firefox profile you can specify its name here.
    Complete list of Firefox Driver arguments available here.
  • webdriver.chrome.driver: Nightwatch can run the tests using Chrome browser also. To enable this you have to download the ChromeDriver binary and specify it's location here. Also don't forget to specify chrome as the browser name in the desiredCapabilities object.
    More information can be found on the ChromeDriver website.
  • webdriver.ie.driver: Nightwatch has support for Internet Explorer also. To enable this you have to download the IE Driver binary and specify it's location here. Also don't forget to specify "internet explorer" as the browser name in the desiredCapabilities object.

Test settings

Below are a number of settings that will be passed to the Nightwatch instance. You can define multiple sections (environments) of test settings so you could overwrite specific values per environment.

A "default" environment is required. All the other environments are inheriting from default and can overwrite settings as needed.

{
  ...
  "test_settings" : {
    "default" : {
      "launch_url" : "http://localhost",
      "globals" : {
        "myGlobalVar" : "some value",
        "otherGlobal" : "some other value"
      }
    },

    "integration" : {
      "launch_url" : "http://staging.host",
      "globals" : {
        "myGlobalVar" : "other value"
      }
    }
  }
}

The key of the settings group can be passed then to the runner as the --env argument to use the specified settings, like so:

$ nightwatch --env integration

This can be useful if you need to have different settings for your local machine and the Continuous Integration server.

The launch_url property

This property will be made available to the main Nightwatch api which is used in the tests. Its value depends on which environment is used.

If you run your tests as in the example above (with --env integration) launch_url will be set to http://staging.host, as per the configuration. Otherwise it will have the value defined in the default environment (i.e. http://localhost).


module.exports = {
  'Demo test' : function (browser) {
    browser
      .url(browser.launchUrl)
      // ...
      .end();
  }
};

Test globals

A very useful concept that Nightwatch provides is test globals. In its most simple form, this is a dictionary of name-value pairs which is defined in your nightwatch.json configuration file. Like the launch_url property, this is made available directly on the Nightwatch api which is passed to the tests. It is also dependent on the environment used, having the ability to overwrite specific globals per environment.

If we still pass the --env integration option to the runner, then our globals object will look like below:


module.exports = {
  'Demo test' : function (browser) {

    console.log(browser.globals);
    // {
    //   "myGlobalVar" : "some value",
    //   "otherGlobal" : "some other value"
    // }

  }
};


By default, a deep object copy will be created for each test suite run. If you'd like to maintain the same object throughout the entire tests run, set the persist_globals option to true, as detailed below.

Full list of settings

Name type default description
launch_url string none A url which can be used later in the tests as the main url to load. Can be useful if your tests will run on different environments, each one with a different url.
selenium_host string localhost The hostname/IP on which the selenium server is accepting connections.
selenium_port integer 4444 The port number on which the selenium server is accepting connections.
silent boolean true Whether to show extended Selenium command logs.
output boolean true Use to disable terminal output completely.
disable_colors boolean false Use to disable colored output in the terminal.
firefox_profile
deprecated
string|boolean none This options has been deprecated in favor of the cli_args object on the selenium settings object.
chrome_driver
deprecated
string none This options has been deprecated in favor of the cli_args object on the selenium settings object.
ie_driver
deprecated
string none This options has been deprecated in favor of the cli_args object on the selenium settings object.
screenshots object none Selenium generates screenshots when command errors occur. With on_failure set to true, also generates screenshots for failing or erroring tests. These are saved on the disk.

Since v0.7.5 you can disable screenshots for command errors by setting "on_error" to false.

Example:

"screenshots" : {
  "enabled" : true,
  "on_failure" : true,
  "on_error" : false,
  "path" : ""
}
username string none In case the selenium server requires credentials this username will be used to compute the Authorization header.

The value can be also an environment variable, in which case it will look like this:
"username" : "${SAUCE_USERNAME}"
access_key string none This field will be used together with username to compute the Authorization header.

Like username, the value can be also an environment variable:
"access_key" : "${SAUCE_ACCESS_KEY}"
proxy
since v0.8.6
string none Proxy requests to the selenium server. http, https, socks(v5), socks5, sock4, and pac are accepted. Uses node-proxy-agent.

Example: http://user:pass@host:port
desiredCapabilities object An object which will be passed to the Selenium WebDriver when a new session will be created. You can specify browser name for instance along with other capabilities.
Example:

"desiredCapabilities" : {
  "browserName" : "firefox",
  "acceptSslCerts" : true
}

You can view the complete list of capabilities here.
globals object An object which will be made available within the test and can be overwritten per environment. Example:

"globals" : {
  "myGlobal" : "some_global"
}
exclude array An array of folders or file patterns to be skipped (relative to the main source folder).
Example:

"exclude" : ["excluded-folder"]
or:
"exclude" : ["test-folder/*-smoke.js"]
filter string Folder or file pattern to be used when loading the tests. Files that don't match this pattern will be ignored.
Example:

"filter" : "tests/*-smoke.js"
log_screenshot_data boolean false Do not show the Base64 image data in the (verbose) log when taking screenshots.
use_xpath boolean false Use xpath as the default locator strategy
cli_args object none Same as Selenium settings cli_args. You can override the global cli_args on a per-environment basis.
end_session_on_fail boolean true End the session automatically when the test is being terminated, usually after a failed assertion.
skip_testcases_on_fail boolean true Skip the remaining testcases (or test steps) from the same test suite (i.e. test file), when one testcase fails.
output_folder
since v0.8.18
string|boolean Define the location where the JUnit XML report files will be saved. This will overwrite any value defined in the Basic Settings section. If you'd like to disable the reports completely inside a specific environment, set this to false.
persist_globals
since v0.8.18
boolean false Set this to true if you'd like to persist the same globals object between testsuite runs or have a (deep) copy of it per each testsuite.
compatible_testcase_support
since v0.9.0
boolean false Applies to unit tests. When set to true this allows for tests to be written in the standard Exports interface which is interchangeable with the Mocha framework. Prior unit tests interface support is deprecated and this will become the default in future releases.
detailed_output
since v0.9.0
boolean true By default detailed assertion output is displayed while the test is running. Set this to false if you'd like to only see the test case name displayed and pass/fail status. This is especially useful when running tests in parallel.

This section contains guides for getting started with most of the major browsers and setup instructions on how to configure the individual webdriver implementations to work with Nightwatch.

The individual drivers described here are usually standalone applications which are used to interact with the browsers via the WebDriver HTTP API. You can run them either directly, or through the Selenium Server.

GeckoDriver

Overview

GeckoDriver is a standalone application used to interact with Gecko-based browsers, such as Firefox. It is written in Rust and maintained by Mozilla.

Starting with Firefox 48, GeckoDriver is the only way to automate Firefox, the legacy FirefoxDriver which used to be part of Selenium is no longer supported. Internally it translates the HTTP calls into Marionette, Mozilla's automation protocol built into Firefox.

Download

Binaries are available for download on the GeckoDriver Releases page on GitHub, for various platforms.

Selenium 2.x users are advised to use version v0.9, whereas Selenium 3 users should use the latest version.

Usage

If you're using GeckoDriver through Selenium Server, simply set the cli argument "webdriver.gecko.driver" to point to the location of the binary file. E.g.:

{
  "selenium" : {
    "start_process" : true,
    "server_path" : "./bin/selenium-server-standalone-3.{VERSION}.jar",
    "log_path" : "",
    "port" : 4444,
    "cli_args" : {
      "webdriver.gecko.driver" : "./bin/geckodriver"
    }
  }
}

GeckoDriver can also be used as a standalone application. Usage steps are documented on GitHub: https://github.com/mozilla/geckodriver#usage.

Command line usage
$ ./bin/geckodriver-0.10 -help
geckodriver 0.10.0

USAGE:
    geckodriver-0.10 [FLAGS] [OPTIONS]

FLAGS:
        --connect-existing    Connect to an existing Firefox instance
    -h, --help                Prints help information
        --no-e10s             Start Firefox without multiprocess support (e10s) enabled
    -V, --version             Prints version information
    -v                        Set the level of verbosity. Pass once for debug level logging and twice for trace level logging

OPTIONS:
    -b, --binary            Path to the Firefox binary, if no binary capability provided
        --log                Set Gecko log level [values: fatal, error, warn, info, config, debug, trace]
        --marionette-port     Port to use to connect to gecko (default: random free port)
        --host                Host ip to use for WebDriver server (default: 127.0.0.1)
    -p, --port                Port to use for WebDriver server (default: 4444)

Firefox Capabilities

GeckoDriver supports a capability named firefoxOptions which takes Firefox-specific preference values. Details are available on the GeckoDriver GitHub page: https://github.com/mozilla/geckodriver#firefox-capabilities.

Firefox Profile

Specifying the firefox profile can be done by setting the profile property in the firefoxOptions dictionary, as detailed above. This can be the base64-encoded zip of a profile directory and it may be used to install extensions or custom certificates.

Implementation Status

GeckoDriver is not yet feature complete, which means it does not yet offer full conformance with the WebDriver standard or complete compatibility with Selenium. Implementation status can be tracked on the Marionette MDN page.

ChromeDriver

Overview

ChromeDriver is a standalone server which implements the W3C WebDriver wire protocol for Chromium. ChromeDriver is available for Chrome on Android and Chrome on Desktop (Mac, Linux, Windows and ChromeOS).

Download

Binaries are available for download on the ChromeDriver Downloads page, for various platforms.

Selenium Server Usage

If you're using ChromeDriver through Selenium Server, simply set the cli argument "webdriver.chrome.driver" to point to the location of the binary file. E.g.:

{
  "selenium" : {
    "start_process" : true,
    "server_path" : "./bin/selenium-server-standalone-3.{VERSION}.jar",
    "log_path" : "",
    "port" : 4444,
    "cli_args" : {
      "webdriver.chrome.driver" : "./bin/chromedriver"
    }
  }
}

Standalone Usage

If you're only running your tests against Chrome, running ChromeDriver standalone is easier and slightly faster. Also there is no dependency on Java.

This requires a bit more configuration:

1) First, disable Selenium Server, if applicable:
{
  "selenium" : {
    "start_process" : false
  }
}
2) Configure the port and default path prefix.

ChromeDriver runs by default on port 9515. We also need to clear the default_path_prefix, as it is set by default to /wd/hub, which is what selenium is using.

{
  "test_settings" : {
    "default" : {
      "selenium_port"  : 9515,
      "selenium_host"  : "localhost",
      "default_path_prefix" : "",

      "desiredCapabilities": {
        "browserName": "chrome",
        "chromeOptions" : {
          "args" : ["--no-sandbox"]
        },
        "acceptSslCerts": true
      }
    }
  }
}
3) Start the ChromeDriver server

The easiest way to manage the ChromeDriver process is by using the chromedriver NPM package, which is a third-party wrapper against the binary. This will abstract the downloading of the chromedriver binary and will make it easy to manage starting and stopping of the process.

You can add this to your external globals file, like so:


var chromedriver = require('chromedriver');
module.exports = {
  before : function(done) {
    chromedriver.start();

    done();
  },

  after : function(done) {
    chromedriver.stop();

    done();
  }
};  

Using a fixed ChromeDriver version

In some situations you may need to use a specific version of ChromeDriver. For instance, the CI server runs an older version of Chrome. Then you will need an older version of ChromeDriver.

Here's what your globals file might look like:


var chromedriver = require('chromedriver');
var path = require('path');
var driverInstanceCI;

function isRunningInCI() {
  return this.test_settings.globals.integration;
}

function startChromeDriver() {
  if (isRunningInCI.call(this)) {
    var location = path.join(__dirname, '../bin/chromedriver-linux64-2.17');
    driverInstanceCI = require('child_process').execFile(location, []);
    return;
  }

  chromedriver.start();
}

function stopChromeDriver() {
  if (isRunningInCI.call(this)) {
    driverInstanceCI && driverInstanceCI.kill();
    return;
  }

  chromedriver.stop();
}

module.exports = {
  'ci-server' : {
    integration : true
  },

  before : function(done) {
    startChromeDriver.call(this);

    done();
  },

  after : function(done) {
    stopChromeDriver.call(this);

    done();
  }
};


Run your tests then with (on the CI server):
$ ./node_modules/.bin/nightwatch --env ci-server

ChromeOptions

You can specify Chrome options or switches using the chromeOptions dictionary, under the desiredCapabilities. Refer to the ChromeDriver website for a fill list of supported capabilities and options.

Command line usage

$ ./bin/chromedriver -h
Usage: ./bin/chromedriver [OPTIONS]

Options
  --port=PORT                     port to listen on
  --adb-port=PORT                 adb server port
  --log-path=FILE                 write server log to file instead of stderr, increases log level to INFO
  --verbose                       log verbosely
  --version                       print the version number and exit
  --silent                        log nothing
  --url-base                      base URL path prefix for commands, e.g. wd/url
  --port-server                   address of server to contact for reserving a port
  --whitelisted-ips               comma-separated whitelist of remote IPv4 addresses which are allowed to connect to ChromeDriver

Microsoft WebDriver

Overview

Microsoft WebDriver is a standalone server which implements the W3C WebDriver wire protocol for the Edge browser. It is supported by Windows 10 and onwards.

Download

Binaries are available for download on the Microsoft WebDriver homepage.

Selenium Server Usage

If you're using Microsoft WebDriver through Selenium Server, simply set the cli argument "webdriver.edge.driver" to point to the location of the binary file. E.g.:

{
  "selenium" : {
    "start_process" : true,
    "server_path" : "bin/selenium-server-standalone-3.{VERSION}.jar",
    "log_path" : "",
    "port" : 4444,
    "cli_args" : {
      "webdriver.edge.driver" : "bin/MicrosoftWebDriver.exe"
    }
  },
  "test_settings" : {
    "default" : {
      "selenium_port"  : 4444,
      "selenium_host"  : "localhost",

      "desiredCapabilities": {
        "browserName": "MicrosoftEdge",
        "acceptSslCerts": true
      }
    }
  }
}

Standalone Usage

If you're only running your tests against Edge, running the EdgeDriver standalone can be slightly faster. Also there is no dependency on Java.

This requires a bit more configuration and you will need to start/stop the EdgeDriver:

1) First, disable Selenium Server, if applicable:
{
  "selenium" : {
    "start_process" : false
  }
}
2) Configure the port and default path prefix.

Microsoft WebDriver runs by default on port 9515. We also need to clear the default_path_prefix, as it is set by default to /wd/hub, which is what selenium is using.

{
  "test_settings" : {
    "default" : {
      "selenium_port"  : 17556,
      "selenium_host"  : "localhost",
      "default_path_prefix" : "",

      "desiredCapabilities": {
        "browserName": "MicrosoftEdge",
        "acceptSslCerts": true
      }
    }
  }
}
3) Start the MicrosoftWebDriver server

From the Windows CMD prompt, simply CD to the folder where the MicrosoftWebDriver.exe binary is located and run:

C:\nightwatch\bin>MicrosoftWebDriver.exe
[13:44:49.515] - Listening on http://localhost:17556/

Full command line usage:

C:\nightwatch\bin>MicrosoftWebDriver.exe -h
Usage:
 MicrosoftWebDriver.exe --host= --port= --package= --verbose

Implementation Status

EdgeDriver is not yet feature complete, which means it does not yet offer full conformance with the WebDriver standard or complete compatibility with Selenium. Implementation status can be tracked on the Microsoft WebDriver homepage.



Developer Guide

Writing Tests

Using the preferred CSS selector model to locate elements on a page, Nightwatch makes it very easy to write automated End-to-End tests.

Create a separate folder for tests in your project, e.g.: tests. Each file inside it will be loaded as a test by the Nightwatch test runner. A basic test will look like this:


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(1000)
      .assert.containsText('#main', 'Night Watch')
      .end();
  }
};

Remember always to call the .end() method when you want to close your test, in order for the Selenium session to be properly closed.

A test can have multiple steps, if needed:

module.exports = {
  'step one' : function (browser) {
    browser
      .url('http://www.google.com')
      .waitForElementVisible('body', 1000)
      .setValue('input[type=text]', 'nightwatch')
      .waitForElementVisible('button[name=btnG]', 1000)
  },

  'step two' : function (browser) {
    browser
      .click('button[name=btnG]')
      .pause(1000)
      .assert.containsText('#main', 'Night Watch')
      .end();
  }
};

Tests can also be written in this format:


this.demoTestGoogle = 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(1000)
    .assert.containsText('#main', 'The Night Watch')
    .end();
};

Using XPath selectors

Nightwatch supports xpath selectors also. To switch to xpath instead of css selectors as the locate strategy, in your test call the method useXpath(), as seen in the example below. To switch back to CSS, call useCss().

To always use xpath by default set the property "use_xpath": true in your test settings.


this.demoTestGoogle = function (browser) {
  browser
    .useXpath() // every selector now must be xpath
    .click("//tr[@data-recordid]/span[text()='Search Text']")
    .useCss() // we're back to CSS now
    .setValue('input[type=text]', 'nightwatch')
};

BDD Expect Assertions

Nightwatch introduces starting with version v0.7 a new BDD-style assertion library which greatly improves the flexibility as well as readability of the assertions.

The expect assertions use a subset of the Expect api from the Chai framework and are available for elements only at this point. Here's an example:


module.exports = {
  'Demo test Google' : function (client) {
    client
      .url('http://google.no')
      .pause(1000);

    // expect element  to be present in 1000ms
    client.expect.element('body').to.be.present.before(1000);

    // expect element <#lst-ib> to have css property 'display'
    client.expect.element('#lst-ib').to.have.css('display');

    // expect element  to have attribute 'class' which contains text 'vasq'
    client.expect.element('body').to.have.attribute('class').which.contains('vasq');

    // expect element <#lst-ib> to be an input tag
    client.expect.element('#lst-ib').to.be.an('input');

    // expect element <#lst-ib> to be visible
    client.expect.element('#lst-ib').to.be.visible;

    client.end();
  }
};


The expect interface provides a much more flexible and fluid language for defining assertions, significantly improved over the existing assert interface. The only downside is that it's not possible to chain assertions anymore and at this point custom messages aren't yet supported.


For a complete list of available expect assertions, refer to the API docs.

Using before[Each] and after[Each] hooks

Nightwatch provides the standard before/after and beforeEach/afterEach hooks to be used in the tests.

The before and after will run before and after the execution of the test suite respectively, while beforeEach and afterEach are ran before and after each testcase (test step).

All methods have the Nightwatch instance passed as argument.

Example:


module.exports = {
  before : function(browser) {
    console.log('Setting up...');
  },

  after : function(browser) {
    console.log('Closing down...');
  },

  beforeEach : function(browser) {

  },

  afterEach : function() {

  },

  'step one' : function (browser) {
    browser
     // ...
  },

  'step two' : function (browser) {
    browser
    // ...
      .end();
  }
};

In the example above the sequence of method calls will be as follows: before(), beforeEach(), "step one", afterEach(), beforeEach(), "step two", afterEach(), after().

For backwards compatibility reasons, the afterEach hook can receive the browser object only in its async form - afterEach(browser, done) { .. }

Asynchronous before[Each] and after[Each]

All the before[Each] and after[Each] methods can also perform asynchronous operations, in which case they will require the callback passed as the second argument.

The done function must be called as the last step when the async operation completes. Not calling it will result in a timeout error.

Example with beforeEach & afterEach:


module.exports = {
  beforeEach: function(browser, done) {
    // performing an async operation
    setTimeout(function() {
      // finished async duties
      done();
    }, 100);
  },

  afterEach: function(browser, done) {
    // performing an async operation
    setTimeout(function() {
      // finished async duties
      done();
    }, 200);
  }
};

Controlling the done invocation timeout

By default the done invocation timeout is set to 10 seconds (2 seconds for unit tests). In some cases this might not be sufficient and to avoid a timeout error, you can increase this timeout by defining an asyncHookTimeout property (in milliseconds) in your external globals file (see below for details on external globals).

For an example, refer to the provided globalsModule example.

Explicitly failing the test

Failing the test intentionally in a test hook is achievable by simply calling done with an Error argument:


module.exports = {
  afterEach: function(browser, done) {
    // performing an async operation
    performAsync(function(err) {
      if (err) {
        done(err);
      }
      // ...
    });
  }
};

External Globals

Most of the time it's more useful to have your globals defined in an external file, specified in the globals_path property, instead of having them defined in nightwatch.json.

You can overwrite globals per environment as needed. Say you have your tests running locally and also against a remote staging server. Most of the times you will need some different setting up.

Global Hooks

The same set of hooks as per test suite is also available globally, outside the scope of the test. See the below example for more details. In the case of global hooks, the beforeEach and afterEach refers to a test suite (i.e. test file), and are ran before and after a test suite.

Global Settings

There are a number of globals which are holding test settings and can control test execution. These are detailed in the provided globalsModule sample.

Example:


module.exports = {
  'default' : {
    isLocal : true,
  },

  'integration' : {
    isLocal : false
  },

  // External before hook is ran at the beginning of the tests run, before creating the Selenium session
  before: function(done) {
    // run this only for the local-env
    if (this.isLocal) {
      // start the local server
      App.startServer(function() {
        // server listening
        done();
      });
    } else {
      done();
    }
  },

  // External after hook is ran at the very end of the tests run, after closing the Selenium session
  after: function(done) {
    // run this only for the local-env
    if (this.isLocal) {
      // start the local server
      App.stopServer(function() {
        // shutting down
        done();
      });
    } else {
      done();
    }
  },

  // This will be run before each test suite is started
  beforeEach: function(browser, done) {
    // getting the session info
    browser.status(function(result) {
      console.log(result.value);
      done();
    });
  },

  // This will be run after each test suite is finished
  afterEach: function(browser, done) {
    console.log(browser.currentTest);
    done();
  }
};

Test Runner

Nightwatch includes a command-line test runner which makes it easy to run tests and generate useful output. There are a few different options on how to use the test runner, depending on your installation type.

Global

If you have installed Nightwatch globally (with -g option), the binary nightwatch will be available anywhere:

$ nightwatch [source] [options]

Project specific

If you have Nightwatch installed as a dependency of your project, you can refer the binary from the node_modules/.bin folder:


Linux and MacOSX:
$ ./node_modules/.bin/nightwatch [source] [options]


Windows:

Create a file nightwatch.js and add the following line:

require('nightwatch/bin/runner.js');

Then run as follows:

C:\workspace\project> node nightwatch.js [source] [options]

Tests source

The optional source argument can be either one or more files or an entire folder. This can be located irrespectively of the src_folders setting.


Example - single test:
$ nightwatch tests/one/firstTest.js


Example - 2 individual tests:
$ nightwatch tests/one/firstTest.js tests/secondTest.js


Example - 1 individual test and 1 folder:
$ nightwatch tests/one/test.js tests/utils

Command-line Options

The test runner supports a number of run-time options to be passed to. To view all, run the following:

$ nightwatch --help
Name Shortname default description
--config -c ./nightwatch.json The location of the nightwatch.json file - the configuration file which the runner uses and which also includes the Selenium WebDriver options.
--output -o tests_output The location where the JUnit XML reports will be saved.
--reporter -r junit Name of a predefined reporter (e.g. junit) or path to a custom reporter file to use.
--env -e default Which testing environment to use - defined in nightwatch.json
--verbose Shows extended selenium command logging during the session
--version -v Shows the version number
--test -t Runs only the specified test suite/module. By default the runner will attempt to run all tests in the src_folders settings folder(s) and their subfolders.
--testcase Used only together with --test. Runs the specified testcase from the current suite/module.
--group -g Runs only the specified group of tests (subfolder). Tests are grouped by being placed in the same subfolder.
--skipgroup -s Skip one or several (comma separated) group of tests.
--filter -f Specify a filter (glob expression) as the file name format to use when loading the test files.
--tag -a Filter test modules by tags. Only tests that have the specified tags will be loaded.
--skiptags Skips tests that have the specified tag or tags (comma separated).
--retries Retries failed or errored testcases up to the specified number of times. Retrying a testcase will also retry the beforeEach and afterEach hooks, if any.
--suiteRetries Retries failed or errored testsuites (test modules) up to the specified number of times. Retrying a testsuite will also retry the before and after hooks (in addition to the global beforeEach and afterEach respectively), if any are defined on the testsuite.

Test Groups

Nightwatch makes it possible to organize your test scripts into groups and run them as needed. To group tests together just place them in the same sub-folder. The folder name is the name of the group.

Example:

lib/
  ├── selenium-server-standalone.jar
custom-commands/
  ├── loginUser.js
  ├── attachPicture.js
tests/
  ├── logingroup
  |   ├── login_test.js
  |   └── otherlogin_test.js
  ├── addressbook
  |   ├── addressbook_test.js
  |   └── contact_test.js
  ├── chat
  |   ├── chatwindow_test.js
  |   ├── chatmessage_test.js
  |   └── otherchat_test.js
  └── smoketests
      ├── smoke_test.js
      └── othersmoke_test.js

To run only the smoketests group you would do the following:

$ nightwatch --group smoketests

Also, if you would want to skip running the smoketests group you would do the following:

$ nightwatch --skipgroup smoketests

To skip multiple groups, just add them as comma-separated:

$ nightwatch --skipgroup addressbook,chat

Test Tags

You can also selectively target tests to run based on tags, such that a test may be belong to multiple tags. For example, you might have a login test that belongs to a login suite as well as a sanity suite.

The tagging can be accomplished by adding the @tags property to a test module:


module.exports = {
  '@tags': ['login', 'sanity'],
  'demo login test': function (client) {
     // test code
  }
};

To select which tags to run, use the --tag command line flag:

$ nightwatch --tag login

Specify multiple tags as:

$ nightwatch --tag login --tag something_else


To skip running tests with a specific tag, use the --skiptags flag:

$ nightwatch --skiptags login

Or to skip multiple tags, add each tag you want to skip as comma-separated:

$ nightwatch --skiptags login,something_else

Disabling Tests

To prevent a test module from running, simply set the disabled attribute in that module to true, like so:


module.exports = {
  '@disabled': true, // This will prevent the test module from running.

  'sample test': function (client) {
    // test code
  }
};

This can be useful if you don't want to run certain tests that are known to be failing.

Disabling Individual Testcases

Disabling individual testcases isn't currently supported out of the box. However it can be achieved relatively straightforward with a simple work-around. By simply converting the test method to a string, Nightwatch will ignore it.

Here's an example:


module.exports = {
  'sample test': function (client) {
    // test code
  },

  // disabled
  'other sample test': ''+function (client) {
    // test code
  }
};

Parallel Running

Starting with v0.5 Nightwatch supports the tests to be run in parallel. This works by specifying multiple environments in the command line, separated by comma. E.g.:

$ nightwatch -e default,chrome

The above will run two environments named default and chrome in parallel.

Terminal Output

Each environment will be run as a separate child_process and the output will be sent to the main process.

To make the output easier to read, Nightwatch by default buffers the output from each child process and displays everything at the end, grouped by environment.

If you'd like to disable the output buffering and see the output from each child process as it is sent to stdout, simply set the property "live_output" : true on the top level in your nightwatch.json (e.g. after selenium).
You can create a separate environment per browser (by chaining desiredCapabilities) and then run them in parallel. In addition, using the filter and exclude options tests can be split per environment in order to be ran in parallel.

Via Workers

Version v0.7 introduces a new feature which allows the tests to be run in parallel. When this is enabled the test runner will launch a configurable number of child processes and then distribute the loaded tests over to be ran in parallel.

To enable test workers, set the test_workers top-level property, like so:


"test_workers": {
  "enabled": true,
  "workers": "auto"
}   

or, simply:


"test_workers": true

The workers option configures how many child processes can run concurrently.

  • "auto" - determined by number of CPUs e.g. 4 CPUs means 4 workers
  • {number} - specifies an exact number of workers

Test concurrency is done at the file level. Each test file will fill a test worker slot. Individual tests/steps in a test file will not run concurrently.

Version 0.9 brings improved support for displaying output when running tests in parallel. We recommend setting detailed_output to false in your test settings for improved output readability.

Using Grunt

Grunt is a popular JavaScript task runner. Starting with version 0.6 Nightwatch is bundled with an easy to use Grunt task which can be used in your existing Grunt-based build configuration for running the tests.

Usage

First, load the Nightwatch grunt task at the top in your Gruntfile.js.


module.exports = function(grunt) {
  var nightwatch = require('nightwatch');
  nightwatch.initGrunt(grunt);

  // ...

};

Task Configuration and Targets

The Nightwatch task will have one or more targets which can be used in various ways, one way being to map them to environments. Available settings are:

  • options - the only available option so far is cwd - current working directory
  • argv - command-line arguments that would normally be passed to the Nightwatch runner (e.g.: env);
  • settings - the test settings specified to a single Nightwatch environment.

Example


grunt.initConfig({
  nightwatch: {
    options: {
      cwd: './'
    },

    'default' : {},

    browserstack: {
      argv: {
        env: 'browserstack'
      },
      settings: {
        silent: true
      }
    },

    'all' : {
      argv: {
        env: 'default,browserstack'
      }
    },
  }
});


Run the task as follows:

$ grunt nightwatch:default
or
$ grunt nightwatch:browserstack


There are also a few third-party Grunt plugins for Nightwatch which can be used instead, if you prefer. The most popular one is grunt-nightwatch.

Using Mocha

Starting with version 0.8 Nightwatch is bundled with a custom version of the popular Mocha test runner which allows running tests using Mocha, thus taking advantage of its interfaces and reporters.

Usage

There are two main ways in which you can use Mocha with Nightwatch.

From Nightwatch

Mocha is used as an alternative test runner to the built-in one. This is done by specifying the "test_runner" option in the nightwatch.json configuration file.

Custom options can also be specified for Mocha:


{
  ...
  "test_runner" : {
    "type" : "mocha",
    "options" : {
      "ui" : "bdd",
      "reporter" : "list"
    }
  }
  ...
}

or simply:


{
  ...
  "test_runner" : "mocha"
  ...
}

A complete list of Mocha options that are supported can be found here.

The test_runner option can also be specified at test environment level:


{
  "test_settings" : {
    "mocha_tests" : {
      "test_runner" : {
        "type" : "mocha",
        "options" : {
          "ui" : "tdd",
          "reporter" : "list"
        }
      }
    }
  }
  ...
}

Example

Writing a test in Mocha is the same as writing it in Nightwatch. Each testcase receives the client object, hooks also receiving a done callback for async operations.


describe('Google demo test for Mocha', function() {

  describe('with Nightwatch', function() {

    before(function(client, done) {
      done();
    });

    after(function(client, done) {
      client.end(function() {
        done();
      });
    });

    afterEach(function(client, done) {
      done();
    });

    beforeEach(function(client, done) {
      done();
    });

    it('uses BDD to run the Google simple test', function(client) {
      client
        .url('http://google.com')
        .expect.element('body').to.be.present.before(1000);

      client.setValue('input[type=text]', ['nightwatch', client.Keys.ENTER])
        .pause(1000)
        .assert.containsText('#main', 'Night Watch');
    });
  });
});

When using the mocha test runner from Nightwatch some cli options are not available, like --retries, --suiteRetries, --reporter.

Using the standard Mocha

Running Nightwatch tests with the standard Mocha it's also possible, though a bit more boilerplate code is involved and you need to manage the selenium server.

Example


var nightwatch = require('nightwatch');

describe('Github', function() {
  var client = nightwatch.initClient({
    silent : true
  });

  var browser = client.api();

  this.timeout(99999999);

  before(function() {

    browser.perform(function() {
      console.log('beforeAll')
    });

  });

  beforeEach(function(done) {
    browser.perform(function() {
      console.log('beforeEach')
    });

    client.start(done);
  });


  it('Demo test GitHub', function (done) {
    browser
      .url('https://github.com/nightwatchjs/nightwatch')
      .waitForElementVisible('body', 5000)
      .assert.title('nightwatchjs/nightwatch · GitHub')
      .waitForElementVisible('body', 1000)
      .assert.visible('.container .breadcrumb a span')
      .assert.containsText('.container .breadcrumb a span', 'nightwatch', 'Checking project title is set to nightwatch');

    client.start(done);
  });

  afterEach(function() {
    browser.perform(function() {
      console.log('afterEach')
    });
  });

  after(function(done) {
    browser.end(function() {
      console.log('afterAll')
    });

    client.start(done);
  });

});

Using Page Objects

The Page Objects methodology is a popular pattern to write end-to-end tests by wrapping the pages or page fragments of a web app into objects. The purpose of a page object is to allow a software client to do anything and see anything that a human can by abstracting away the underlying html actions needed to access and manipulate the page.

A comprehensive introduction to Page Objects can be found in this article.

As of version 0.7 Nightwatch provides an enhanced and more powerful interface for creating page objects, significantly improved over the previous support. Page objects created prior to v0.7 will still continue to work however we recommend upgrading to the new version. To use the new version, your page object must contain either the elements or sections property. Otherwise, Nightwatch will defer to the old.

Configuring Page Objects

To create a page object simply create an object with properties that describe the page. Each page object should be located in a separate file, located in a designated folder. Nightwatch reads the page objects from the folder (or folders) specified in the page_objects_path configuration property.

The page_objects_path property can also be an array of folders, allowing you thus to logically split the page objects into smaller groups.

The Url property

You can optionally add a url property that designates the page's URL. To navigate to the page, you can call the navigate method on the page object.

The URL will usually be defined as a string:


module.exports = {
  url: 'http://google.com',
  elements: {}
};

It can also be a function in case the URL is dynamic. One use case for this is to support different test environments. You can create a function that gets called in the context of the page, thus allowing you to do:


module.exports = {
  url: function() { 
    return this.api.launchUrl + '/login'; 
  },
  elements: {}
};

Defining Elements

Most of the time, you will want to define elements on your page that your tests will interact with through commands and assertions. This is made simple using the elements property so that all your elements are defined in a single place. Especially in larger integration tests, using elements will go a long way to keep test code DRY.

Switching between css and xpath locate strategies is handled internally so you don't need to call useXpath and useCss in your tests. The default locateStrategy is css but you can also specify xpath:


module.exports = {
  elements: {
    searchBar: { 
      selector: 'input[type=text]' 
    },
    submit: { 
      selector: '//[@name="q"]', 
      locateStrategy: 'xpath' 
    }
  }
};


Or if you're creating elements with the same locate strategy as is default, you can use the shorthand:


module.exports = {
  elements: {
    searchBar: 'input[type=text]'
  }
};


Using the elements property allows you to refer to the element by its name with an "@" prefix, rather than selector, when calling element commands and assertions (click, etc).

Optionally, you can define an array of objects:


var sharedElements = {
  mailLink: 'a[href*="mail.google.com"]'
};

module.exports = {
  elements: [
    sharedElements,
    { searchBar: 'input[type=text]' }
  ]
};


Putting elements and url together, say you have the following defined above saved as a google.js file:


module.exports = {
  url: 'http://google.com',
  elements: {
    searchBar: { 
      selector: 'input[type=text]' 
    },
    submit: { 
      selector: '//[@name="q"]', 
      locateStrategy: 'xpath' 
    }
  }
};


In your tests you will use it as follows:


module.exports = {
  'Test': function (client) {
    var google = client.page.google();

    google.navigate()
      .assert.title('Google')
      .assert.visible('@searchBar')
      .setValue('@searchBar', 'nightwatch')
      .click('@submit');

    client.end();
  }
};

Defining Sections

Sometimes it is useful to define sections of a page. Sections do 2 things:

  • Provide a level of namespacing under the page
  • Provide element-level nesting so that any element defined within a section is a descendant of its parent section in the DOM

You can create sections using the sections property:


module.exports = {
  sections: {
    menu: {
      selector: '#gb',
      elements: {
        mail: {
          selector: 'a[href="mail"]'
        },
        images: {
          selector: 'a[href="imghp"]'
        }
      }
    }
  }
};


Your tests would use it as follows:


module.exports = {
  'Test': function (client) {
    var google = client.page.google();
    google.expect.section('@menu').to.be.visible;

    var menuSection = google.section.menu;
    menuSection.expect.element('@mail').to.be.visible;
    menuSection.expect.element('@images').to.be.visible;

    menuSection.click('@mail');

    client.end();
  }
};


Note that every command and assertion on a section (other than expect assertions) returns that section for chaining. If desired, you can nest sections under other sections for complex DOM structures.

Example of nesting page object sections:


module.exports = {
  sections: {
    menu: {
      selector: '#gb',
      elements: {
        mail: {
          selector: 'a[href="mail"]'
        },
        images: {
          selector: 'a[href="imghp"]'
        }
      },
      sections: {
        apps: {
          selector: 'div.gb_pc',
          elements: {
            myAccount: {
              selector: '#gb192'
            },
            googlePlus: {
              selector: '#gb119'
            }
          }
        }
      }
    }
  }
};


Using a nested section in your test is straightforward:


module.exports = {
  'Test': function (client) {
    var google = client.page.google();
    google.expect.section('@menu').to.be.visible;

    var menuSection = google.section.menu;
    var appSection = menuSection.section.apps;
    menuSection.click('@appSection');

    appSection.expect.element('@myAccount').to.be.visible;
    appSection.expect.element('@googlePlus').to.be.visible;

    client.end();
  }
};

Writing Commands

You can add commands to your page object using the commands property. This is a useful way to encapsulate logic about the page that would otherwise live in a test, or multiple tests.

Nightwatch will call the command on the context of the page or section. Client commands like pause are available via this.api. For chaining, each function should return the page object or section.

In this case, a command is used to encapsulate logic for clicking the submit button:


var googleCommands = {
  submit: function() {
    this.api.pause(1000);
    return this.waitForElementVisible('@submitButton', 1000)
      .click('@submitButton')
      .waitForElementNotPresent('@submitButton');
  }
};

module.exports = {
  commands: [googleCommands],
  elements: {
    searchBar: {
      selector: 'input[type=text]'
    },
    submitButton: {
      selector: 'button[name=btnG]'
    }
  }
};


Then the test is simply:


module.exports = {
  'Test': function (client) {
    var google = client.page.google();
    google.setValue('@searchBar', 'nightwatch')
      .submit();

    client.end();
  }
};

Writing Custom Commands

Most of the time you will need to extend the Nightwatch commands to suit your own application needs. Doing that is only a matter of creating a separate folder and defining your own commands inside there, each one inside its own file.

Then specify the path to that folder inside the nightwatch.json file, as the custom_commands_path property. The command name is the name of the file itself.

There are two main ways in which you can define a custom command:

1) Function-style commands

This is the simplest form in which commands are defined, however they are also quite limited. Your command module needs to export a command function, which needs to call at least one Nightwatch api method (such as .execute()). This is due to a limitation of how the asynchronous queueing system of commands works. You can also wrap everything in a .perform() call. Client commands like execute and perform are available via this.


exports.command = function(file, callback) {
  var self = this;
  var imageData;
  var fs = require('fs');

  try {
    var originalData = fs.readFileSync(file);
    var base64Image = new Buffer(originalData, 'binary').toString('base64');
    imageData = 'data:image/jpeg;base64,' + base64Image;
  } catch (err) {
    console.log(err);
    throw "Unable to open file: " + file;
  }

  this.execute(
    function(data) { // execute application specific code
      App.resizePicture(data);
      return true;
    },

    [imageData], // arguments array to be passed

    function(result) {
      if (typeof callback === "function") {
        callback.call(self, result);
      }
    }
  );

  return this;
};

The example above defines a command (e.g. resizePicture.js) which loads an image file as data-URI and calls a method named resizePicture (via .execute()), defined inside the application.

With this command, the test will look something like:


module.exports = {
  "testing resize picture" : function (browser) {
    browser
      .url("http://app.host")
      .waitForElementVisible("body")
      .resizePicture("/var/www/pics/moon.jpg")
      .assert.element(".container .picture-large")
      .end();
  }
};

2) Class-style commands

This is how most of the Nightwatch's own commands are written. Your command module needs to export a class constructor with a command instance method representing the command function. Commands written like this should inherit from EventEmitter and manually signal the complete event, to indicate command completion.

Class-based command methods are run in the context (the value of this) of the class instance. The test api object is available as this.api or this.client.api, where this.client is the Nightwatch instance itself.

The example below is the .pause() command:


var util = require('util');
var events = require('events');

function Pause() {
  events.EventEmitter.call(this);
}

util.inherits(Pause, events.EventEmitter);

Pause.prototype.command = function(ms, cb) {
  var self = this;
  // If we don't pass the milliseconds, the client will
  // be suspended indefinitely
  if (!ms) {
    return this;
  }
  setTimeout(function() {
    // if we have a callback, call it right before the complete event
    if (cb) {
      cb.call(self.client.api);
    }

    self.emit('complete');
  }, ms);

  return this;
};

module.exports = Pause;


The "complete" event

Signaling the complete event needs to be done inside an asynchronous action (e.g. a setTimeout call). Command classes that do not extend EventEmitter will be treated similar to command functions, requiring that the command method calls at least one Nightwatch api method to be able to complete.

Using ES6 classes as custom commands is not supported at the moment. See nightwatchjs#1199 for more details.

Writing Custom Assertions

Nightwatch allows you to even define your own assertions, extending the available .assert and .verify namespaces.

Assertions implement a simple interface which is shared between built-in assertions and custom ones:


exports.assertion = function() {

  /**
   * The message which will be used in the test output and
   * inside the XML reports
   * @type {string}
   */
  this.message;

  /**
   * A value to perform the assertion on. If a function is
   * defined, its result will be used.
   * @type {function|*}
   */
  this.expected;

  /**
   * The method which performs the actual assertion. It is
   * called with the result of the value method as the argument.
   * @type {function}
   */
  this.pass = function(value) {

  };

  /**
   * The method which returns the value to be used on the
   * assertion. It is called with the result of the command's
   * callback as argument.
   * @type {function}
   */
  this.value = function(result) {

  };

  /**
   * Performs a protocol command/action and its result is
   * passed to the value method via the callback argument.
   * @type {function}
   */
  this.command = function(callback) {

    return this;
  };

};

Custom assertions also inherit from EventEmitter. To see some examples, check the assertions module on Github:
/nightwatch/tree/master/lib/selenium/assertions

Custom Reporter

If you'd like to define your own reporter in addition to the built-in ones (stdout and junit-xml) you can do so in two ways:

The --reporter command-line argument

Interface:

module.exports = {
  write : function(results, options, done) {
    done();
  }
};

The reporter method in your external globals file.

See the provided globalsModule.js for an example.

Example:


module.exports = {
  reporter : function(results, done) {
    console.log(results);
    done();
  }
};

Writing Unit Tests

Unit testing in Nightwatch has been refined in version 0.9. Unit tests now written in Nightwatch are also fully compatible with Mocha's Exports interface, so you can use either test runners. In fact, all Nightwatch's unit tests have been rewritten so they can be ran with either Nightwatch or Mocha.

For backwards compatibility reasons, to take advantage of the improved unit testing support you need to set the toggle setting compatible_testcase_support to true in your test settings.

Unit tests written in versions prior to 0.9 will still continue to work however we recommend upgrading them.

Disabling automatic selenium session

Nightwatch automatically attempts to connect to the specified selenium server and create a session. When running unit tests this needs to be disabled by setting the start_session property to false inside the selenium settings group either on the root level or inside a specific environment.

Assertion framework

Starting with 0.9, in the improved support for unit tests, the client object is no longer passed as an argument to the test. The only argument passed now is the done callback to be used for asynchronous tests.

You can use whatever assertion framework you like. Chai.js is quite a good one and very flexible. We use the internal Node.js assert module in the Nightwatch unit tests.

You can still refer the client object via this.client in your tests.

Example

Here's a subset of the unit test for the utils.js Nightwatch module:


var assert = require('assert');
var common = require('../../common.js');
var Utils = common.require('util/utils.js');

module.exports = {
  'test Utils' : {
    testFormatElapsedTime : function() {

      var resultMs = Utils.formatElapsedTime(999);
      assert.equal(resultMs, '999ms');

      var resultSec = Utils.formatElapsedTime(1999);
      assert.equal(resultSec, '1.999s');

      var resultMin = Utils.formatElapsedTime(122299, true);
      assert.equal(resultMin, '2m 2s / 122299ms');
    },

    testMakeFnAsync : function() {
      function asyncFn(cb) {
        cb();
      }

      function syncFn() {}

      var convertedFn = Utils.makeFnAsync(1, syncFn);
      var called = false;
      convertedFn(function() {
        called = true;
      });

      assert.equal(Utils.makeFnAsync(1, asyncFn), asyncFn);
      assert.ok(called);
    }
  }
};

Asynchronous Unit Tests

The argument to the test function is the optional done callback which signals the test is complete. If present, the callback must be called when the async operation finishes.

Example

Here's unit test which checks if Nightwatch throws an error if you don't invoke the done callback within a set time (10 ms).


module.exports = {
  var path = require('path');
  var assert = require('assert');
  var common = require('../../common.js');
  var CommandGlobals = require('../../lib/globals/commands.js');
  var Runner = common.require('runner/run.js');

  module.exports = {
    'testRunner': {
      before: function (done) {
        CommandGlobals.beforeEach.call(this, done);
      },

      after: function (done) {
        CommandGlobals.afterEach.call(this, done);
      },

      beforeEach: function () {
        process.removeAllListeners('exit');
        process.removeAllListeners('uncaughtException');
      },

      'test async unit test with timeout error': function (done) {
        var testsPath = path.join(__dirname, '../../asynchookstests/unittest-async-timeout.js');
        var globals = {
          calls : 0,
          asyncHookTimeout: 10
        };

        process.on('uncaughtException', function (err) {
          assert.ok(err instanceof Error);
          assert.equal(err.message, 'done() callback timeout of 10 ms was reached while executing "demoTest". ' +
            'Make sure to call the done() callback when the operation finishes.');

          done();
        });

        var runner = new Runner([testsPath], {
          seleniumPort: 10195,
          silent: true,
          output: false,
          persist_globals : true,
          globals: globals,
          compatible_testcase_support : true
        }, {
          output_folder : false,
          start_session : false
        });

        runner.run().catch(function(err) {
          done(err);
        });
      }
    }
  };
};

The complete test suite can be viewed on GitHub: https://github.com/nightwatchjs/nightwatch/tree/master/test/src/runner/testRunner.js

Running the Nightwatch unit tests

To get an idea of how running unit tests with Nightwatch works you can head over to our GitHub page, clone the project and follow the instructions on how to run the tests.

You can also check out Nightwatch's own complete test suite for examples: https://github.com/nightwatchjs/nightwatch/tree/master/test/src

Here's the configuration needed to run them:


{
  "src_folders" : ["./test/src"],
  "selenium" : {
    "start_process" : false,
    "start_session" : false
  },

  "test_settings" : {
    "default" : {
      "filter" : "*/.js",
      "compatible_testcase_support" : true
    }
  }
}

Using a Combined Configuration

Below it's an example of how you can combine end-to-end tests and unit tests in the same nightwatch.json configuration file. Notice the usage of exclude and filter properties.

An empty exclude means we want to reset its value and rely only on filter.

{
  "src_folders" : ["./examples/tests", "./examples/unittests"],
  "output_folder" : "./examples/reports",

  "selenium" : {
    "start_process" : true,
    "server_path" : "./bin/selenium-server-standalone.jar",
    "log_path" : "",
    "host" : "127.0.0.1",
    "port" : 4444,
    "cli_args" : {
      "webdriver.chrome.driver" : "",
      "webdriver.ie.driver" : ""
    }
  },

  "test_settings" : {
    "default" : {
      "launch_url" : "http://localhost",
      "selenium_port"  : 4444,
      "selenium_host"  : "localhost",
      "silent": true,
      "screenshots" : {
        "enabled" : false,
        "path" : ""
      },
      "desiredCapabilities": {
        "browserName": "firefox",
        "javascriptEnabled": true,
        "acceptSslCerts": true
      },
      "exclude" : "./examples/unittests/*"
    },

    "unittests" : {
      "selenium" : {
        "start_process" : false,
        "start_session" : false
      },
      "filter" : "./examples/unittests/*",
      "exclude" : ""
    }
  }
}

Code Coverage

At the moment, Nightwatch doesn't provide a coverage reporter but it is something that's being planned for a future release. In the meantime you can write a custom reporter which will output coverage data. See the custom reporter section for details and the Mocha HTMLCov reporter for how the reporter should look like.

3rd party coverage service

There are some hosted services which provide the reporting and metrics for you in a modern web interface. These services will typically require coverage data in LCOV format. Nightwatch uses coveralls.io.

For details on how an LCOV reporter should look like and how to integrate with your project, you can check out the mocha-lcov-reporter.



API Reference


Nightwatch introduces in version 0.7 a new BDD-style interface for performing assertions on elements, defined on the expect namespace on the main Nightwatch instance. It is based on the Chai Expect assertion library and provides a greater level of flexibility and adds new capabilities over the classic assert interface.

It uses a chainable language to construct assertions given an element specified by a css/xpath selector. A simple example looks like the following:


this.demoTest = function (browser) {
  // start with identifying the element
  // and then assert the element is present
  browser.expect.element('#main').to.be.present;

  // or assert the element is visible
  browser.expect.element('#main').to.be.visible;
};

Language Chains

The following are provided as chainable getters to improve the readability of your assertions. They do not provide testing capabilities and the order is not important.

  • to
  • be
  • been
  • is
  • that
  • which
  • and
  • has
  • have
  • with
  • at
  • does
  • of

.equal(value)/.contain(value)/.match(regex)

These methods will perform assertions on the specified target on the current element. The targets can be an attribute value, the element's inner text and a css property.


this.demoTest = function (browser) {
  browser.expect.element('#main').text.to.equal('The Night Watch');

  browser.expect.element('#main').text.to.contain('The Night Watch');

  browser.expect.element('#main').to.have.css('display').which.equals('block');
};

.not

Negates any of assertions following in the chain.


this.demoTest = function (browser) {
  browser.expect.element('#main').text.to.not.equal('The Night Watch');

  browser.expect.element('#main').text.to.not.contain('The Night Watch');

  browser.expect.element('#main').to.have.css('display').which.does.not.equal('block');
};

.before(ms)/.after(ms)

These methods perform the same thing which is essentially retrying the assertion for the given amount of time (in milliseconds). before or after can be chained to any assertion and thus adding retry capability.

You can change the polling interval by defining a waitForConditionPollInterval property (in milliseconds) as a global property in your nightwatch.json or in your external globals file. Similarly, a default timeout can be specified as a global waitForConditionTimeout property (in milliseconds).


this.demoTest = function (browser) {
  browser.expect.element('#main').text.to.contain('The Night Watch').before(1000);

  browser.expect.element('#main').text.to.not.contain('The Night Watch').after(500);
};

.a(type)

Checks if the type (i.e. tag name) of a specified element is of an expected value.

Parameters:
Name Type description
type string The expected type
message
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {
  browser.expect.element('#q').to.be.an('input');
  browser.expect.element('#q').to.be.an('input', 'Testing if #q is an input');
  browser.expect.element('#w').to.be.a('span');
};

.attribute(name)

Checks if a given attribute of an element exists and optionally if it has the expected value.

Parameters:
Name Type description
attribute string The attribute name
message
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {
  browser.expect.element('body').to.have.attribute('data-attr');
  browser.expect.element('body').to.not.have.attribute('data-attr');
  browser.expect.element('body').to.not.have.attribute('data-attr', 'Testing if body does not have data-attr');
  browser.expect.element('body').to.have.attribute('data-attr').before(100);
  browser.expect.element('body').to.have.attribute('data-attr')
    .equals('some attribute');
  browser.expect.element('body').to.have.attribute('data-attr')
    .not.equals('other attribute');
  browser.expect.element('body').to.have.attribute('data-attr')
    .which.contains('something');
  browser.expect.element('body').to.have.attribute('data-attr')
    .which.matches(/^something\ else/);
};

.css(property)

Checks a given css property of an element exists and optionally if it has the expected value.

Parameters:
Name Type description
property string The css property name
message
Optional
string Optional log message to display in the output. If missing, one is displayed by default.*
Usage:

this.demoTest = function (browser) {
  browser.expect.element('#main').to.have.css('display');
  browser.expect.element('#main').to.have.css('display', 'Testing for display');
  browser.expect.element('#main').to.not.have.css('display');
  browser.expect.element('#main').to.have.css('display').before(100);
  browser.expect.element('#main').to.have.css('display').which.equals('block');
  browser.expect.element('#main').to.have.css('display').which.contains('some value');
  browser.expect.element('#main').to.have.css('display').which.matches(/some\ value/);
};

.enabled

Property that checks if an element is currently enabled.

Usage:

this.demoTest = function (browser) {
  browser.expect.element('#weblogin').to.be.enabled;
  browser.expect.element('#main').to.not.be.enabled;
  browser.expect.element('#main').to.be.enabled.before(100);
};

.present

Property that checks if an element is present in the DOM.

Usage:

this.demoTest = function (browser) {
  browser.expect.element('#main').to.be.present;
  browser.expect.element('#main').to.not.be.present;
  browser.expect.element('#main').to.be.present.before(100);
};

.selected

Property that checks if an OPTION element, or an INPUT element of type checkbox or radio button is currently selected.

Usage:

this.demoTest = function (browser) {
  browser.expect.element('#main').to.be.selected;
  browser.expect.element('#main').to.not.be.selected;
  browser.expect.element('#main').to.be.selected.before(100);
};

.text

Property that retrieves the text contained by an element. Can be chained to check if contains/equals/matches the specified text or regex.

Usage:

this.demoTest = function (browser) {
  browser.expect.element('#main').text.to.equal('The Night Watch');
  browser.expect.element('#main').text.to.not.equal('The Night Watch');
  browser.expect.element('#main').text.to.equal('The Night Watch').before(100);
  browser.expect.element('#main').text.to.contain('The Night Watch');
  browser.expect.element('#main').text.to.match(/The\ Night\ Watch/);
};

.value

Property that retrieves the value (i.e. the value attributed) of an element. Can be chained to check if contains/equals/matches the specified text or regex.

Usage:

this.demoTest = function (browser) {
  browser.expect.element('#q').to.have.value.that.equals('search');
  browser.expect.element('#q').to.have.value.not.equals('search');
  browser.expect.element('#q').to.have.value.which.contains('search');
  browser.expect.element('#q').to.have.value.which.matches(/search/);
};

.visible

Property that asserts the visibility of a specified element.

Usage:

this.demoTest = function (browser) {
  browser.expect.element('#main').to.be.visible;
  browser.expect.element('#main').to.not.be.visible;
  browser.expect.element('#main').to.be.visible.before(100);
};

The classic assert/verify library is still available on the Nightwatch instance as two objects containing the same methods to perform assertions on elements:

  • .assert - when an assertion fails, the test ends, skipping all other assertions.
  • .verify - when an assertion fails, the test logs the failure and continues with other assertions.

This will end the test:

client.assert.visible('.non_existing');

But this will just log the failure and continue:

client.verify.visible(".non_existing");

Node.js Assert Module

Nightwatch.js extends Node.js assert module, so you can also use any of the available methods there in your tests.

Automatically retrying failed assertions

You can tell Nightwatch to automatically retry failed assertions until a given timeout is reached, before the test runner gives up and fails the test. This can be accomplished by setting the property retryAssertionTimeout (in milliseconds) in the globals file.

For example: retryAssertionTimeout = 2000

.attributeContains()

Checks if the given attribute of an element contains the expected value.

Parameters:
Name Type description
selector string The selector (CSS / Xpath) used to locate the element.
attribute string The attribute name
expected string The expected contained value of the attribute to check.
message
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.attributeContains('#someElement', 'href', 'google.com');

};

.attributeEquals()

Checks if the given attribute of an element has the expected value.

Parameters:
Name Type description
cssSelector string The CSS selector used to locate the element.
attribute string The attribute name
expected string The expected value of the attribute to check.
msg
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.attributeEquals("body", "data-attr", "some value");

};

.containsText()

Checks if the given element contains the specified text.

Parameters:
Name Type description
cssSelector string The CSS selector used to locate the element.
expectedText string The text to look for.
msg
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.containsText("#main", "The Night Watch");

};

.cssClassPresent()

Checks if the given element has the specified CSS class.

Parameters:
Name Type description
cssSelector string The CSS selector used to locate the element.
className string The CSS class to look for.
msg
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.cssClassPresent("#main", "container");

};

.cssClassNotPresent()

Checks if the given element does not have the specified CSS class.

Parameters:
Name Type description
cssSelector string The CSS selector used to locate the element.
className string The CSS class to look for.
msg
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.cssClassNotPresent("#main", "container");

};

.cssProperty()

Checks if the specified css property of a given element has the expected value.

Parameters:
Name Type description
cssSelector string The CSS selector used to locate the element.
cssProperty string The CSS property.
expected string|number The expected value of the css property to check.
msg
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.cssProperty("#main", "display", "block");

};

.elementPresent()

Checks if the given element exists in the DOM.

Parameters:
Name Type description
cssSelector string The CSS selector used to locate the element.
msg
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.elementPresent("#main");

};

.elementNotPresent()

Checks if the given element does not exist in the DOM.

Parameters:
Name Type description
cssSelector string The CSS selector used to locate the element.
msg
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.elementNotPresent(".should_not_exist");

};

.hidden()

Checks if the given element is not visible on the page.

Parameters:
Name Type description
cssSelector string The CSS selector used to locate the element.
msg
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.hidden(".should_not_be_visible");

};

.title()

Checks if the page title equals the given value.

Parameters:
Name Type description
expected string The expected page title.
msg
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.title("Nightwatch.js");

};

.urlContains()

Checks if the current URL contains the given value.

Parameters:
Name Type description
expectedText string The value expected to exist within the current URL.
msg
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.urlContains('google');

};

.urlEquals()

Checks if the current url equals the given value.

Parameters:
Name Type description
expected string The expected url.
msg
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.urlEquals('http://www.google.com');

};

.value()

Checks if the given form element's value equals the expected value.

Parameters:
Name Type description
cssSelector string The CSS selector used to locate the element.
expectedText string The expected text.
msg
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.value("form.login input[type=text]", "username");

};

.valueContains()

Checks if the given form element's value contains the expected value.

Parameters:
Name Type description
cssSelector string The CSS selector used to locate the element.
expectedText string The expected text.
msg
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.valueContains("form.login input[type=text]", "username");

};

.visible()

Checks if the given element is visible on the page.

Parameters:
Name Type description
cssSelector string The CSS selector used to locate the element.
msg
Optional
string Optional log message to display in the output. If missing, one is displayed by default.
Usage:

this.demoTest = function (browser) {

  browser.assert.visible(".should_be_visible");

};

The commands are convenience methods for performing various operations on the page and usually incorporate two or more WebDriver protocol actions.

The callback function

Each method below allows an optional callback argument to be passed as the last argument. The callback function will then be called after the command is completed with the main instance as the context and the response object as argument.


this.demoTest = function (browser) {

  browser.click("#main ul li a.first", function(response) {
    this.assert.ok(browser === this, "Check if the context is right.");
    this.assert.ok(typeof response == "object", "We got a response object.");
  });

};

.clearValue()

Clear a textarea or a text input element's value. Uses elementIdValue protocol command.

Parameters:
Name Type description
selector string The CSS/Xpath selector used to locate the element.
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

this.demoTest = function (client) {
  client.clearValue('input[type=text]');
};

.click()

Simulates a click event on the given DOM element. Uses elementIdClick protocol command.

Parameters:
Name Type description
selector string The CSS/Xpath selector used to locate the element.
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

this.demoTest = function (client) {
  client.click("#main ul li a.first");
};

.closeWindow()

Close the current window. This can be useful when you're working with multiple windows open (e.g. an OAuth login).
Uses window protocol command.

Parameters:
Name Type description
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

this.demoTest = function (client) {
  client.closeWindow();
};

.deleteCookie()

Delete the cookie with the given name. This command is a no-op if there is no such cookie visible to the current page.

Parameters:
Name Type description
The cookieName name of the cookie to delete.
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

this.demoTest = function(browser) {
  browser.deleteCookie("test_cookie", function() {
    // do something more in here
  });
}

.deleteCookies()

Delete all cookies visible to the current page.

Parameters:
Name Type description
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

this.demoTest = function(browser) {
  browser.deleteCookies(function() {
    // do something more in here
  });
}

.end()

Ends the session. Uses session protocol command.

Parameters:
Name Type description
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

this.demoTest = function (browser) {
  browser.end();
};

.getAttribute()

Retrieve the value of an attribute for a given DOM element. Uses elementIdAttribute protocol command.

Parameters:
Name Type description
selector string The CSS/Xpath selector used to locate the element.
attribute string The attribute name to inspect.
callback function Callback function which is called with the result value.
Returns
Type description
* The value of the attribute
Usage:

this.demoTest = function (client) {
  client.getAttribute("#main ul li a.first", "href", function(result) {
    this.assert.equal(typeof result, "object");
    this.assert.equal(result.status, 0);
    this.assert.equal(result.value, "#home");
  });
};

.getCookie()

Retrieve a single cookie visible to the current page. The cookie is returned as a cookie JSON object, as defined here.

Uses cookie protocol command.

Parameters:
Name Type description
name string The cookie name.
callback function Callback function which is called with the result value.
Returns
Type description
object|null The cookie object as a selenium cookie JSON object or null if the cookie wasn't found.
Usage:

this.demoTest = function(browser) {
  browser.getCookie(name, function callback(result) {
    this.assert.equal(result.value, '123456');
    this.assert.equals(result.name, 'test_cookie');
  });
}

.getCookies()

Retrieve all cookies visible to the current page. The cookies are returned as an array of cookie JSON object, as defined here.

Uses cookie protocol command.

Parameters:
Name Type description
callback function The callback function which will receive the response as an argument.
Returns
Type description
Array.<object> A list of cookies.
Usage:

this.demoTest = function(browser) {
  browser.getCookies(function callback(result) {
    this.assert.equal(result.value.length, 1);
    this.assert.equals(result.value[0].name, 'test_cookie');
  });
}

.getCssProperty()

Retrieve the value of a css property for a given DOM element. Uses elementIdCssProperty protocol command.

Parameters:
Name Type description
selector string The CSS/Xpath selector used to locate the element.
cssProperty string The CSS property to inspect.
callback function Callback function which is called with the result value.
Returns
Type description
* The value of the css property
Usage:

this.demoTest = function (client) {
  client.getCssProperty("#main ul li a.first", "display", function(result) {
    this.assert.equal(typeof result, "object");
    this.assert.equal(result.status, 0);
    this.assert.equal(result.value, 'inline');
  });
};

.getElementSize()

Determine an element's size in pixels. Uses elementIdSize protocol command.

Parameters:
Name Type description
selector string The CSS/Xpath selector used to locate the element.
callback function Callback function which is called with the result value.
Returns
Type description
{width: number, height: number} The width and height of the element in pixels
Usage:

this.demoTest = function (client) {
  client.getElementSize("#main ul li a.first", function(result) {
    this.assert.equal(typeof result, "object");
    this.assert.equal(result.status, 0);
    this.assert.equal(result.value.width, 500);
    this.assert.equal(result.value.height, 20);
 });
};

.getLocation()

Determine an element's location on the page. The point (0, 0) refers to the upper-left corner of the page.

The element's coordinates are returned as a JSON object with x and y properties. Uses elementIdLocation protocol command.

Parameters:
Name Type description
selector string The CSS/Xpath selector used to locate the element.
callback function Callback function which is called with the result value.
Returns
Type description
x:number, y:number The X and Y coordinates for the element on the page.
Usage:

this.demoTest = function (client) {
  client.getLocation("#main ul li a.first", function(result) {
    this.assert.equal(typeof result, "object");
    this.assert.equal(result.status, 0);
    this.assert.equal(result.value.x, 200);
    this.assert.equal(result.value.y, 200);
  });
};

.getLocationInView()

Determine an element's location on the screen once it has been scrolled into view. Uses elementIdLocationInView protocol command.

Parameters:
Name Type description
selector string The CSS/Xpath selector used to locate the element.
callback function Callback function which is called with the result value.
Returns
Type description
x: number, y: number The X and Y coordinates for the element on the page.
Usage:

this.demoTest = function (browser) {
  browser.getLocationInView("#main ul li a.first", function(result) {
    this.assert.equal(typeof result, "object");
    this.assert.equal(result.status, 0);
    this.assert.equal(result.value.x, 200);
    this.assert.equal(result.value.y, 200);
  });
};

.getLog()

Gets a log from selenium.

Parameters:
Name Type description
typeString string|function Log type to request
callback function Callback function which is called with the result value.
Usage:

this.demoTest = function(client) {
  this.getLog('browser', function(logEntriesArray) {
    console.log('Log length: ' + logEntriesArray.length);
    logEntriesArray.forEach(function(log) {
       console.log('[' + log.level + '] ' + log.timestamp + ' : ' + log.message);
     });
  });
};

.getLogTypes()

Gets the available log types. More info about log types in WebDriver can be found here: https://github.com/SeleniumHQ/selenium/wiki/Logging

Parameters:
Name Type description
callback function Callback function which is called with the result value.
Returns
Type description
Array Available log types
Usage:

this.demoTest = function(client) {
  this.getLogTypes(function(typesArray) {
    console.log(typesArray);
  });
};

.getTagName()

Query for an element's tag name. Uses elementIdName protocol command.

Parameters:
Name Type description
selector string The CSS/Xpath selector used to locate the element.
callback function Callback function which is called with the result value.
Returns
Type description
number The element's tag name, as a lowercase string.
Usage:

this.demoTest = function (client) {
  client.getTagName("#main ul li .first", function(result) {
    this.assert.equal(typeof result, "object");
    this.assert.equal(result.status, 0);
    this.assert.equal(result.value, "a");
  });
};

.getText()

Returns the visible text for the element. Uses elementIdText protocol command.

Parameters:
Name Type description
selector string The CSS/Xpath selector used to locate the element.
callback function Callback function which is called with the result value.
Returns
Type description
string The element's visible text.
Usage:

this.demoTest = function (browser) {
  browser.getText("#main ul li a.first", function(result) {
    this.assert.equal(typeof result, "object");
    this.assert.equal(result.status, 0);
    this.assert.equal(result.value, "nightwatchjs.org");
  });
};

.getTitle()

Returns the title of the current page. Uses title protocol command.

Parameters:
Name Type description
callback function Callback function which is called with the result value.
Returns
Type description
string The page title.
Usage:

 this.demoTest = function (browser) {
   browser.getTitle(function(title) {
     this.assert.equal(typeof title, 'string');
     this.assert.equal(title, 'Nightwatch.js');
   });
 };

.getValue()

Returns a form element current value. Uses elementIdValue protocol command.

Parameters:
Name Type description
selector string The CSS/Xpath selector used to locate the element.
callback function Callback function which is called with the result value.
Returns
Type description
string The element's value.
Usage:

this.demoTest = function (browser) {
  browser.getValue("form.login input[type=text]", function(result) {
    this.assert.equal(typeof result, "object");
    this.assert.equal(result.status, 0);
    this.assert.equal(result.value, "enter username");
  });
};

.init()

This command is an alias to url and also a convenience method when called without any arguments in the sense that it performs a call to .url() with passing the value of launch_url field from the settings file.
Uses url protocol command.

Parameters:
Name Type description
url
Optional
string Url to navigate to.
Usage:

this.demoTest = function (client) {
  client.init();
};

.injectScript()

Utility command to load an external script into the page specified by url.

Parameters:
Name Type description
scriptUrl string The script file url
id
Optional
string Dom element id to be set on the script tag.
callback
Optional
function Optional callback function to be called when the command finishes.
Returns
Type description
HTMLScriptElement The newly created script tag.
Usage:

this.demoTest = function(client) {
  this.injectScript("{script-url}", function() {
    // we're all done here.
  });
};

.isLogAvailable()

Utility command to test if the log type is available.

Parameters:
Name Type description
typeString string|function Type of log to test
callback function Callback function which is called with the result value.
Usage:

this.demoTest = function(browser) {
  browser.isLogAvailable('browser', function(isAvailable) {
    // do something more in here
  });
}

.isVisible()

Determine if an element is currently displayed. Uses elementIdDisplayed protocol command.

Parameters:
Name Type description
selector string The CSS/Xpath selector used to locate the element.
callback function Callback function which is called with the result value.
Usage:

this.demoTest = function (browser) {
  browser.isVisible('#main', function(result) {
    this.assert.equal(typeof result, "object");
    this.assert.equal(result.status, 0);
    this.assert.equal(result.value, true);
  });
};

.maximizeWindow()

Maximizes the current window.

Parameters:
Name Type description
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

 this.demoTest = function (browser) {
   browser.maximizeWindow();
 };

.moveToElement()

Move the mouse by an offset of the specified element. Uses moveTo protocol command.

Parameters:
Name Type description
selector string The CSS/Xpath selector used to locate the element.
xoffset number X offset to move to, relative to the top-left corner of the element.
yoffset number Y offset to move to, relative to the top-left corner of the element.
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

this.demoTest = function (browser) {
  browser.moveToElement('#main', 10, 10);
};

.pause()

Suspends the test for the given time in milliseconds. If the milliseconds argument is missing it will suspend the test indefinitely

Parameters:
Name Type description
ms number The number of milliseconds to wait.
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

this.demoTest = function (browser) {
  browser.pause(1000);
  // or suspend indefinitely
  browser.pause();
};

.perform()

A simple perform command which allows access to the "api" in a callback.
Can be useful if you want to read variables set by other commands.

Parameters:
Name Type description
callback function The function to run as part of the queue. Its signature can have up to two parameters. No parameters: callback runs and perform completes immediately at the end of the execution of the callback. One parameter: allows for asynchronous execution within the callback providing a done callback function for completion as the first argument. Two parameters: allows for asynchronous execution with the "api" object passed in as the first argument, followed by the done callback.
Usage:

this.demoTest = function (browser) {
  var elementValue;
  browser
    .getValue('.some-element', function(result) {
      elementValue = result.value;
    })
    // other stuff going on ...
    //
    // self-completing callback
    .perform(function() {
      console.log('elementValue', elementValue);
      // without any defined parameters, perform
      // completes immediately (synchronously)
    })
    //
    // asynchronous completion
    .perform(function(done) {
      console.log('elementValue', elementValue);
      // potentially other async stuff going on
      // on finished, call the done callback
      done();
    })
    //
    // asynchronous completion including api (client)
    .perform(function(client, done) {
      console.log('elementValue', elementValue);
      // similar to before, but now with client
      // potentially other async stuff going on
      // on finished, call the done callback
      done();
    });
};

.resizeWindow()

Resizes the current window.

Parameters:
Name Type description
width number The new window width.
height number The new window height.
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

 this.demoTest = function (browser) {
   browser.resizeWindow(1000, 800);
 };

.saveScreenshot()

Take a screenshot of the current page and saves it as the given filename.

Parameters:
Name Type description
fileName string The complete path to the file name where the screenshot should be saved.
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

 this.demoTest = function (browser) {
   browser.saveScreenshot('/path/to/fileName.png');
 };

.setCookie()

Set a cookie, specified as a cookie JSON object, as defined here.

Uses cookie protocol command.

Parameters:
Name Type description
cookie object The cookie object.
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

this.demoTest = function(browser) {
  browser.setCookie({
    name     : "test_cookie",
    value    : "test_value",
    path     : "/", (Optional)
    domain   : "example.org", (Optional)
    secure   : false, (Optional)
    httpOnly : false, // (Optional)
    expiry   : 1395002765 // (Optional) time in seconds since midnight, January 1, 1970 UTC
  });
}

.setValue()

See sessionsessionidelementidvalue

Sends some text to an element. Can be used to set the value of a form element or to send a sequence of key strokes to an element. Any UTF-8 character may be specified.

An object map with available keys and their respective UTF-8 characters, as defined on W3C WebDriver draft spec, is loaded onto the main Nightwatch instance as client.Keys.

Parameters:
Name Type description
selector string The CSS/Xpath selector used to locate the element.
inputValue string|array The text to send to the element or key strokes.
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

// send some simple text to an input
this.demoTest = function (browser) {
  browser.setValue('input[type=text]', 'nightwatch');
};
//
// send some text to an input and hit enter.
this.demoTest = function (browser) {
  browser.setValue('input[type=text]', ['nightwatch', browser.Keys.ENTER]);
};

.setWindowPosition()

Sets the current window position.

Parameters:
Name Type description
offsetX number The new window offset x-position.
offsetY number The new window offset y-position.
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

 this.demoTest = function (browser) {
   browser.setWindowPosition(0, 0);
 };

.submitForm()

Submit a FORM element. The submit command may also be applied to any element that is a descendant of a FORM element. Uses submit protocol command.

Parameters:
Name Type description
selector string The CSS/Xpath selector used to locate the element.
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

this.demoTest = function (browser) {
  browser.submitForm('form.login');
};

.switchWindow()

Change focus to another window. The window to change focus to may be specified by its server assigned window handle, or by the value of its name attribute.

To find out the window handle use window_handles protocol action

Parameters:
Name Type description
handleOrName string The server assigned window handle or the name attribute.
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

 this.demoTest = function (browser) {
   browser.window_handles(function(result) {
     var handle = result.value[0];
     browser.switchWindow(handle);
   });
 };

.urlHash()

Convenience method that adds the specified hash (i.e. url fragment) to the current value of the launch_url as set in nightwatch.json.

Parameters:
Name Type description
hash string The hash to add/replace to the current url (i.e. the value set in the launch_url property in nightwatch.json).
Usage:

this.demoTest = function (client) {
  client.urlHash('#hashvalue');
  // or
  client.urlHash('hashvalue');
};

.useCss()

Sets the locate strategy for selectors to css selector, therefore every following selector needs to be specified as css.

Parameters:
Name Type description
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

this.demoTest = function (browser) {
  browser
    .useCss() // we're back to CSS now
    .setValue('input[type=text]', 'nightwatch');
};

.useXpath()

Sets the locate strategy for selectors to xpath, therefore every following selector needs to be specified as xpath.

Parameters:
Name Type description
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

this.demoTest = function (browser) {
  browser
    .useXpath() // every selector now must be xpath
    .click("//tr[@data-recordid]/span[text()='Search Text']");
};

.waitForElementNotPresent()

Opposite of waitForElementPresent. Waits a given time in milliseconds for an element to be not present (i.e. removed) in the page before performing any other commands or assertions.

If the element is still present after the specified amount of time, the test fails.

You can change the polling interval by defining a waitForConditionPollInterval property (in milliseconds) in as a global property in your nightwatch.json or in your external globals file.

Similarly, a default timeout can be specified as a global waitForConditionTimeout property (in milliseconds).

Parameters:
Name Type description
selector string The selector (CSS / Xpath) used to locate the element.
time number The number of milliseconds to wait. The runner performs repeated checks every 500 ms.
abortOnFailure
Optional
boolean By the default if the element is not found the test will fail. Set this to false if you wish for the test to continue even if the assertion fails. To set this globally you can define a property `abortOnAssertionFailure` in your globals.
callback
Optional
function Optional callback function to be called when the command finishes.
message
Optional
string Optional message to be shown in the output; the message supports two placeholders: %s for current selector and %d for the time (e.g. Element %s was not in the page for %d ms).
Usage:

this.demoTest = function (browser) {
  browser.waitForElementNotPresent('#dialog', 1000);
};

.waitForElementNotVisible()

Opposite of waitForElementVisible. Waits a given time in milliseconds for an element to be not visible (i.e. hidden but existing) in the page before performing any other commands or assertions.

If the element fails to be hidden in the specified amount of time, the test fails.

You can change the polling interval by defining a waitForConditionPollInterval property (in milliseconds) in as a global property in your nightwatch.json or in your external globals file.

Similarly, a default timeout can be specified as a global waitForConditionTimeout property (in milliseconds).

Parameters:
Name Type description
selector string The selector (CSS / Xpath) used to locate the element.
time number The number of milliseconds to wait. The runner performs repeated checks every 500 ms.
abortOnFailure
Optional
boolean By the default if the element is not found the test will fail. Set this to false if you wish for the test to continue even if the assertion fails. To set this globally you can define a property `abortOnAssertionFailure` in your globals.
callback
Optional
function Optional callback function to be called when the command finishes.
message
Optional
string Optional message to be shown in the output; the message supports two placeholders: %s for current selector and %d for the time (e.g. Element %s was not in the page for %d ms).
Usage:

this.demoTest = function (browser) {
  browser.waitForElementNotVisible('#dialog', 1000);
};

.waitForElementPresent()

Waits a given time in milliseconds for an element to be present in the page before performing any other commands or assertions.

If the element fails to be present in the specified amount of time, the test fails. You can change this by setting abortOnFailure to false.

You can change the polling interval by defining a waitForConditionPollInterval property (in milliseconds) in as a global property in your nightwatch.json or in your external globals file.

Similarly, a default timeout can be specified as a global waitForConditionTimeout property (in milliseconds).

Parameters:
Name Type description
selector string The selector (CSS / Xpath) used to locate the element.
time number The number of milliseconds to wait. The runner performs repeated checks every 500 ms.
abortOnFailure
Optional
boolean By the default if the element is not found the test will fail. Set this to false if you wish for the test to continue even if the assertion fails. To set this globally you can define a property `abortOnAssertionFailure` in your globals.
callback
Optional
function Optional callback function to be called when the command finishes.
message
Optional
string Optional message to be shown in the output; the message supports two placeholders: %s for current selector and %d for the time (e.g. Element %s was not in the page for %d ms).
Usage:

this.demoTest = function (browser) {
  browser.waitForElementPresent('body', 1000);
  // continue if failed
  browser.waitForElementPresent('body', 1000, false);
  // with callback
  browser.waitForElementPresent('body', 1000, function() {
    // do something while we're here
  });
  // custom Spanish message
  browser.waitForElementPresent('body', 1000, 'elemento %s no era presente en %d ms');
  // many combinations possible - the message is always the last argument
  browser.waitForElementPresent('body', 1000, false, function() {}, 'elemento %s no era presente en %d ms');
};

.waitForElementVisible()

Waits a given time in milliseconds for an element to be visible in the page before performing any other commands or assertions.

If the element fails to be present and visible in the specified amount of time, the test fails. You can change this by setting abortOnFailure to false.

You can change the polling interval by defining a waitForConditionPollInterval property (in milliseconds) in as a global property in your nightwatch.json or in your external globals file.

Similarly, a default timeout can be specified as a global waitForConditionTimeout property (in milliseconds).

Parameters:
Name Type description
selector string The selector (CSS / Xpath) used to locate the element.
time number The number of milliseconds to wait. The runner performs repeated checks every 500 ms.
abortOnFailure
Optional
boolean By the default if the element is not found the test will fail. Set this to false if you wish for the test to continue even if the assertion fails. To set this globally you can define a property `abortOnAssertionFailure` in your globals.
callback
Optional
function Optional callback function to be called when the command finishes.
message
Optional
string Optional message to be shown in the output; the message supports two placeholders: %s for current selector and %d for the time (e.g. Element %s was not in the page for %d ms).
Usage:

this.demoTest = function (browser) {
  browser.waitForElementVisible('body', 1000);
  // continue if failed
  browser.waitForElementVisible('body', 1000, false);
  // with callback
  browser.waitForElementVisible('body', 1000, function() {
    // do something while we're here
  });
  // custom Spanish message
  browser.waitForElementVisible('body', 1000, 'elemento %s no era visible en %d ms');
  // many combinations possible - the message is always the last argument
  browser.waitForElementVisible('body', 1000, false, function() {}, 'elemento %s no era visible en %d ms');
};

The protocol commands are most of the times simple mappings to the Selenium JsonWireProtocol endpoints.

Some of them are basic commands (such as url and execute) and others are internal commands being used by Nightwatch commands and assertions.

Sessions

A WebDriver session represents the connection between a local end and a specific remote end. Read more on WebDriver page.

.session()

Get info about, delete or create a new session. Defaults to the current session.

Parameters:
Name Type description
action
Optional
string The http verb to use, can be "get", "post" or "delete". If only the callback is passed, get is assumed by default.
sessionId
Optional
string The id of the session to get info about or delete.
callback
Optional
function Optional callback function to be called when the command finishes.
Usage:

 this.demoTest = function (browser) {
   browser.session(function(result) {
     console.log(result.value);
   });
   //
   browser.session('delete', function(result) {
     console.log(result.value);
   });
   //
   browser.session('delete', '12345-abc', function(result) {
     console.log(result.value);
   });
 };

.sessions()

Returns a list of the currently active sessions.

Parameters:
Name Type description
callback function Callback function which is called with the result value.
Usage:

 this.demoTest = function (browser) {
   browser.sessions(function(result) {
     console.log(result.value);
   });
 };

.timeouts()

Configure the amount of time that a particular type of operation can execute for before they are aborted and a |Timeout| error is returned to the client.

Parameters:
Name Type description
type string The type of operation to set the timeout for. Valid values are: "script" for script timeouts, "implicit" for modifying the implicit wait timeout and "page load" for setting a page load timeout.
ms number The amount of time, in milliseconds, that time-limited commands are permitted to run.
callback
Optional
function Optional callback function to be called when the command finishes.

.timeoutsAsyncScript()

Set the amount of time, in milliseconds, that asynchronous scripts executed by .executeAsync are permitted to run before they are aborted and a |Timeout| error is returned to the client.

Parameters:
Name Type description
ms number The amount of time, in milliseconds, that time-limited commands are permitted to run.
callback
Optional
function Optional callback function to be called when the command finishes.

.timeoutsImplicitWait()

Set the amount of time the driver should wait when searching for elements. If this command is never sent, the driver will default to an implicit wait of 0ms.

Parameters:
Name Type description
ms number The amount of time, in milliseconds, that time-limited commands are permitted to run.
callback
Optional
function Optional callback function to be called when the command finishes.

.status()

Query the server's current status.

Parameters:
Name Type description
callback function Callback function which is called with the result value.

.sessionLog()

Gets the text of the log type specified. To find out the available log types, use .getLogTypes().

Parameters:
Name Type description
typeString string Type of log to request.
callback function Callback function which is called with the result value.
Returns
Type description
Array Array of the text entries of the log.

.sessionLogTypes()

Gets an array of strings for which log types are available. This methods returns the entire WebDriver response, if you are only interested in the logs array, use .getLogTypes() instead.

Parameters:
Name Type description
callback function Callback function which is called with the result value.

Navigation

The commands in this section allow navigation to new URLs and introspection of the currently loaded url.

.url()

Retrieve the URL of the current page or navigate to a new URL.

Parameters:
Name Type description
url
Optional
string|function If missing, it will return the URL of the current page as an argument to the supplied callback.
callback
Optional
Function
Usage:

module.exports = {
 'demo Test' : function(browser) {
    browser.url(function(result) {
      // return the current url
      console.log(result);
    });
    //
    // navigate to new url:
    browser.url('{URL}');
    //
    //
    // navigate to new url:
    browser.url('{URL}', function(result) {
      console.log(result);
    });
  }
};

.back()

Navigate backwards in the browser history, if possible.

Parameters:
Name Type description
callback
Optional
function Optional callback function to be called when the command finishes.

.forward()

Navigate forwards in the browser history, if possible.

Parameters:
Name Type description
callback
Optional
function Optional callback function to be called when the command finishes.

.refresh()

Refresh the current page.

Parameters:
Name Type description
callback
Optional
function Optional callback function to be called when the command finishes.

.title()

Get the current page title.

Parameters:
Name Type description
callback function Callback function which is called with the result value.

Command Contexts

.window()

Change focus to another window or close the current window. Shouldn't normally be used directly, instead .switchWindow() and .closeWindow() should be used.

Parameters:
Name Type description
method string The HTTP method to use. Can be either `POST` (change focus) or `DELETE` (close window).
handleOrName string The window to change focus to.
callback
Optional
function Optional callback function to be called when the command finishes.

.windowHandle()

Retrieve the current window handle.

Parameters:
Name Type description
callback function Callback function which is called with the result value.

.windowHandles()

Retrieve the list of all window handles available to the session.

Parameters:
Name Type description
callback function Callback function which is called with the result value.

.windowMaximize()

Increases the window to the maximum available size without going full-screen.

Parameters:
Name Type description
handleOrName
Optional
string windowHandle URL parameter; if it is "current", the currently active window will be maximized.
callback
Optional
function Optional callback function to be called when the command finishes.

.windowPosition()

Change or get the position of the specified window. If the second argument is a function it will be used as a callback and the call will perform a get request to retrieve the existing window position.

Parameters:
Name Type description
windowHandle string
offsetX number
offsetY number
callback function Callback function which is called with the result value.

.windowSize()

Change or get the size of the specified window. If the second argument is a function it will be used as a callback and the call will perform a get request to retrieve the existing window size.

Parameters:
Name Type description
windowHandle string
width number
height number
callback
Optional
function Optional callback function to be called when the command finishes.

.frame()

Change focus to another frame on the page. If the frame id is missing or null, the server should switch to the page's default content.

Parameters:
Name Type description
frameId
Optional
string|number|null Identifier for the frame to change focus to.
callback
Optional
function Optional callback function to be called when the command finishes.

.frameParent()

Change focus to the parent context. If the current context is the top level browsing context, the context remains unchanged.

Parameters:
Name Type description
callback
Optional
function Optional callback function to be called when the command finishes.

Elements

These are the low level commands that are used to locate elements in the page. Each element has an associated web element reference (a UUID) that uniquely identifies the element across all browsing contexts. More details on elements are available on the WebDriver page.

Details on how WebDriver checks if the element is displayed are available Element Displayedness page.

.element()

Search for an element on the page, starting from the document root. The located element will be returned as a WebElement JSON object.
First argument to be passed is the locator strategy, which is detailed on the WebDriver docs.

Parameters:
Name Type description
using string The locator strategy to use.
value string The search target.
callback function Callback function which is called with the result value.
Usage:

module.exports = {
 'demo Test' : function(browser) {
    browser.element('css selector', 'body', function(res) {
      console.log(res)
    });
  }
};

.elements()

Search for multiple elements on the page, starting from the document root. The located elements will be returned as WebElement JSON objects.
First argument to be passed is the locator strategy, which is detailed on the WebDriver docs.

Parameters:
Name Type description
using string The locator strategy to use.
value string The search target.
callback function Callback function to be invoked with the result when the command finishes.

.elementIdElement()

Search for an element on the page, starting from the identified element. The located element will be returned as a WebElement JSON object.

Parameters:
Name Type description
id string ID of the element to route the command to.
using string The locator strategy to use.
value string The search target.
callback function Callback function which is called with the result value.

.elementIdElements()

Search for multiple elements on the page, starting from the identified element. The located element will be returned as a WebElement JSON objects.

Parameters:
Name Type description
id string ID of the element to route the command to.
using string The locator strategy to use.
value string The search target.
callback function Callback function which is called with the result value.

.elementIdEquals()

Test if two element IDs refer to the same DOM element.

Parameters:
Name Type description
id string ID of the element to route the command to.
otherId string ID of the element to compare against.
callback function Callback function which is called with the result value.

.elementActive()

Get the element on the page that currently has focus.

Parameters:
Name Type description
callback function Callback function which is called with the result value.

Element State

.elementIdAttribute()

Get the value of an element's attribute.

Parameters:
Name Type description
id string ID of the element to route the command to.
attributeName string The attribute name
callback function Callback function which is called with the result value.

.elementIdCssProperty()

Retrieve the computed value of the given CSS property of the given element.

The CSS property to query should be specified using the CSS property name, not the JavaScript property name (e.g. background-color instead of backgroundColor).

Parameters:
Name Type description
id string ID of the element to route the command to.
cssPropertyName string
callback function Callback function which is called with the result value.

.elementIdDisplayed()

Determine if an element is currently displayed.

Parameters:
Name Type description
id string ID of the element to route the command to.
callback function Callback function which is called with the result value.

.elementIdEnabled()

Determine if an element is currently enabled.

Parameters:
Name Type description
id string ID of the element to route the command to.
callback function Callback function which is called with the result value.

.elementIdName()

Retrieve the qualified tag name of the given element.

Parameters:
Name Type description
id string ID of the element to route the command to.
callback function Callback function which is called with the result value.

.elementIdSelected()

Determine if an OPTION element, or an INPUT element of type checkbox or radio button is currently selected.

Parameters:
Name Type description
id string ID of the element to route the command to.
callback function Callback function which is called with the result value.

.elementIdSize()

Determine an element's size in pixels. The size will be returned as a JSON object with width and height properties.

Parameters:
Name Type description
id string ID of the element to route the command to.
callback function Callback function which is called with the result value.

.elementIdText()

Returns the visible text for the element.

Parameters:
Name Type description
id string ID of the element to route the command to.
callback function Callback function which is called with the result value.

Element Interaction

.elementIdClear()

Scrolls into view a submittable element excluding buttons or editable element, and then attempts to clear its value, reset the checked state, or text content.

Parameters:
Name Type description
id string ID of the element to route the command to.
callback
Optional
function Optional callback function to be called when the command finishes.

.elementIdClick()

Scrolls into view the element and clicks the in-view centre point. If the element is not pointer-interactable, an element not interactable error is returned.

Parameters:
Name Type description
id string ID of the element to route the command to.
callback
Optional
function Optional callback function to be called when the command finishes.

.elementIdValue()

Scrolls into view the form control element and then sends the provided keys to the element, or returns the current value of the element. In case the element is not keyboard interactable, an element not interactable error is returned.

Parameters:
Name Type description
id string ID of the element to route the command to.
value
Optional
string|array|none Value to send to element in case of a POST
callback function Callback function which is called with the result value.

.keys()

Send a sequence of key strokes to the active element. The sequence is defined in the same format as the sendKeys command.
An object map with available keys and their respective UTF-8 characters, as defined on W3C WebDriver draft spec, is loaded onto the main Nightwatch instance as client.Keys.

Rather than the setValue, the modifiers are not released at the end of the call. The state of the modifier keys is kept between calls, so mouse interactions can be performed while modifier keys are depressed.

Parameters:
Name Type description
keysToSend Array The keys sequence to be sent.
callback
Optional
function Optional callback function to be called when the command finishes.

.submit()

Submit a FORM element. The submit command may also be applied to any element that is a descendant of a FORM element.

Parameters:
Name Type description
id string ID of the element to route the command to.
callback
Optional
function Optional callback function to be called when the command finishes.

Element Location

.elementIdLocationInView()

Determine an element's location on the screen once it has been scrolled into view.

Parameters:
Name Type description
id string ID of the element to route the command to.
callback
Optional
function Optional callback function to be called when the command finishes.

.elementIdLocation()

Determine an element's location on the page. The point (0, 0) refers to the upper-left corner of the page.

The element's coordinates are returned as a JSON object with x and y properties.

Parameters:
Name Type description
id string ID of the element to route the command to.
callback function Callback function which is called with the result value.
Returns
Type description
x:number, y:number The X and Y coordinates for the element on the page.

Document Handling

.source()

Returns a string serialisation of the DOM of the current page.

Parameters:
Name Type description
callback function Callback function which is called with the result value.

.execute()

Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be synchronous and the result of evaluating the script is returned to the client.
The script argument defines the script to execute in the form of a function body. The value returned by that function will be returned to the client.

The function will be invoked with the provided args array and the values may be accessed via the arguments object in the order specified.

Parameters:
Name Type description
body string|function The function body to be injected.
args Array An array of arguments which will be passed to the function.
callback
Optional
function Optional callback function to be called when the command finishes.
Returns
Type description
* The script result.
Usage:

 this.demoTest = function (browser) {
   browser.execute(function(data) {
     // resize operation
     return true;
   }, [imagedata], function(result) {
     ...
   });
 };

.executeAsync()

Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be asynchronous and the result of evaluating the script is returned to the client.

Asynchronous script commands may not span page loads. If an unload event is fired while waiting for a script result, an error should be returned to the client.

Parameters:
Name Type description
script string|function The function body to be injected.
args Array An array of arguments which will be passed to the function.
callback
Optional
function Optional callback function to be called when the command finishes.
Returns
Type description
* The script result.
Usage:

 this.demoTest = function (browser) {
   browser.executeAsync(function(data, done) {
     someAsyncOperation(function() {
       done(true);
     });
   }, [imagedata], function(result) {
     // ...
   });
 };

Cookies

Retrieve or delete all cookies visible to the current page or set a cookie. Normally this shouldn't be used directly, instead the cookie convenience methods should be used: getCookie, getCookies, setCookie, deleteCookie, deleteCookies.

Parameters:
Name Type description
method string Http method
callbackOrCookie
Optional
function|object Optional callback function to be called when the command finishes.

User Actions

.doubleClick()

Double-clicks at the current mouse coordinates (set by .moveto()).

Parameters:
Name Type description
callback
Optional
function Optional callback function to be called when the command finishes.

.mouseButtonClick()

Click at the current mouse coordinates (set by moveto).

The button can be (0, 1, 2) or ('left', 'middle', 'right'). It defaults to left mouse button, and if you don't pass in a button but do pass in a callback, it will handle it correctly.

Parameters:
Name Type description
button string|number The mouse button
callback
Optional
function Optional callback function to be called when the command finishes.

.mouseButtonDown()

Click and hold the left mouse button (at the coordinates set by the last moveto command). Note that the next mouse-related command that should follow is mouseButtonUp . Any other mouse command (such as click or another call to buttondown) will yield undefined behaviour.

Can be used for implementing drag-and-drop. The button can be (0, 1, 2) or ('left', 'middle', 'right'). It defaults to left mouse button, and if you don't pass in a button but do pass in a callback, it will handle it correctly.

Parameters:
Name Type description
button string|number The mouse button
callback
Optional
function Optional callback function to be called when the command finishes.

.mouseButtonUp()

Releases the mouse button previously held (where the mouse is currently at). Must be called once for every mouseButtonDown command issued.

Can be used for implementing drag-and-drop. The button can be (0, 1, 2) or ('left', 'middle', 'right'). It defaults to left mouse button, and if you don't pass in a button but do pass in a callback, it will handle it correctly.

Parameters:
Name Type description
button string|number The mouse button
callback
Optional
function Optional callback function to be called when the command finishes.

.moveTo()

Move the mouse by an offset of the specificed element. If no element is specified, the move is relative to the current mouse cursor. If an element is provided but no offset, the mouse will be moved to the center of the element.

If the element is not visible, it will be scrolled into view.

Parameters:
Name Type description
element string Opaque ID assigned to the element to move to. If not specified or is null, the offset is relative to current position of the mouse.
xoffset number X offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element.
yoffset number Y offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element.
callback
Optional
function Optional callback function to be called when the command finishes.

User Prompts

.acceptAlert()

Accepts the currently displayed alert dialog. Usually, this is equivalent to clicking on the 'OK' button in the dialog.

Parameters:
Name Type description
callback
Optional
function Optional callback function to be called when the command finishes.

.dismissAlert()

Dismisses the currently displayed alert dialog. For confirm() and prompt() dialogs, this is equivalent to clicking the 'Cancel' button.

For alert() dialogs, this is equivalent to clicking the 'OK' button.

Parameters:
Name Type description
callback
Optional
function Optional callback function to be called when the command finishes.

.getAlertText()

Gets the text of the currently displayed JavaScript alert(), confirm(), or prompt() dialog.

Parameters:
Name Type description
callback function Callback function which is called with the result value.
Returns
Type description
string The text of the currently displayed alert.

.setAlertText()

Sends keystrokes to a JavaScript prompt() dialog.

Parameters:
Name Type description
value string Keystrokes to send to the prompt() dialog
callback
Optional
function Optional callback function to be called when the command finishes.

Screen Capture

.screenshot()

Take a screenshot of the current page.

Parameters:
Name Type description
log_screenshot_data boolean Whether or not the screenshot data should appear in the logs when running with --verbose
callback function Callback function which is called with the result value.

Mobile Related

.getOrientation()

Get the current browser orientation.

Parameters:
Name Type description
callback function Callback function which is called with the result value.
Returns
Type description
string} The current browser orientation: {LANDSCAPE|PORTRAIT

.setOrientation()

Sets the browser orientation.

Parameters:
Name Type description
orientation string The new browser orientation: {LANDSCAPE|PORTRAIT}
callback
Optional
function Optional callback function to be called when the command finishes.

.contexts()

Get a list of the available contexts.

Used by Appium when testing hybrid mobile web apps. More info here: https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/hybrid.md.

Parameters:
Name Type description
callback function Callback function to be called when the command finishes.
Returns
Type description
Array an array of strings representing available contexts, e.g 'WEBVIEW', or 'NATIVE'

.currentContext()

Get current context.

Parameters:
Name Type description
callback function Callback function to be called when the command finishes.
Returns
Type description
string|null a string representing the current context or `null`, representing "no context"

.setContext()

Sets the context.

Parameters:
Name Type description
context string context name to switch to - a string representing an available context.
callback
Optional
function Optional callback function to be called when the command finishes.
Run and manage your Nightwatch tests with absolutely no hassle, no config, no nonsense.

Cloud Testing

NightCloud is Nightwatch's own cloud testing platform which aims to simplify much further the way development teams write, manage and run their automated tests.

Main Features

  • Remote Testing

    Run your tests remotely and free up your develper machine or test server

  • Easy Debugging

    Debug your tests remotely from the Chrome Developer Tools

  • Screenshots & Videos

    Automatic screenshot capture at every test step and video recordings available

  • No Config

    Manage your various test configurations from a friendly UI instead of config files

  • Testcase Management

    Manage your entire Nightwatch test suite in a comprehensive and modern UI

  • Testcase Introspection

    Automatic and inteligent analysis of test cases, with detection of common problems

Stay Updated

NightCloud is not ready for prime time just yet. Sign up below to get access to the private beta.

Your email address:

Contact

Issues

Please report any issues or feature requests at github.com/nightwatchjs/nightwatch/issues.

Questions/Getting Help

You're encouraged to ask any questions you might have regarding the usage of Nightwatch or its API on the Mailing List or on Twitter. In addition, there is a StackOverflow Nightwatch.js tag at your disposal.

Contributing

Contributions to Nightwatch are welcome, but please review the Contributing Guidelines beforehand to avoid your PR getting delayed or declined.

Becoming a Sponsor

Interested in supporting Nightwatch finnancially? Now you can become a sponsor on the excellent OpenCollective platform. Your support can accelerate the development of Nightwatch, allow us to spend more time on issues, new features and documentation.