Nightmare

A high-level browser automation library

README

Nightmare


Nightmare is a high-level browser automation library from Segment .

The goal is to expose a few simple methods that mimic user actions (like goto, typeand click), with an API that feels synchronous for each block of scripting, rather than deeply nested callbacks. It was originally designed for automating tasks across sites that don't have APIs, but is most often used for UI testing and crawling.

Under the covers it uses Electron , which is similar to PhantomJS but roughly twice as fast and more modern.

⚠️Security Warning:We've implemented many of the security recommendations outlined by Electron to try and keep you safe, but undiscovered vulnerabilities may exist in Electron that could allow a malicious website to execute code on your computer. Avoid visiting untrusted websites.

🛠Migrating to 3.x:You'll want to check out this issue before upgrading. We've worked hard to make improvements to nightmare while limiting the breaking changes and there's a good chance you won't need to do anything.

Niffy is a perceptual diffing tool built on Nightmare. It helps you detect UI changes and bugs across releases of your web app.

Daydream is a complementary chrome extension built by @stevenmiller888 that generates Nightmare scripts for you while you browse.

Many thanks to @matthewmueller and @rosshinkley for their help on Nightmare.

Examples
UI Testing Quick Start
Perceptual Diffing with Niffy & Nightmare

API
Set up an instance
Interact with the page
Extract from the page
Cookies
Proxies
Promises
Extending Nightmare

Usage
Debugging
Additional Resources

Examples


Let's search on DuckDuckGo:

  1. ``` js
  2. const Nightmare = require('nightmare')
  3. const nightmare = Nightmare({ show: true })

  4. nightmare
  5.   .goto('https://duckduckgo.com')
  6.   .type('#search_form_input_homepage', 'github nightmare')
  7.   .click('#search_button_homepage')
  8.   .wait('#r1-0 a.result__a')
  9.   .evaluate(() => document.querySelector('#r1-0 a.result__a').href)
  10.   .end()
  11.   .then(console.log)
  12.   .catch(error => {
  13.     console.error('Search failed:', error)
  14.   })
  15. ```

You can run this with:

  1. ``` shell
  2. npm install --save nightmare
  3. node example.js
  4. ```

Or, let's run some mocha tests:

  1. ``` js
  2. const Nightmare = require('nightmare')
  3. const chai = require('chai')
  4. const expect = chai.expect

  5. describe('test duckduckgo search results', () => {
  6.   it('should find the nightmare github link first', function(done) {
  7.     this.timeout('10s')

  8.     const nightmare = Nightmare()
  9.     nightmare
  10.       .goto('https://duckduckgo.com')
  11.       .type('#search_form_input_homepage', 'github nightmare')
  12.       .click('#search_button_homepage')
  13.       .wait('#links .result__a')
  14.       .evaluate(() => document.querySelector('#links .result__a').href)
  15.       .end()
  16.       .then(link => {
  17.         expect(link).to.equal('https://github.com/segmentio/nightmare')
  18.         done()
  19.       })
  20.   })
  21. })
  22. ```

You can see examples of every function in the tests here .

To get started with UI Testing, check out this quick start guide .

To install dependencies


  1. ``` null
  2. npm install

  3. ```

To run the mocha tests


  1. ``` null
  2. npm test

  3. ```

Node versions


Nightmare is intended to be run on NodeJS 4.x or higher.

API


Nightmare(options)


Creates a new instance that can navigate around the web. The available options are documented here , along with the following nightmare-specific options.

waitTimeout (default: 30s)

Throws an exception if the .wait()didn't return truewithin the set timeframe.

  1. ``` js
  2. const nightmare = Nightmare({
  3.   waitTimeout: 1000 // in ms
  4. })
  5. ```

gotoTimeout (default: 30s)

Throws an exception if the .goto()didn't finish loading within the set timeframe. Note that, even though gotonormally waits for all the resources on a page to load, a timeout exception is only raised if the DOM itself has not yet loaded.

  1. ``` js
  2. const nightmare = Nightmare({
  3.   gotoTimeout: 1000 // in ms
  4. })
  5. ```

loadTimeout (default: infinite)

Forces Nightmare to move on if a page transition caused by an action (eg, .click()) didn't finish within the set timeframe. If loadTimeoutis shorter than gotoTimeout, the exceptions thrown by gotoTimeoutwill be suppressed.

  1. ``` js
  2. const nightmare = Nightmare({
  3.   loadTimeout: 1000 // in ms
  4. })
  5. ```

executionTimeout (default: 30s)

The maximum amount of time to wait for an .evaluate()statement to complete.

  1. ``` js
  2. const nightmare = Nightmare({
  3.   executionTimeout: 1000 // in ms
  4. })
  5. ```

