Nightwatch provides the basic WebDriver protocol mappings and also various composite commands to ensure a more fluent and convenient syntax for writing tests.

  • composite commands - such as getValue or isVisible, usually incorporate two or more WebDriver protocol commands
  • protocol commands - are most of the times simple mappings to the W3C WebDriver protocol or, in some cases, its predecessor - the Selenium JsonWireProtocol protocol.

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

Callback function

Each method below allows a callback argument to be passed as the last argument. The callback function will then be called after the command is completed with the main API (browser) as the context and the response object as argument.


this.demoTest = function (browser) {
  browser.click("#main ul li a.first", function(result) {
    this.assert.ok(browser === this);
    this.assert.ok(typeof result == "object");
  });
};

Promises in callbacks

If the callback happens to return a Promise, the test runner will wait for the promise to settle (i.e. resolve or reject) before continuing with the rest of the commands.


module.exports = {
  demoTest: function (browser) {
    browser
      .init()
      .getText("#main ul li", function(result) {
        return new Promise(function(resolve, reject) {
          setTimeout(function() {
            console.log('Value:', result.value);
            resolve();
          }, 1000);
        });
      })
      .click('#login button');
  },

  demoTestAsync: async function(browser) {
    const text = await browser.init().getText("#main ul li", function(result) {
      return Promise.resolve(result.value);
    });
console.log('The text is', text); } };

Using Chrome DevTools protocol

Both ChromeDriver and EdgeDriver expose some specific commands for working with their respective browsers.

When using ChromeDriver or EdgeDriver it is now possible to execute commands via the Chrome DevTools protocol.

Here's the full list of commands available on the chrome namespace on the browser object:

browser.chrome:

More info:

Example:

describe('Chrome DevTools Example', function() {

  it ('using CDP DOM Snapshot', async function() {
    const dom = await browser.chrome.sendAndGetDevToolsCommand('DOMSnapshot.captureSnapshot', {
       computedStyles: []
    });

    console.log('DOM', dom)
  })
});

Firefox Specific Commands

The FirefoxDriver exposes some specific commands, such as for setting context to run "privileged" javascript code or for working with addons. These are now available on in Nightwatch directly, on the firefox namespace.

browser.firefox:

More info:

Customizing the Firefox Profile

Each Firefox WebDriver instance will be created with an anonymous profile, ensuring browser historys do not share session data (cookies, history, cache, offline storage, etc.).

The profile used for each WebDriver session may be configured using the Options class from Selenium. Nightwatch 2 fully supports options objects created with the selenium-webdriver library.

Pre-existing Firefox profile are not modified; instead WebDriver will create a copy for it to modify. Certain browser preferences are required for WebDriver to function properly and they will always be overwritten.

Installing a Firefox extension:

Let's say you need to install an extension, called Firebug. In your nightwatch.conf.js, you may use the Options class to configure the WebDriver session like so:

const firefox = require('selenium-webdriver/firefox');

const options = new firefox.Options()
  .addExtensions('/path/to/firebug.xpi')
  .setPreference('extensions.firebug.showChromeErrors', true);

module.exports = {
  src_folders: ['tests'],
  test_settings: {
    default: {
      browserName: 'firefox',
      desiredCapabilities: options
    }
  }
};

Or as a function:

module.exports = {
  src_folders: ['tests'],
  test_settings: {
    default: {
      browserName: 'firefox',
      desiredCapabilities() {
        const firefox = require('selenium-webdriver/firefox');

        const options = new firefox.Options()
          .addExtensions('/path/to/firebug.xpi')
          .setPreference('extensions.firebug.showChromeErrors', true);

        return options;
      }
    }
  }
};