function Promise() { [native code] }n/a
action = function () {
var name = arguments[0], childfn, parentfn;
if(arguments.length === 2) {
parentfn = arguments[1];
} else {
parentfn = arguments[2];
childfn = arguments[1];
}
// support functions and objects
// if it's an object, wrap it's
// properties in the queue function
if(parentfn) {
if (typeof parentfn === 'function') {
Nightmare.prototype[name] = queued(name, parentfn);
} else {
if (!~Nightmare.namespaces.indexOf(name)) {
Nightmare.namespaces.push(name);
}
Nightmare.prototype[name] = function() {
var self = this;
return keys(parentfn).reduce(function (obj, key) {
obj[key] = queued(name, parentfn[key]).bind(self)
return obj;
}, {});
}
}
}
if(childfn) {
if (typeof childfn === 'function') {
Nightmare.childActions[name] = childfn;
} else {
for(var key in childfn){
Nightmare.childActions[name+'.'+key] = childfn;
}
}
}
}...
var Promise = require('bluebird');
var nightmare = Nightmare({ Promise });
```
### Extending Nightmare
#### Nightmare.action(name, [electronAction|electronNamespace], action|namespace)
You can add your own custom actions to the Nightmare prototype. Here's an example:
```js
Nightmare.action('size', function (done) {
this.evaluate_now(function() {
var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0)
...function FrameManager(window) {
if (!(this instanceof FrameManager)) return new FrameManager(window);
EventEmitter.call(this);
var subscribed = false;
var requestedFrame = false;
var frameRequestTimeout;
var self = this;
this.on('newListener', subscribe);
this.on('removeListener', unsubscribe);
function subscribe(eventName) {
if (!subscribed && eventName === 'data') {
parent.emit('log', 'subscribing to browser window frames');
window.webContents.beginFrameSubscription(receiveFrame);
}
}
function unsubscribe() {
if (!self.listenerCount('data')) {
parent.emit('log', 'unsubscribing from browser window frames')
window.webContents.endFrameSubscription();
subscribed = false;
}
}
function receiveFrame(buffer) {
requestedFrame = false;
clearTimeout(frameRequestTimeout);
self.emit('data', buffer);
}
/**
* In addition to listening for events, calling `requestFrame` will ensure
* that a frame is queued up to render (instead of just waiting for the next
* time the browser chooses to draw a frame).
* @param {Function} [callback] Called when the frame is rendered.
* @param {Number} [timeout=1000] If no frame has been rendered after this
many milliseconds, run the callback anyway. In this case, The
callback's first argument, an image buffer, will be `null`.
*/
this.requestFrame = function(callback, timeout) {
timeout = (timeout == undefined) ? 1000 : timeout;
if (callback) {
this.once('data', callback);
}
if (!requestedFrame) {
requestedFrame = true;
// Force the browser to render new content by using the debugger to
// highlight a portion of the page. This way, we can guarantee a change
// that both requires rendering a frame and does not actually affect
// the content of the page.
if (!window.webContents.debugger.isAttached()) {
try {
window.webContents.debugger.attach();
}
catch (error) {
parent.emit('log', `Failed to attach to debugger for frame subscriptions: ${error}`);
this.emit('data', null);
return;
}
}
if (timeout) {
frameRequestTimeout = setTimeout(function() {
parent.emit('log', `FrameManager timing out after ${timeout} ms with no new rendered frames`);
self.emit('data', null)
}, timeout);
}
parent.emit('log', 'Highlighting page to trigger rendering.');
window.webContents.debugger.sendCommand('DOM.enable')
window.webContents.debugger.sendCommand(
'DOM.highlightRect', HIGHLIGHT_STYLE, function(error) {
window.webContents.debugger.sendCommand('DOM.hideHighlight');
window.webContents.debugger.detach();
});
}
};
}n/a
authentication = function (login, password, done) {
debug('.authentication()');
this.child.call('authentication', login, password, done);
}...
#### .engineVersions()
Gets the versions for Electron and Chromium.
#### .useragent(useragent)
Set the `useragent` used by electron.
#### .authentication(user, password)
Set the `user` and `password` for accessing a web page using basic authentication. Be sure to set it before calling `.goto(url)`.
#### .end()
Complete 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 a `.end()` callback, the `.end()` call is equivalent
to calling `.end()` followed by `.then(fn)`. Consider:
```js
nightmare
...back = function (done) {
debug('.back()');
this.evaluate_now(function() {
window.history.back();
}, done);
}...
- `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 `goto` will wait before timing out by setting the [`gotoTimeout` option](#gototimeout-default-30s)
on the Nightmare constructor.
#### .back()
Go back to the previous page.
#### .forward()
Go forward to the next page.
#### .refresh()
Refresh the current page.
...check = function (selector, done) {
debug('.check() ' + selector);
this.evaluate_now(function(selector) {
var element = document.querySelector(selector);
var event = document.createEvent('HTMLEvents');
element.checked = true;
event.initEvent('change', true, true);
element.dispatchEvent(event);
}, done, selector);
}...
> If you don't need the keyboard events, consider using `.insert()` instead as it will be faster and more robust.
#### .insert(selector[, text])
Similar to `.type()`. `.insert()` enters the `text` provided into the `selector` element. Empty or falsey values provided for `
text` will clear the selector's value.
`.insert()` is faster than `.type()` but does not trigger the keyboard events.
#### .check(selector)
checks the `selector` checkbox element.
#### .uncheck(selector)
unchecks the `selector` checkbox element.
#### .select(selector, option)
Changes the `selector` dropdown element to the option with attribute [value=`option`]
...click = function (selector, done) {
debug('.click() on ' + selector);
this.evaluate_now(function (selector) {
document.activeElement.blur();
var element = document.querySelector(selector);
if (!element) {
throw new Error('Unable to find element by selector: ' + selector);
}
var event = document.createEvent('MouseEvent');
event.initEvent('click', true, true);
element.dispatchEvent(event);
}, done, selector);
}...
```js
var Nightmare = require('nightmare');
var nightmare = Nightmare({ show: true });
nightmare
.goto('https://duckduckgo.com')
.type('#search_form_input_homepage', 'github nightmare')
.click('#search_button_homepage')
.wait('#zero_click_wrapper .c-info__title a')
.evaluate(function () {
return document.querySelector('#zero_click_wrapper .c-info__title a').href;
})
.end()
.then(function (result) {
console.log(result);
...engineVersions = function (done){
debug('.engineVersions()');
done(null, this.engineVersions);
}...
Defines the number of times to retry an authentication when set up with `.authenticate()`.
```js
var nightmare = Nightmare({
maxAuthRetries: 3
});
```
#### .engineVersions()
Gets the versions for Electron and Chromium.
#### .useragent(useragent)
Set the `useragent` used by electron.
#### .authentication(user, password)
Set the `user` and `password` for accessing a web page using basic authentication. Be sure to set it before calling `.goto(url)`.
...evaluate = function (fn) {
var args = sliced(arguments);
var done = args[args.length-1];
var self = this;
var newDone = function(){
clearTimeout(timeoutTimer);
done.apply(self, arguments);
};
var newArgs = [fn, newDone].concat(args.slice(1,-1));
if (typeof fn !== 'function') {
return done(new Error('.evaluate() fn should be a function'));
}
debug('.evaluate() fn on the page');
var timeoutTimer = setTimeout(function(){
done(new Error(`Evaluation timed out after ${self.options.executionTimeout}msec. Are you calling done() or resolving your promises
?`));
}, self.options.executionTimeout);
this.evaluate_now.apply(this, newArgs);
}...
var nightmare = Nightmare({ show: true });
nightmare
.goto('https://duckduckgo.com')
.type('#search_form_input_homepage', 'github nightmare')
.click('#search_button_homepage')
.wait('#zero_click_wrapper .c-info__title a')
.evaluate(function () {
return document.querySelector('#zero_click_wrapper .c-info__title a').href;
})
.end()
.then(function (result) {
console.log(result);
})
.catch(function (error) {
...exists = function (selector, done) {
debug('.exists() for ' + selector);
this.evaluate_now(function(selector) {
return (document.querySelector(selector)!==null);
}, done, selector);
}...
Wait until the `fn` evaluated on the page with `arg1, arg2,...` returns `true`. All the `args` are optional. See `.evaluate()` for
usage.
#### .header([header, value])
Add a header override for all HTTP requests. If `header` is undefined, the header overrides will be reset.
### Extract from the Page
#### .exists(selector)
Returns whether the selector exists or not on the page.
#### .visible(selector)
Returns whether the selector is visible or not
#### .on(event, callback)
Capture page events with the callback. You have to call `.on()` before calling `.goto()`. Supported events are [documented here](
http://electron.atom.io/docs/api/web-contents/#instance-events).
...forward = function (done) {
debug('.forward()');
this.evaluate_now(function() {
window.history.forward();
}, done);
}...
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 `goto` will wait before timing out by setting the [`gotoTimeout` option](#gototimeout-default-30s)
on the Nightmare constructor.
#### .back()
Go back to the previous page.
#### .forward()
Go forward to the next page.
#### .refresh()
Refresh the current page.
#### .click(selector)
Clicks the `selector` element once.
...html = function (path, saveType, done) {
debug('.html()');
if (typeof path === 'function' && !saveType && !done) {
done = path;
saveType = undefined;
path = undefined;
} else if (typeof path === 'object' && typeof saveType === 'function' && !done) {
done = saveType;
saveType = path;
path = undefined;
} else if (typeof saveType === 'function' && !done) {
done = saveType;
saveType = undefined;
}
this.child.call('html', path, saveType, function (error) {
if (error) debug(error);
done(error);
});
}...
#### .removeListener(event, callback)
Removes a given listener callback for an event.
#### .screenshot([path][, clip])
Takes a screenshot of the current page. Useful for debugging. The output is always a `png`. Both arguments are optional. If `path
` is provided, it saves the image to the disk. Otherwise it returns a `Buffer` of the image data. If `clip` is provided (as [documented
here](https://github.com/atom/electron/blob/master/docs/api/browser-window.md#wincapturepagerect-callback)), the image will be
clipped to the rectangle.
#### .html(path, saveType)
Save the current page as html as files to disk at the given path. Save type options are [here](https://github.com/atom/electron/
blob/master/docs/api/web-contents.md#webcontentssavepagefullpath-savetype-callback).
#### .pdf(path, options)
Saves a PDF to the specified `path`. Options are [here](https://github.com/electron/electron/blob/v1.4.4/docs/api/web-contents.md
#contentsprinttopdfoptions-callback).
#### .title()
Returns the title of the current page.
...inject = function (type, file, done) {
debug('.inject()-ing a file');
if (type === 'js') {
var js = fs.readFileSync(file, { encoding: 'utf-8' });
this._inject(js, done);
}
else if (type === 'css') {
var css = fs.readFileSync(file, { encoding: 'utf-8' });
this.child.call('css', css, done);
}
else {
debug('unsupported file type in .inject()');
done();
}
}...
#### .scrollTo(top, left)
Scrolls the page to desired position. `top` and `left` are always relative to the top left corner of the document.
#### .viewport(width, height)
Set the viewport size.
#### .inject(type, file)
Inject a local `file` onto the current page. The file `type` must be either `js` or `css`.
#### .evaluate(fn[, arg1, arg2,...])
Invokes `fn` on the page with `arg1, arg2,...`. All the `args` are optional. On completion it returns the return value of `fn`.
Useful for extracting information from the page. Here's an example:
```js
var selector = 'h1';
...insert = function (selector, text, done) {
if (arguments.length === 2) {
done = text
text = null
}
debug('.insert() %s into %s', text, selector);
var child = this.child;
focusSelector.bind(this)(function(err) {
if(err) {
debug('Unable to .insert() into non-existent selector %s', selector);
return done(err);
}
var blurDone = blurSelector.bind(this, done, selector);
if ((text || '') == '') {
this.evaluate_now(function(selector) {
document.querySelector(selector).value = '';
}, blurDone, selector);
} else {
child.call('insert', text, blurDone);
}
}, selector);
}...
#### .type(selector[, text])
Enters the `text` provided into the `selector` element. Empty or falsey values provided for `text` will clear the selector'
;s value.
`.type()` mimics a user typing in a textbox and will emit the proper keyboard events
Key presses can also be fired using Unicode values with `.type()`. For example, if you wanted to fire an enter key press, you would
write `.type('body', '\u000d')`.
> If you don't need the keyboard events, consider using `.insert()` instead
as it will be faster and more robust.
#### .insert(selector[, text])
Similar to `.type()`. `.insert()` enters the `text` provided into the `selector` element. Empty or falsey values provided for `
text` will clear the selector's value.
`.insert()` is faster than `.type()` but does not trigger the keyboard events.
#### .check(selector)
...mousedown = function (selector, done) {
debug('.mousedown() on ' + selector);
this.evaluate_now(function (selector) {
var element = document.querySelector(selector);
if (!element) {
throw new Error('Unable to find element by selector: ' + selector);
}
var event = document.createEvent('MouseEvent');
event.initEvent('mousedown', true, true);
element.dispatchEvent(event);
}, done, selector);
}...
#### .refresh()
Refresh the current page.
#### .click(selector)
Clicks the `selector` element once.
#### .mousedown(selector)
Mousedown the `selector` element once.
#### .mouseup(selector)
Mouseup the `selector` element once.
#### .mouseover(selector)
Mouseover the `selector` element once.
...mouseover = function (selector, done) {
debug('.mouseover() on ' + selector);
this.evaluate_now(function (selector) {
var element = document.querySelector(selector);
if (!element) {
throw new Error('Unable to find element by selector: ' + selector);
}
var event = document.createEvent('MouseEvent');
event.initMouseEvent('mouseover', true, true);
element.dispatchEvent(event);
}, done, selector);
}...
#### .mousedown(selector)
Mousedown the `selector` element once.
#### .mouseup(selector)
Mouseup the `selector` element once.
#### .mouseover(selector)
Mouseover the `selector` element once.
#### .type(selector[, text])
Enters the `text` provided into the `selector` element. Empty or falsey values provided for `text` will clear the selector'
;s value.
`.type()` mimics a user typing in a textbox and will emit the proper keyboard events
...mouseup = function (selector, done) {
debug('.mouseup() on ' + selector);
this.evaluate_now(function (selector) {
var element = document.querySelector(selector);
if (!element) {
throw new Error('Unable to find element by selector: ' + selector);
}
var event = document.createEvent('MouseEvent');
event.initEvent('mouseup', true, true);
element.dispatchEvent(event);
}, done, selector);
}...
#### .click(selector)
Clicks the `selector` element once.
#### .mousedown(selector)
Mousedown the `selector` element once.
#### .mouseup(selector)
Mouseup the `selector` element once.
#### .mouseover(selector)
Mouseover the `selector` element once.
#### .type(selector[, text])
Enters the `text` provided into the `selector` element. Empty or falsey values provided for `text` will clear the selector'
;s value.
...path = function (done) {
debug('.path() getting it');
this.evaluate_now(function() {
return document.location.pathname;
}, done);
}...
#### .title()
Returns the title of the current page.
#### .url()
Returns the url of the current page.
#### .path()
Returns the path name of the current page.
### Cookies
#### .cookies.get(name)
Get a cookie by it's `name`. The url will be the current url.
...pdf = function (path, options, done) {
debug('.pdf()');
if (typeof path === 'function' && !options && !done) {
done = path;
options = undefined;
path = undefined;
} else if (typeof path === 'object' && typeof options === 'function' && !done){
done = options;
options = path;
path = undefined;
} else if (typeof options === 'function' && !done) {
done = options;
options = undefined;
}
this.child.call('pdf', path, options, function (error, pdf) {
if (error) debug(error);
var buf = new Buffer(pdf.data);
debug('.pdf() captured with length %s', buf.length);
path ? fs.writeFile(path, buf, done) : done(null, buf);
});
}...
#### .screenshot([path][, clip])
Takes a screenshot of the current page. Useful for debugging. The output is always a `png`. Both arguments are optional. If `path
` is provided, it saves the image to the disk. Otherwise it returns a `Buffer` of the image data. If `clip` is provided (as [documented
here](https://github.com/atom/electron/blob/master/docs/api/browser-window.md#wincapturepagerect-callback)), the image will be
clipped to the rectangle.
#### .html(path, saveType)
Save the current page as html as files to disk at the given path. Save type options are [here](https://github.com/atom/electron/
blob/master/docs/api/web-contents.md#webcontentssavepagefullpath-savetype-callback).
#### .pdf(path, options)
Saves a PDF to the specified `path`. Options are [here](https://github.com/electron/electron/blob/v1.4.4/docs/api/web-contents.md
#contentsprinttopdfoptions-callback).
#### .title()
Returns the title of the current page.
#### .url()
Returns the url of the current page.
...refresh = function (done) {
debug('.refresh()');
this.evaluate_now(function() {
window.location.reload();
}, done);
}...
#### .back()
Go back to the previous page.
#### .forward()
Go forward to the next page.
#### .refresh()
Refresh the current page.
#### .click(selector)
Clicks the `selector` element once.
#### .mousedown(selector)
Mousedown the `selector` element once.
...screenshot = function (path, clip, done) {
debug('.screenshot()');
if (typeof path === 'function') {
done = path;
clip = undefined;
path = undefined;
} else if (typeof clip === 'function') {
done = clip;
clip = (typeof path === 'string') ? undefined : path;
path = (typeof path === 'string') ? path : undefined;
}
this.child.call('screenshot', path, clip, function (error, img) {
var buf = new Buffer(img.data);
debug('.screenshot() captured with length %s', buf.length);
path ? fs.writeFile(path, buf, done) : done(null, buf);
});
}...
#### .once(event, callback)
Similar to `.on()`, but captures page events with the callback one time.
#### .removeListener(event, callback)
Removes a given listener callback for an event.
#### .screenshot([path][, clip])
Takes a screenshot of the current page. Useful for debugging. The output is always a `png`. Both arguments are optional. If `path
` is provided, it saves the image to the disk. Otherwise it returns a `Buffer` of the image data. If `clip` is provided (as [documented
here](https://github.com/atom/electron/blob/master/docs/api/browser-window.md#wincapturepagerect-callback)), the image will be
clipped to the rectangle.
#### .html(path, saveType)
Save the current page as html as files to disk at the given path. Save type options are [here](https://github.com/atom/electron/
blob/master/docs/api/web-contents.md#webcontentssavepagefullpath-savetype-callback).
#### .pdf(path, options)
Saves a PDF to the specified `path`. Options are [here](https://github.com/electron/electron/blob/v1.4.4/docs/api/web-contents.md
#contentsprinttopdfoptions-callback).
...scrollTo = function (y, x, done) {
debug('.scrollTo()');
this.evaluate_now(function (y, x) {
window.scrollTo(x, y);
}, done, y, x);
}...
#### .uncheck(selector)
unchecks the `selector` checkbox element.
#### .select(selector, option)
Changes the `selector` dropdown element to the option with attribute [value=`option`]
#### .scrollTo(top, left)
Scrolls the page to desired position. `top` and `left` are always relative to the top left corner of the document.
#### .viewport(width, height)
Set the viewport size.
#### .inject(type, file)
...select = function (selector, option, done) {
debug('.select() ' + selector);
this.evaluate_now(function(selector, option) {
var element = document.querySelector(selector);
var event = document.createEvent('HTMLEvents');
element.value = option;
event.initEvent('change', true, true);
element.dispatchEvent(event);
}, done, selector, option);
}...
#### .check(selector)
checks the `selector` checkbox element.
#### .uncheck(selector)
unchecks the `selector` checkbox element.
#### .select(selector, option)
Changes the `selector` dropdown element to the option with attribute [value=`option`]
#### .scrollTo(top, left)
Scrolls the page to desired position. `top` and `left` are always relative to the top left corner of the document.
#### .viewport(width, height)
...title = function (done) {
debug('.title() getting it');
this.evaluate_now(function() {
return document.title;
}, done);
}...
#### .html(path, saveType)
Save the current page as html as files to disk at the given path. Save type options are [here](https://github.com/atom/electron/
blob/master/docs/api/web-contents.md#webcontentssavepagefullpath-savetype-callback).
#### .pdf(path, options)
Saves a PDF to the specified `path`. Options are [here](https://github.com/electron/electron/blob/v1.4.4/docs/api/web-contents.md
#contentsprinttopdfoptions-callback).
#### .title()
Returns the title of the current page.
#### .url()
Returns the url of the current page.
#### .path()
Returns the path name of the current page.
...type = function () {
var selector = arguments[0], text, done;
if(arguments.length == 2) {
done = arguments[1];
} else {
text = arguments[1];
done = arguments[2];
}
debug('.type() %s into %s', text, selector);
var self = this;
focusSelector.bind(this)(function(err) {
if(err) {
debug('Unable to .type() into non-existent selector %s', selector);
return done(err);
}
var blurDone = blurSelector.bind(this, done, selector);
if ((text || '') == '') {
this.evaluate_now(function(selector) {
document.querySelector(selector).value = '';
}, blurDone, selector);
} else {
self.child.call('type', text, blurDone);
}
}, selector);
}...
```js
var Nightmare = require('nightmare');
var nightmare = Nightmare({ show: true });
nightmare
.goto('https://duckduckgo.com')
.type('#search_form_input_homepage', 'github nightmare')
.click('#search_button_homepage')
.wait('#zero_click_wrapper .c-info__title a')
.evaluate(function () {
return document.querySelector('#zero_click_wrapper .c-info__title a').href;
})
.end()
.then(function (result) {
...uncheck = function (selector, done){
debug('.uncheck() ' + selector);
this.evaluate_now(function(selector) {
var element = document.querySelector(selector);
var event = document.createEvent('HTMLEvents');
element.checked = null;
event.initEvent('change', true, true);
element.dispatchEvent(event);
}, done, selector);
}...
Similar to `.type()`. `.insert()` enters the `text` provided into the `selector` element. Empty or falsey values provided for `
text` will clear the selector's value.
`.insert()` is faster than `.type()` but does not trigger the keyboard events.
#### .check(selector)
checks the `selector` checkbox element.
#### .uncheck(selector)
unchecks the `selector` checkbox element.
#### .select(selector, option)
Changes the `selector` dropdown element to the option with attribute [value=`option`]
#### .scrollTo(top, left)
Scrolls the page to desired position. `top` and `left` are always relative to the top left corner of the document.
...url = function (done) {
debug('.url() getting it');
this.evaluate_now(function() {
return document.location.href;
}, done);
}...
#### .pdf(path, options)
Saves a PDF to the specified `path`. Options are [here](https://github.com/electron/electron/blob/v1.4.4/docs/api/web-contents.md
#contentsprinttopdfoptions-callback).
#### .title()
Returns the title of the current page.
#### .url()
Returns the url of the current page.
#### .path()
Returns the path name of the current page.
### Cookies
...useragent = function (useragent, done) {
debug('.useragent() to ' + useragent);
this.child.call('useragent', useragent, done);
}...
maxAuthRetries: 3
});
```
#### .engineVersions()
Gets the versions for Electron and Chromium.
#### .useragent(useragent)
Set the `useragent` used by electron.
#### .authentication(user, password)
Set the `user` and `password` for accessing a web page using basic authentication. Be sure to set it before calling `.goto(url)`.
#### .end()
Complete 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 a `.end()` callback, the `.end()` call is equivalent
to calling `.end()` followed by `.then(fn)`. Consider:
...viewport = function (width, height, done) {
debug('.viewport()');
this.child.call('size', width, height, done);
}...
#### .select(selector, option)
Changes the `selector` dropdown element to the option with attribute [value=`option`]
#### .scrollTo(top, left)
Scrolls the page to desired position. `top` and `left` are always relative to the top left corner of the document.
#### .viewport(width, height)
Set the viewport size.
#### .inject(type, file)
Inject a local `file` onto the current page. The file `type` must be either `js` or `css`.
#### .evaluate(fn[, arg1, arg2,...])
...visible = function (selector, done) {
debug('.visible() for ' + selector);
this.evaluate_now(function(selector) {
var elem = document.querySelector(selector);
if (elem) return (elem.offsetWidth > 0 && elem.offsetHeight > 0);
else return false;
}, done, selector);
}...
Add a header override for all HTTP requests. If `header` is undefined, the header overrides will be reset.
### Extract from the Page
#### .exists(selector)
Returns whether the selector exists or not on the page.
#### .visible(selector)
Returns whether the selector is visible or not
#### .on(event, callback)
Capture page events with the callback. You have to call `.on()` before calling `.goto()`. Supported events are [documented here](
http://electron.atom.io/docs/api/web-contents/#instance-events).
##### Additional "page" events
...wait = function () {
var args = sliced(arguments);
var done = args[args.length-1];
if (args.length < 2) {
debug('Not enough arguments for .wait()');
return done();
}
var arg = args[0];
if (typeof arg === 'number') {
debug('.wait() for ' + arg + 'ms');
if(arg < this.options.waitTimeout){
waitms(arg, done);
} else {
waitms(this.options.waitTimeout, function(){
done(new Error('.wait() timed out after '+this.options.waitTimeout+'msec'));
}.bind(this));
}
}
else if (typeof arg === 'string') {
var timeout = null;
if (typeof args[1] === 'number') {
timeout = args[1];
}
debug('.wait() for '+arg+' element'+(timeout ? ' or '+timeout+'msec' : ''));
waitelem.apply({ timeout: timeout }, [this, arg, done]);
}
else if (typeof arg === 'function') {
debug('.wait() for fn');
args.unshift(this);
waitfn.apply(this, args);
}
else {
done();
}
}...
var Nightmare = require('nightmare');
var nightmare = Nightmare({ show: true });
nightmare
.goto('https://duckduckgo.com')
.type('#search_form_input_homepage', 'github nightmare')
.click('#search_button_homepage')
.wait('#zero_click_wrapper .c-info__title a')
.evaluate(function () {
return document.querySelector('#zero_click_wrapper .c-info__title a').href;
})
.end()
.then(function (result) {
console.log(result);
})
...function FrameManager(window) {
if (!(this instanceof FrameManager)) return new FrameManager(window);
EventEmitter.call(this);
var subscribed = false;
var requestedFrame = false;
var frameRequestTimeout;
var self = this;
this.on('newListener', subscribe);
this.on('removeListener', unsubscribe);
function subscribe(eventName) {
if (!subscribed && eventName === 'data') {
parent.emit('log', 'subscribing to browser window frames');
window.webContents.beginFrameSubscription(receiveFrame);
}
}
function unsubscribe() {
if (!self.listenerCount('data')) {
parent.emit('log', 'unsubscribing from browser window frames')
window.webContents.endFrameSubscription();
subscribed = false;
}
}
function receiveFrame(buffer) {
requestedFrame = false;
clearTimeout(frameRequestTimeout);
self.emit('data', buffer);
}
/**
* In addition to listening for events, calling `requestFrame` will ensure
* that a frame is queued up to render (instead of just waiting for the next
* time the browser chooses to draw a frame).
* @param {Function} [callback] Called when the frame is rendered.
* @param {Number} [timeout=1000] If no frame has been rendered after this
many milliseconds, run the callback anyway. In this case, The
callback's first argument, an image buffer, will be `null`.
*/
this.requestFrame = function(callback, timeout) {
timeout = (timeout == undefined) ? 1000 : timeout;
if (callback) {
this.once('data', callback);
}
if (!requestedFrame) {
requestedFrame = true;
// Force the browser to render new content by using the debugger to
// highlight a portion of the page. This way, we can guarantee a change
// that both requires rendering a frame and does not actually affect
// the content of the page.
if (!window.webContents.debugger.isAttached()) {
try {
window.webContents.debugger.attach();
}
catch (error) {
parent.emit('log', `Failed to attach to debugger for frame subscriptions: ${error}`);
this.emit('data', null);
return;
}
}
if (timeout) {
frameRequestTimeout = setTimeout(function() {
parent.emit('log', `FrameManager timing out after ${timeout} ms with no new rendered frames`);
self.emit('data', null)
}, timeout);
}
parent.emit('log', 'Highlighting page to trigger rendering.');
window.webContents.debugger.sendCommand('DOM.enable')
window.webContents.debugger.sendCommand(
'DOM.highlightRect', HIGHLIGHT_STYLE, function(error) {
window.webContents.debugger.sendCommand('DOM.hideHighlight');
window.webContents.debugger.detach();
});
}
};
}n/a
function EventEmitter() {
EventEmitter.init.call(this);
}n/a
function anonymous(obj ) {
function escape(html) {
return String(html)
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>');
};
function section(obj, prop, negate, thunk) {
var val = obj[prop];
if (Array.isArray(val)) return val.map(thunk).join('');
if ('function' == typeof val) return val.call(obj, thunk(obj));
if (negate) val = !val;
if (val) return thunk(obj);
return '';
};
return "\n(function javascript () {\n var ipc = (window.__nightmare ? __nightmare.ipc : window[''].nightmare.ipc);\n try {\n
var fn = (" + obj.src + "),\n response, \n args = [];\n\n " + section(obj, "args", false, function(obj){ return "args.push(" + obj.argument + ");" }) + "\n\n if(fn.length - 1 == args.length) {\n args.push(((err, v) => {\n if(err) {\n ipc.send('error', err.message || err.toString());\n }\n ipc.send('response', v);\n }));\n fn.apply(null, args);\n } \n else {\n response = fn.apply(null, args);\n if(response && response.then) {\n response.then((v) => {\n ipc.send('response', v);\n })\n .catch((err) => {\n ipc.send('error', err)\n });\n } else {\n ipc.send('response', response);\n }\n }\n } catch (err) {\n ipc.send('error', err.message);\n }\n})()\n"
}n/a
function anonymous(obj ) {
function escape(html) {
return String(html)
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>');
};
function section(obj, prop, negate, thunk) {
var val = obj[prop];
if (Array.isArray(val)) return val.map(thunk).join('');
if ('function' == typeof val) return val.call(obj, thunk(obj));
if (negate) val = !val;
if (val) return thunk(obj);
return '';
};
return "\n(function javascript () {\n var ipc = (window.__nightmare ? __nightmare.ipc : window[''].nightmare.ipc);\n try {\n
var response = (function () { " + obj.src + "\n})()\n ipc.send('response', response);\n } catch (e) {\n ipc.send('error', e.message);\n }\n})()\n"
}...
#### .scrollTo(top, left)
Scrolls the page to desired position. `top` and `left` are always relative to the top left corner of the document.
#### .viewport(width, height)
Set the viewport size.
#### .inject(type, file)
Inject a local `file` onto the current page. The file `type` must be either `js` or `css`.
#### .evaluate(fn[, arg1, arg2,...])
Invokes `fn` on the page with `arg1, arg2,...`. All the `args` are optional. On completion it returns the return value of `fn`.
Useful for extracting information from the page. Here's an example:
```js
var selector = 'h1';
...