paths

The default system paths that Electron knows about. Here's a list of available paths: https://github.com/atom/electron/blob/master/docs/api/app.md#appgetpathname

You can overwrite them in Nightmare by doing the following:

  1. ``` js
  2. const nightmare = Nightmare({
  3.   paths: {
  4.     userData: '/user/data'
  5.   }
  6. })
  7. ```

switches

The command line switches used by the Chrome browser that are also supported by Electron. Here's a list of supported Chrome command line switches: https://github.com/atom/electron/blob/master/docs/api/chrome-command-line-switches.md

  1. ``` js
  2. const nightmare = Nightmare({
  3.   switches: {
  4.     'proxy-server': '1.2.3.4:5678',
  5.     'ignore-certificate-errors': true
  6.   }
  7. })
  8. ```

electronPath

The path to the prebuilt Electron binary. This is useful for testing on different versions of Electron. Note that Nightmare only supports the version on which this package depends. Use this option at your own risk.

  1. ``` js
  2. const nightmare = Nightmare({
  3.   electronPath: require('electron')
  4. })
  5. ```

dock (OS X)

A boolean to optionally show the Electron icon in the dock (defaults to false). This is useful for testing purposes.

  1. ``` js
  2. const nightmare = Nightmare({
  3.   dock: true
  4. })
  5. ```

openDevTools

Optionally shows the DevTools in the Electron window using true, or use an object hash containing mode: 'detach'to show in a separate window. The hash gets passed to contents.openDevTools() to be handled. This is also useful for testing purposes. Note that this option is honored only if showis set to true.

  1. ``` js
  2. const nightmare = Nightmare({
  3.   openDevTools: {
  4.     mode: 'detach'
  5.   },
  6.   show: true
  7. })
  8. ```

typeInterval (default: 100ms)

How long to wait between keystrokes when using .type().

  1. ``` js
  2. const nightmare = Nightmare({
  3.   typeInterval: 20
  4. })
  5. ```

pollInterval (default: 250ms)

How long to wait between checks for the .wait()condition to be successful.

  1. ``` js
  2. const nightmare = Nightmare({
  3.   pollInterval: 50 //in ms
  4. })
  5. ```

maxAuthRetries (default: 3)

Defines the number of times to retry an authentication when set up with .authenticate().

  1. ``` js
  2. const nightmare = Nightmare({
  3.   maxAuthRetries: 3
  4. })
  5. ```

certificateSubjectName


A string to determine the client certificate selected by electron. If this options is set, the select-client-certificate event will be set to loop through the certificateList and find the first certificate that matches subjectNameon the electron Certificate Object .

  1. ``` js
  2. const nightmare = Nightmare({
  3.   certificateSubjectName: 'tester'
  4. })
  5. ```

.engineVersions()


Gets the versions for Electron and Chromium.

.useragent(useragent)


Sets the useragentused by electron.

.authentication(user, password)


Sets the userand passwordfor accessing a web page using basic authentication. Be sure to set it before calling .goto(url).

.end()


Completes any queue operations, disconnect and close the electron process. Note that if you're using promises, .then()must be called after .end()to run the .end()task. Also note that if using an .end()callback, the .end()call is equivalent to calling .end()followed by .then(fn). Consider:

  1. ``` js
  2. nightmare
  3.   .goto(someUrl)
  4.   .end(() => 'some value')
  5.   //prints "some value"
  6.   .then(console.log)
  7. ```

.halt(error, done)


Clears all queued operations, kills the electron process, and passes error message or 'Nightmare Halted' to an unresolved promise. Done will be called after the process has exited.

Interact with the Page


.goto(url[, headers])


Loads the page at url. Optionally, a headershash can be supplied to set headers on the gotorequest.

When a page load is successful, gotoreturns an object with metadata about the page load, including:

url: The URL that was loaded
code: The HTTP status code (e.g. 200, 404, 500)
method: The HTTP method used (e.g. "GET", "POST")
referrer: The page that the window was displaying prior to this load or an empty string if this is the first page load.
headers: An object representing the response headers for the request as in {header1-name: header1-value, header2-name: header2-value}

If the page load fails, the error will be an object with the following properties:

message: A string describing the type of error
code: The underlying error code describing what went wrong. Note this is NOT the HTTP status code. For possible values, see https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h
details: A string with additional details about the error. This may be null or an empty string.
url: The URL that failed to load

Note that any valid response from a server is considered “successful.” That means things like 404 “not found” errors are successful results for goto. Only things that would cause no page to appear in the browser window, such as no server responding at the given address, the server hanging up in the middle of a response, or invalid URLs, are errors.

You can also adjust how long gotowill wait before timing out by setting the gotoTimeout option on the Nightmare constructor.