node-horseman
Advanced tools
Comparing version 3.2.0 to 3.3.0
# Change Log | ||
All notable changes to this project will be documented in this file. | ||
## 3.3.0 - 2017-04-06 | ||
### Added | ||
- `phantomOptions` option for passing arbitrary PhantomJS CLI options - | ||
thanks @fabiocorneti | ||
- Support for per-action timeouts on `.waitFor` type actions - thanks @piercus | ||
### Fixed | ||
- `.boundingRectangle()` sometimes not using jQuery when it could - | ||
thanks @robsgreen | ||
- `.evaluate()` sometimes failing due to an utilized internal variable - | ||
thanks @robertpallas | ||
### Changed | ||
- Removed `clientScripts` option (it had no effect anyways) | ||
## 3.2.0 - 2016-10-21 | ||
@@ -5,0 +20,0 @@ ### Added |
@@ -28,7 +28,7 @@ // Grab links from Google. | ||
function scrape(){ | ||
return new Promise( function( resolve, reject ){ | ||
return getLinks() | ||
.then(function(newLinks){ | ||
links = links.concat(newLinks); | ||
@@ -44,3 +44,3 @@ | ||
.then( scrape ); | ||
} | ||
} | ||
}); | ||
@@ -57,3 +57,3 @@ } | ||
.type("input[name='q']","horseman") | ||
.click("button:contains('Google Search')") | ||
.click("input[value='Google Search']") | ||
.keyboardEvent("keypress",16777221) | ||
@@ -65,2 +65,2 @@ .waitForSelector("div.g") | ||
horseman.close(); | ||
}); | ||
}); |
@@ -369,3 +369,3 @@ 'use strict'; | ||
if (window.jQuery) { | ||
return $(selector)[0].getBoundingClientRect(); | ||
return jQuery(selector)[0].getBoundingClientRect(); | ||
} else { | ||
@@ -842,2 +842,5 @@ var element = document.querySelector(selector); | ||
var res = evaluate(function evaluate(fnstr, hasCb, args) { | ||
if(!window.__horseman) { | ||
window.__horseman = {}; | ||
} | ||
__horseman.cbargs = undefined; | ||
@@ -1556,8 +1559,16 @@ var done = function done(err, res) { | ||
* @throws Horseman.TimeoutError | ||
* @param {object} options | ||
* @param {number} [options.timeout=undefined] - timeout options | ||
* @emits Horseman#timeout | ||
*/ | ||
exports.waitForNextPage = function() { | ||
exports.waitForNextPage = function(options) { | ||
debug('.waitForNextPage()'); | ||
var self = this; | ||
var startCnt = self.lastActionPageCnt; | ||
var timeout; | ||
if(typeof(options) !== "undefined" && typeof(options.timeout) === "number"){ | ||
timeout = options.timeout; | ||
} else { | ||
timeout = self.options.timeout; | ||
} | ||
return this.ready.then(function() { | ||
@@ -1573,3 +1584,3 @@ var start = Date.now(); | ||
var diff = Date.now() - start; | ||
if (diff > self.options.timeout) { | ||
if (diff > timeout) { | ||
clearInterval(waiting); | ||
@@ -1593,7 +1604,9 @@ debug('.waitForNextPage() timed out'); | ||
* @param {string} - The selector on which to wait. | ||
* @param {object} options | ||
* @param {number} [options.timeout=undefined] - timeout options | ||
* @throws Horseman.TimeoutError | ||
* @emits Horseman#timeout | ||
*/ | ||
exports.waitForSelector = function(selector) { | ||
debug('.waitForSelector()', selector); | ||
exports.waitForSelector = function(selector, options) { | ||
debug('.waitForSelector()', selector, options); | ||
var elementPresent = function elementPresent(selector) { | ||
@@ -1604,3 +1617,14 @@ var els = window.jQuery ? | ||
}; | ||
return this.waitFor(elementPresent, selector, true).then(function() { | ||
var opts = { | ||
fn : elementPresent, | ||
args : [selector], | ||
value : true | ||
}; | ||
if(typeof(options) !== "undefined" && typeof(options.timeout) === "number"){ | ||
opts.timeout = options.timeout; | ||
} | ||
return this.waitFor(opts).then(function() { | ||
debug('.waitForSelector() complete'); | ||
@@ -1612,3 +1636,7 @@ }); | ||
* Waits for a function to evaluate to a given value in browser | ||
* @param {function} fn | ||
* @param {function | object} optsOrFn - If optsOrFn is a function, use the classic signature waitFor(fn, arg1, arg2, value), If arg is an object, use waitFor(options) | ||
* @param {array} optsOrFn.args - arguments of fn | ||
* @param {function} optsOrFn.fn - function to evaluate | ||
* @param {*} optsOrFn.value - expected value of function | ||
* @param {number} [optsOrFn.timeout=null] - timeout in ms | ||
* @param {...*} [arguments] | ||
@@ -1626,3 +1654,7 @@ * @param {*} value | ||
* @param {Page | undefined} page | ||
* @param {function} fn | ||
* @param {function | object} optsOrFn - If optsOrFn is a function, use the classic signature waitForPage(page, fn, arg1, arg2, value), If arg is an object, use waitForPage(page, options) | ||
* @param {array} optsOrFn.args - arguments of fn | ||
* @param {function} optsOrFn.fn - function to evaluate | ||
* @param {*} optsOrFn.value - expected value of function | ||
* @param {number} [optsOrFn.timeout=null] - timeout in ms | ||
* @param {...*} [arguments] | ||
@@ -1632,8 +1664,21 @@ * @param {*} value | ||
*/ | ||
function waitForPage(page, fn) { | ||
function waitForPage(page, optsOrFn) { | ||
var self = this; | ||
var args = Array.prototype.slice.call(arguments); | ||
var value = args.pop(); | ||
var fname = fn.name || '<anonymous>'; | ||
var args, value, fname, timeout = self.options.timeout, fn; | ||
if(typeof optsOrFn === "function"){ | ||
fn = optsOrFn; | ||
args = Array.prototype.slice.call(arguments); | ||
value = args.pop(); | ||
fname = fn.name || '<anonymous>'; | ||
} else if(typeof optsOrFn === "object"){ | ||
fn = optsOrFn.fn; | ||
args = [page, fn].concat(optsOrFn.args || []); | ||
value = optsOrFn.value; | ||
fname = fn.name || '<anonymous>'; | ||
if(optsOrFn.timeout){ | ||
timeout = optsOrFn.timeout; | ||
} | ||
} | ||
debug.apply(debug, ['.waitFor()', fname].concat(args.slice(2))); | ||
@@ -1646,3 +1691,3 @@ return this.ready.then(function() { | ||
var diff = Date.now() - start; | ||
if (diff > self.options.timeout) { | ||
if (diff > timeout) { | ||
clearInterval(checkInterval); | ||
@@ -1649,0 +1694,0 @@ debug('.waitFor() timed out'); |
@@ -37,3 +37,2 @@ 'use strict'; | ||
weak: true, | ||
clientScripts: [], | ||
loadImages: true, | ||
@@ -138,2 +137,9 @@ sslProtocol: 'any', //sslv3, sslv2, tlsv1, any | ||
Object.keys(this.options.phantomOptions || {}).forEach(function (key) { | ||
if (typeof phantomOptions[key] !== 'undefined') { | ||
debug('Horseman option ' + key + ' overridden by phantomOptions'); | ||
} | ||
phantomOptions[key] = this.options.phantomOptions[key]; | ||
}.bind(this)); | ||
var instantiationOptions = { | ||
@@ -140,0 +146,0 @@ parameters: phantomOptions |
{ | ||
"name": "node-horseman", | ||
"version": "3.2.0", | ||
"version": "3.3.0", | ||
"description": "Run PhantomJS from Node", | ||
@@ -5,0 +5,0 @@ "repository": { |
@@ -78,3 +78,2 @@ Horseman | ||
* `clientScripts` an array of local JavaScript files to load onto each page. | ||
* `timeout`: how long to wait for page loads or wait periods, | ||
@@ -112,2 +111,7 @@ default `5000` ms. | ||
you can use this option to specify the executable's location. | ||
* `phantomOptions`: Explicit PhantomJS options, e.g. | ||
`{'ssl-certificates-path': 'ca.pem'}`. | ||
For a complete list refer to the [PhantomJS command line interface]( | ||
http://phantomjs.org/api/command-line.html). | ||
**These options have precedence over options implicitly set by Horseman.** | ||
* `debugPort`: Enable web inspector on specified port, default not set. | ||
@@ -380,5 +384,6 @@ * `debugAutorun`: Autorun on launch when in debug mode, default is true. | ||
[getBoundingClientRect]: https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect | ||
Takes a cropped screenshot of the page. | ||
`area` can be a string identifying an html element on the screen to crop to, | ||
or a getBoundingClientRect object. | ||
or a [getBoundingClientRect][] object. | ||
@@ -389,3 +394,3 @@ #### .cropBase64(area, type) | ||
`area` can be a string identifying an html element on the screen to crop to, | ||
or a getBoundingClientRect object. | ||
or a [getBoundingClientRect][] object. | ||
Type must be one of 'PNG', 'GIF', or 'JPEG'. | ||
@@ -634,7 +639,8 @@ | ||
#### .waitForNextPage() | ||
#### .waitForNextPage([options]) | ||
Wait until a page finishes loading, typically after a `.click()`. | ||
`options` can have be `{timeout: 5000}` to define an action-specific timeout. | ||
#### .waitForSelector(selector) | ||
#### .waitForSelector(selector, [options]) | ||
@@ -644,2 +650,4 @@ Wait until the element `selector` is present, | ||
`options` can have be `{timeout: 5000}` to define an action-specific timeout. | ||
#### .waitFor(fn, \[arg1, arg2,...\], value) | ||
@@ -660,2 +668,25 @@ | ||
#### .waitFor(options) | ||
Alternative signature for .waitFor, with extra options. | ||
```js | ||
// This will call the function in the browser repeatedly | ||
// until true (or whatever else you specified) is returned | ||
horseman | ||
.waitFor({ | ||
fn : function waitForSelectorCount(selector, count) { | ||
return $(selector).length >= count | ||
}, | ||
args : ['.some-selector', 2], | ||
value : true | ||
}) | ||
// last argument (true here) is what return value to wait for | ||
``` | ||
`fn` : function to execute, mandatory | ||
`args` : `fn` arguments | ||
`value` : Wait until the `fn` evaluated on the page returns the *specified* `value`. | ||
`timeout` : specific timeout | ||
### Frames | ||
@@ -662,0 +693,0 @@ |
@@ -166,2 +166,18 @@ 'use strict'; | ||
it('should pass custom options to Phantom', function() { | ||
var horseman = new Horseman({ | ||
timeout: defaultTimeout, | ||
injectJquery: bool, | ||
ignoreSSLErrors: true, | ||
phantomOptions: { | ||
'ignore-ssl-errors': false | ||
} | ||
}); | ||
return horseman | ||
.open('https://expired.badssl.com') | ||
.close() | ||
.should | ||
.be.rejected(); | ||
}); | ||
it('should set the viewport', function() { | ||
@@ -1329,2 +1345,18 @@ var horseman = new Horseman({ | ||
it('should timeout after a specific time', function() { | ||
var start = new Date(); | ||
var horseman = new Horseman({ | ||
timeout: defaultTimeout, | ||
}); | ||
return horseman | ||
.open(serverUrl) | ||
.waitForSelector("#not-existing-id", { timeout : defaultTimeout/5}) | ||
.close() | ||
.catch(function(err){ | ||
var end = new Date(); | ||
var diff = end - start; | ||
diff.should.be.below(defaultTimeout/2); //may be a ms or so off. | ||
}); | ||
}); | ||
it('should wait until a selector is seen', function() { | ||
@@ -1360,2 +1392,22 @@ var horseman = new Horseman({ | ||
it('should call onTimeout if timeout in waitForNextPage with custom timeout', function() { | ||
var start = new Date(); | ||
var timeoutHorseman = new Horseman({ | ||
timeout: 10 | ||
}); | ||
var timeoutFiredTime = 0; | ||
return timeoutHorseman | ||
.on('timeout', function() { | ||
var end = new Date(); | ||
var diff = end - start; | ||
timeoutFiredTime = diff; | ||
}) | ||
.waitForNextPage({timeout: 1000}) | ||
.catch(Horseman.TimeoutError, function() {}) | ||
.close() | ||
.then(function() { | ||
timeoutFiredTime.should.be.above(900); | ||
}); | ||
}); | ||
it('should reject Promise if timeout in waitForNextPage', function() { | ||
@@ -2000,3 +2052,3 @@ var timeoutHorseman = new Horseman({ | ||
}); | ||
var hadHeader = 'truthy'; | ||
var hadHeader = false; | ||
return horseman | ||
@@ -2007,3 +2059,3 @@ .on('resourceReceived', function(resp) { | ||
}); | ||
hadHeader = hadHeader && hasHeader; | ||
hadHeader = hadHeader || hasHeader; | ||
}) | ||
@@ -2024,3 +2076,3 @@ .open('http://www.google.com') | ||
} | ||
var hadHeader = 'truthy'; | ||
var hadHeader = false; | ||
return horseman | ||
@@ -2032,3 +2084,3 @@ .setProxy('localhost', PROXY_PORT) | ||
}); | ||
hadHeader = hadHeader && hasHeader; | ||
hadHeader = hadHeader || hasHeader; | ||
}) | ||
@@ -2035,0 +2087,0 @@ .open('http://www.google.com') |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
231883
4375
922