Comparing version 1.1.0-beta2 to 1.1.0-beta3
@@ -47,8 +47,20 @@ /*! | ||
if (typeof Function.prototype.bind !== "function") { | ||
Function.prototype.bind = function(scope) { | ||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Compatibility | ||
Function.prototype.bind = function (oThis) { | ||
"use strict"; | ||
var _function = this; | ||
return function() { | ||
return _function.apply(scope, arguments); | ||
}; | ||
/* jshint -W055 */ | ||
if (typeof this !== "function") { | ||
// closest thing possible to the ECMAScript 5 internal IsCallable function | ||
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); | ||
} | ||
var aArgs = Array.prototype.slice.call(arguments, 1), | ||
fToBind = this, | ||
fNOP = function() {}, | ||
fBound = function() { | ||
return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, | ||
aArgs.concat(Array.prototype.slice.call(arguments))); | ||
}; | ||
fNOP.prototype = this.prototype; | ||
fBound.prototype = new fNOP(); | ||
return fBound; | ||
}; | ||
@@ -300,3 +312,3 @@ } | ||
if (!fs.isFile(phantom.casperScript)) { | ||
if (phantom.casperScript !== "/dev/stdin" && !fs.isFile(phantom.casperScript)) { | ||
return __die('Unable to open file: ' + phantom.casperScript); | ||
@@ -303,0 +315,0 @@ } |
@@ -8,3 +8,3 @@ Usage: casperjs [options] script.[js|coffee] [script argument [script argument ...]] | ||
--direct Prints log messages to the console | ||
--verbose Prints log messages to the console | ||
--log-level Sets logging level | ||
@@ -11,0 +11,0 @@ --help Prints this help |
@@ -8,53 +8,72 @@ # CasperJS contributors | ||
Nicolas Perriault | ||
Mickaël Andrieu | ||
Laurent Jouanneau | ||
hexid | ||
Brikou CARRE | ||
oncletom | ||
Brikou CARRE | ||
hexid | ||
Matt DuVall | ||
Nathan Black | ||
hannyu | ||
Julien Muetton | ||
hannyu | ||
Chris Bosco | ||
Matt Bowman | ||
Shiryaev Andrey | ||
mickaelandrieu | ||
Clochix | ||
Chris Lorenzo | ||
Victor Yap | ||
JF Paradis | ||
Matthew DuVall | ||
Rob Barreca | ||
Oleg Pudeyev | ||
pborreli | ||
nrabinowitz | ||
pborreli | ||
Darrell Hamilton | ||
Tyler Ritchie | ||
Oleg Pudeyev | ||
renatodarrigo | ||
Clochix | ||
Andrew Childs | ||
Eric Bouchut | ||
Dave Lee | ||
Solomon White | ||
Luke Rodgers | ||
Andrew Childs | ||
reina.sweet | ||
Solomon White | ||
Dave Lee | ||
renatodarrigo | ||
Donovan Hutchinson | ||
Sean Massa | ||
Vladimir Chizhov | ||
Samuel Gabel | ||
Reina Sweet | ||
Jan Schaumann | ||
fwebdev | ||
Reid Lynch | ||
Justin Collum | ||
Philip Hansen | ||
Michael Geers | ||
Orchestrator81 | ||
Nick Currier | ||
Julien Moulin | ||
Philip Hansen | ||
Donovan Hutchinson | ||
Elmar Langholz | ||
Reid Lynch | ||
Reina Sweet | ||
Sean Massa | ||
Jason Funk | ||
Lee Byrd | ||
Thomas Rosenau | ||
Lee Byrd | ||
V Sreekanth | ||
Vladimir Chizhov | ||
Jan Schaumann | ||
Jason Funk | ||
snkashis | ||
Patrick Reagan | ||
Andrew de Andrade | ||
Andy Shinn | ||
Ben Johnson | ||
Ben Lowery | ||
Bert Pareyn | ||
Brandon Bethke | ||
Charlie Park | ||
Chris Winters | ||
Christophe Benz | ||
Dharrya | ||
Dmitry Menshikov | ||
Florent DUBOST | ||
Harrison Reiser | ||
Itamar Nabriski | ||
Ivan | ||
Jamey J. DeOrio | ||
Jan Pochyla | ||
Jan-Martin Fruehwacht | ||
John F. Douthat | ||
Julian Gruber | ||
@@ -70,7 +89,8 @@ Justin Marsan | ||
Mehdi Kabab | ||
Mickaël Andrieu | ||
Miguel González | ||
Mikhail Korobov | ||
Mikko Peltonen | ||
Narno | ||
Orchestrator81 | ||
Pascal Borreli | ||
Phillip Alexander | ||
Rafael | ||
@@ -80,7 +100,13 @@ Rafael Garcia | ||
Rock Li | ||
Scott | ||
Thomas Parisot | ||
Tim Bunce | ||
Tzvi Friedman | ||
Yasuo Ohgaki | ||
Yevgeny Smirnov | ||
alfetopito | ||
jayseeg | ||
jean-philippe serafin | ||
shekyan | ||
snkashis | ||
``` |
@@ -62,3 +62,23 @@ /*! | ||
this.options.scope = this.options.scope || document; | ||
/** | ||
* Calls a method part of the current prototype, with arguments. | ||
* | ||
* @param {String} method Method name | ||
* @param {Array} args arguments | ||
* @return {Mixed} | ||
*/ | ||
this.__call = function __call(method, args) { | ||
if (method === "__call") { | ||
return; | ||
} | ||
try { | ||
return this[method].apply(this, args); | ||
} catch (err) { | ||
err.__isCallError = true; | ||
return err; | ||
} | ||
}; | ||
/** | ||
* Clicks on the DOM element behind the provided selector. | ||
@@ -134,15 +154,20 @@ * | ||
* | ||
* @param Object element DOM element | ||
* @param Object element DOM element | ||
* @return Boolean | ||
*/ | ||
this.elementVisible = function elementVisible(elem) { | ||
var style; | ||
try { | ||
var comp = window.getComputedStyle(elem, null); | ||
return comp.visibility !== 'hidden' && | ||
comp.display !== 'none' && | ||
elem.offsetHeight > 0 && | ||
elem.offsetWidth > 0; | ||
style = window.getComputedStyle(elem, null); | ||
} catch (e) { | ||
return false; | ||
} | ||
var hidden = style.visibility === 'hidden' || style.display === 'none'; | ||
if (hidden) { | ||
return false; | ||
} | ||
if (style.display === "inline") { | ||
return true; | ||
} | ||
return elem.clientHeight > 0 && elem.clientWidth > 0; | ||
} | ||
@@ -295,3 +320,3 @@ | ||
* @param HTMLElement|null scope Element to search child elements within | ||
* @return NodeList|undefined | ||
* @return Array|undefined | ||
*/ | ||
@@ -305,3 +330,3 @@ this.findAll = function findAll(selector, scope) { | ||
} else { | ||
return scope.querySelectorAll(pSelector.path); | ||
return Array.prototype.slice.call(scope.querySelectorAll(pSelector.path)); | ||
} | ||
@@ -567,6 +592,15 @@ } catch (e) { | ||
var formSelector = ''; | ||
if (options && options.formSelector) { | ||
if (options.formSelector) { | ||
formSelector = options.formSelector + ' '; | ||
} | ||
var inputs = this.findAll(formSelector + '[name="' + inputName + '"]'); | ||
if (options.inputSelector) { | ||
inputs = inputs.concat(this.findAll(options.inputSelector)); | ||
} | ||
if (options.inputXPath) { | ||
inputs = inputs.concat(this.getElementsByXPath(options.inputXPath)); | ||
} | ||
switch (inputs.length) { | ||
@@ -627,3 +661,3 @@ case 0: return undefined; | ||
var pos = elem.getBoundingClientRect(); | ||
center_x = Math.floor((pos.left + pos.right) / 2), | ||
center_x = Math.floor((pos.left + pos.right) / 2); | ||
center_y = Math.floor((pos.top + pos.bottom) / 2); | ||
@@ -699,2 +733,19 @@ } catch(e) {} | ||
/** | ||
* Scrolls current document to x, y coordinates. | ||
* | ||
* @param {Number} x X position | ||
* @param {Number} y Y position | ||
*/ | ||
this.scrollTo = function scrollTo(x, y) { | ||
window.scrollTo(parseInt(x || 0, 10), parseInt(y || 0, 10)); | ||
}; | ||
/** | ||
* Scrolls current document up to its bottom. | ||
*/ | ||
this.scrollToBottom = function scrollToBottom() { | ||
this.scrollTo(0, this.getDocumentHeight()); | ||
}, | ||
/** | ||
* Performs an AJAX request. | ||
@@ -701,0 +752,0 @@ * |
@@ -167,11 +167,2 @@ /*! | ||
// casper events | ||
this.casper.on('error', function onCasperError(msg, backtrace) { | ||
self.processPhantomError(msg, backtrace); | ||
}); | ||
this.casper.on('waitFor.timeout', function onWaitForTimeout(timeout) { | ||
this.warn(f('wait timeout of %dms reached', timeout)); | ||
}); | ||
function errorHandler(error, backtrace) { | ||
@@ -194,3 +185,3 @@ self.casper.unwait(); | ||
} | ||
function errorHandlerAndDone(error, backtrace) { | ||
@@ -201,2 +192,7 @@ errorHandler(error, backtrace); | ||
// casper events | ||
this.casper.on('error', function onCasperError(msg, backtrace) { | ||
self.processPhantomError(msg, backtrace); | ||
}); | ||
[ | ||
@@ -233,4 +229,30 @@ 'wait.error', | ||
this.casper.options.onWaitTimeout = function test_onWaitTimeout(timeout) { | ||
throw new TimedOutError(f("Wait timeout occured (%dms)", timeout)); | ||
this.casper.options.onWaitTimeout = function test_onWaitTimeout(timeout, details) { | ||
/*jshint maxcomplexity:10*/ | ||
var message = f("Wait timeout occured (%dms)", timeout); | ||
details = details || {}; | ||
if (details.selector) { | ||
message = f(details.waitWhile ? '"%s" never went away in %dms' : '"%s" still did not exist in %dms', details.selector, timeout); | ||
} | ||
else if (details.visible) { | ||
message = f(details.waitWhile ? '"%s" never disappeared in %dms' : '"%s" never appeared in %dms', details.visible, timeout); | ||
} | ||
else if (details.url || details.resource) { | ||
message = f('%s did not load in %dms', details.url || details.resource, timeout); | ||
} | ||
else if (details.popup) { | ||
message = f('%s did not pop up in %dms', details.popup, timeout); | ||
} | ||
else if (details.text) { | ||
message = f('"%s" did not appear in the page in %dms', details.text, timeout); | ||
} | ||
else if (details.selectorTextChange) { | ||
message = f('"%s" did not have a text change in %dms', details.selectorTextChange, timeout); | ||
} | ||
else if (utils.isFunction(details.testFx)) { | ||
message = f('"%s" did not evaluate to something truthy in %dms', details.testFx.toString(), timeout); | ||
} | ||
errorHandlerAndDone(new TimedOutError(message)); | ||
}; | ||
@@ -434,2 +456,17 @@ }; | ||
function baseFieldAssert(inputName, expected, actual, message) { | ||
/*jshint validthis:true */ | ||
"use strict"; | ||
return this.assert(utils.equals(actual, expected), message, { | ||
type: 'assertField', | ||
standard: f('"%s" input field has the value "%s"', inputName, expected), | ||
values: { | ||
inputName: inputName, | ||
actual: actual, | ||
expected: expected | ||
} | ||
}); | ||
} | ||
/** | ||
@@ -459,25 +496,66 @@ * Asserts that the provided assertion fails (used for internal testing). | ||
* | ||
* @param String inputName The name attribute of the input element | ||
* @param String expected The expected value of the input element | ||
* @param String message Test description | ||
* @param Object options ClientUtils#getFieldValue options (optional) | ||
* @return Object An assertion result object | ||
* @param String|Object input The name attribute of the input element | ||
* or an object with the selector | ||
* @param String expected The expected value of the input element | ||
* @param String message Test description | ||
* @param Object options ClientUtils#getFieldValue options (optional) | ||
* @return Object An assertion result object | ||
*/ | ||
Tester.prototype.assertField = function assertField(inputName, expected, message, options) { | ||
Tester.prototype.assertField = function assertField(input, expected, message, options) { | ||
"use strict"; | ||
if (typeof input === 'object') { | ||
switch (input.type) { | ||
case 'css': | ||
return this.assertFieldCSS(input.path, expected, message); | ||
case 'xpath': | ||
return this.assertFieldXPath(input.path, expected, message); | ||
default: | ||
throw new CasperError('Invalid regexp.'); | ||
// no default | ||
} | ||
} | ||
var actual = this.casper.evaluate(function(inputName, options) { | ||
return __utils__.getFieldValue(inputName, options); | ||
}, inputName, options); | ||
return this.assert(utils.equals(actual, expected), message, { | ||
type: 'assertField', | ||
standard: f('"%s" input field has the value "%s"', inputName, expected), | ||
values: { | ||
inputName: inputName, | ||
actual: actual, | ||
expected: expected | ||
} | ||
}); | ||
}, input, options); | ||
return baseFieldAssert.call(this, input, expected, actual, message); | ||
}; | ||
/** | ||
* Asserts that a given input field by CSS selector has the provided value. | ||
* | ||
* @param Object cssSelector The CSS selector to use for the assert field value | ||
* @param String expected The expected value of the input element | ||
* @param String message Test description | ||
* @return Object An assertion result object | ||
*/ | ||
Tester.prototype.assertFieldCSS = function assertFieldCSS(cssSelector, expected, message) { | ||
"use strict"; | ||
var actual = this.casper.evaluate(function(inputName, cssSelector) { | ||
return __utils__.getFieldValue(inputName, {inputSelector: cssSelector}); | ||
}, null, cssSelector); | ||
return baseFieldAssert.call(this, null, expected, actual, message); | ||
}; | ||
/** | ||
* Asserts that a given input field by XPath selector has the provided value. | ||
* | ||
* @param Object xPathSelector The XPath selector to use for the assert field value | ||
* @param String expected The expected value of the input element | ||
* @param String message Test description | ||
* @return Object An assertion result object | ||
*/ | ||
Tester.prototype.assertFieldXPath = function assertFieldXPath(xPathSelector, expected, message) { | ||
"use strict"; | ||
var actual = this.casper.evaluate(function(inputName, xPathSelector) { | ||
return __utils__.getFieldValue(inputName, {inputXPath: xPathSelector}); | ||
}, null, xPathSelector); | ||
return baseFieldAssert.call(this, null, expected, actual, message); | ||
}; | ||
/** | ||
* Asserts that an element matching the provided selector expression exists in | ||
@@ -497,3 +575,3 @@ * remote DOM. | ||
type: "assertExists", | ||
standard: f("Found an element matching: %s", selector), | ||
standard: f("Find an element matching: %s", selector), | ||
values: { | ||
@@ -518,3 +596,3 @@ selector: selector | ||
type: "assertDoesntExist", | ||
standard: f("No element found matching selector: %s", selector), | ||
standard: f("Fail to find element matching selector: %s", selector), | ||
values: { | ||
@@ -649,3 +727,3 @@ selector: selector | ||
type: "assertResourceExists", | ||
standard: "Expected resource has been found", | ||
standard: "Confirm page has resource", | ||
values: { | ||
@@ -694,3 +772,3 @@ test: test | ||
type: "assertTextExists", | ||
standard: "Found expected text within the document body", | ||
standard: "Find text within the document body", | ||
values: { | ||
@@ -755,3 +833,3 @@ text: text | ||
type: "assertSelectorHasText", | ||
standard: f('Found "%s" within the selector "%s"', text, selector), | ||
standard: f('Find "%s" within the selector "%s"', text, selector), | ||
values: { | ||
@@ -871,3 +949,3 @@ selector: selector, | ||
subject: subject, | ||
constructorName: constructor.name, | ||
constructorName: constructor.name | ||
} | ||
@@ -1419,7 +1497,9 @@ }); | ||
* | ||
* @param Boolean exit | ||
* @param Boolean exit Exit casper after results have been rendered? | ||
* @param Number status Exit status code (default: 0) | ||
* @param String save Optional path to file where to save the results log | ||
*/ | ||
Tester.prototype.renderResults = function renderResults(exit, status, save) { | ||
"use strict"; | ||
/*jshint maxstatements:20*/ | ||
/*jshint maxstatements:25*/ | ||
save = save || this.options.save; | ||
@@ -1462,2 +1542,3 @@ var exitStatus = 0, | ||
if (exit === true) { | ||
this.emit("exit"); | ||
this.casper.exit(status ? ~~status : exitStatus); | ||
@@ -1464,0 +1545,0 @@ } |
@@ -84,15 +84,19 @@ /*! | ||
/*jshint eqnull:true, eqeqeq:false */ | ||
while (input != null) { | ||
if (input == constructor.prototype) { | ||
if (typeof input == 'undefined' || input == null) { | ||
return false; | ||
} | ||
var inputToTest = input; | ||
while (inputToTest != null) { | ||
if (inputToTest == constructor.prototype) { | ||
return true; | ||
} | ||
if (typeof input == 'xml') { | ||
if (typeof inputToTest == 'xml') { | ||
return constructor.prototype == document.prototype; | ||
} | ||
if (typeof input == 'undefined') { | ||
if (typeof inputToTest == 'undefined') { | ||
return false; | ||
} | ||
input = input.__proto__; | ||
} | ||
return false; | ||
inputToTest = inputToTest.__proto__; | ||
} | ||
return equals(input.constructor.name, constructor.name); | ||
} | ||
@@ -626,4 +630,16 @@ exports.betterInstanceOf = betterInstanceOf; | ||
function mergeObjectsInSlimerjs(origin, add) { | ||
/** | ||
* Object recursive merging utility for use in the SlimerJS environment | ||
* | ||
* @param Object origin the origin object | ||
* @param Object add the object to merge data into origin | ||
* @param Object opts optional options to be passed in | ||
* @return Object | ||
*/ | ||
function mergeObjectsInSlimerjs(origin, add, opts) { | ||
"use strict"; | ||
var options = opts || {}, | ||
keepReferences = options.keepReferences; | ||
for (var p in add) { | ||
@@ -634,3 +650,3 @@ if (isPlainObject(add[p])) { | ||
} else { | ||
origin[p] = clone(add[p]); | ||
origin[p] = keepReferences ? add[p] : clone(add[p]); | ||
} | ||
@@ -649,7 +665,11 @@ } else { | ||
* @param Object add the object to merge data into origin | ||
* @param Object opts optional options to be passed in | ||
* @return Object | ||
*/ | ||
function mergeObjects(origin, add) { | ||
function mergeObjects(origin, add, opts) { | ||
"use strict"; | ||
var options = opts || {}, | ||
keepReferences = options.keepReferences; | ||
if (phantom.casperEngine === 'slimerjs') { | ||
@@ -661,2 +681,3 @@ // Because of an issue in the module system of slimerjs (security membranes?) | ||
} | ||
for (var p in add) { | ||
@@ -667,3 +688,3 @@ if (add[p] && add[p].constructor === Object) { | ||
} else { | ||
origin[p] = clone(add[p]); | ||
origin[p] = keepReferences ? add[p] : clone(add[p]); | ||
} | ||
@@ -670,0 +691,0 @@ } else { |
@@ -156,3 +156,3 @@ /*! | ||
}.bind(this)); | ||
this._xml.setAttribute('duration', utils.ms2seconds(this.results.calculateDuration())); | ||
this._xml.setAttribute('time', utils.ms2seconds(this.results.calculateDuration())); | ||
return this._xml; | ||
@@ -159,0 +159,0 @@ }; |
{ | ||
"name": "casperjs", | ||
"description": "Navigation scripting & testing utility for PhantomJS", | ||
"version": "1.1.0-beta2", | ||
"description": "A navigation scripting & testing utility for PhantomJS and SlimerJS", | ||
"version": "1.1.0-beta3", | ||
"keywords": [ | ||
"phantomjs", | ||
"javascript" | ||
"slimerjs", | ||
"test", | ||
"testing", | ||
"scraping" | ||
], | ||
"maintainers": [ | ||
{ | ||
"name": "Nicolas Perriault", | ||
"email": "nperriault@gmail.com", | ||
"web": "http://www.akei.com" | ||
} | ||
], | ||
"bin": "./bin/casperjs", | ||
"author": { | ||
"name": "Nicolas Perriault", | ||
"email": "nicolas@perriault.net", | ||
"web": "https://nicolas.perriault.net/" | ||
}, | ||
"dependencies": { | ||
"http://www.phantomjs.org/": "master" | ||
"phantomjs": ">=1.8.2" | ||
}, | ||
@@ -22,11 +24,9 @@ "bugs": { | ||
}, | ||
"repositories": [ | ||
{ | ||
"type": "git", | ||
"url": "git://github.com/n1k0/casperjs.git" | ||
} | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/n1k0/casperjs.git" | ||
}, | ||
"licenses": [ | ||
{ | ||
"name": "MIT", | ||
"type": "MIT", | ||
"url": "http://www.opensource.org/licenses/mit-license.php" | ||
@@ -33,0 +33,0 @@ } |
@@ -22,11 +22,11 @@ # CasperJS | ||
- defining & ordering [navigation steps](http://casperjs.org/quickstart.html) | ||
- [filling forms](http://casperjs.org/api.html#casper.fill) | ||
- [clicking links](http://casperjs.org/api.html#casper.click) | ||
- [capturing screenshots](http://casperjs.org/api.html#casper.captureSelector) of a page (or an area) | ||
- [making assertions on remote DOM](http://casperjs.org/api.html#tester) | ||
- [logging](http://casperjs.org/logging.html) & [events](http://casperjs.org/events-filters.html) | ||
- [downloading base64](http://casperjs.org/api.html#casper.download) encoded resources, even binary ones | ||
- defining & ordering [navigation steps](http://docs.casperjs.org/en/latest/quickstart.html) | ||
- [filling forms](http://docs.casperjs.org/en/latest/modules/casper.html#fill) | ||
- [clicking links](http://docs.casperjs.org/en/latest/modules/casper.html#click) | ||
- [capturing screenshots](http://docs.casperjs.org/en/latest/modules/casper.html#captureselector) of a page (or an area) | ||
- [making assertions on remote DOM](http://docs.casperjs.org/en/latest/modules/tester.html) | ||
- [logging](http://docs.casperjs.org/en/latest/logging.html) & [events](http://docs.casperjs.org/en/latest/events-filters.html) | ||
- [downloading](http://docs.casperjs.org/en/latest/modules/casper.html#download) resources, even binary ones | ||
- catching errors and react accordingly | ||
- writing [functional test suites](http://casperjs.org/testing.html), exporting results as JUnit XML (xUnit) | ||
- writing [functional test suites](http://docs.casperjs.org/en/latest/testing.html), exporting results as JUnit XML (xUnit) | ||
@@ -36,3 +36,3 @@ Browse the [sample examples repository](https://github.com/n1k0/casperjs/tree/master/samples). | ||
**Read the [full documentation](http://casperjs.org/) on casperjs dedicated website.** | ||
**Read the [full documentation](http://docs.casperjs.org/) on casperjs documentation website.** | ||
@@ -45,7 +45,9 @@ Subscribe to the [project mailing-list](https://groups.google.com/forum/#!forum/casperjs) | ||
First [install CasperJS](http://docs.casperjs.org/en/latest/installation.html), we'll use 1.1 beta here. | ||
Sample test to see if some dropdown can be opened: | ||
```javascript | ||
casper.test.begin('a twitter bootsrap dropdown can be opened', 2, function(test) { | ||
casper.start('http://twitter.github.com/bootstrap/javascript.html#dropdowns', function() { | ||
casper.test.begin('a twitter bootstrap dropdown can be opened', 2, function(test) { | ||
casper.start('http://getbootstrap.com/2.3.2/javascript.html#dropdowns', function() { | ||
test.assertExists('#navbar-example'); | ||
@@ -68,6 +70,7 @@ this.click('#dropdowns .nav-pills .dropdown:last-of-type a.dropdown-toggle'); | ||
If you're having problems with using the project, use the support forum at CodersClan. | ||
Need help with getting CasperJS up and running? Got a time-consuming problem you want to get solved quickly? | ||
<a href="http://codersclan.net/forum/index.php?repo_id=32"><img src="http://www.codersclan.net/graphics/getSupport_blue_big.png" width="160"></a> | ||
Get <a href="http://codersclan.net/?repo_id=32">CasperJS support on CodersClan.</a> | ||
<a href="http://codersclan.net/?repo_id=32"><img src="http://www.codersclan.net/gs_button/?repo_id=32" width="200"></a> | ||
## Contributing | ||
@@ -84,1 +87,13 @@ | ||
To view the source files on github, head to [the gh-pages branch](https://github.com/n1k0/casperjs/tree/gh-pages), and check the [documentation's README](https://github.com/n1k0/casperjs/tree/gh-pages#readme) for further instructions. | ||
## Team | ||
- Nicolas Perriault ([@n1k0](https://github.com/n1k0)) | ||
- Nick Currier ([@hexid](https://github.com/hexid)) | ||
- Laurent Jouanneau ([@laurentj](https://github.com/laurentj)) | ||
- Mickaël Andrieu ([@mickaelandrieu](https://github.com/mickaelandrieu)) | ||
- Matt DuVall ([@mduvall](https://github.com/mduvall)) | ||
## License | ||
MIT |
@@ -45,3 +45,3 @@ /*jshint strict:false*/ | ||
this.then(function() { | ||
this.fill('form[action="/search"]', {q: term}, true); | ||
this.fill('form[action="/search"]', {q: '"' + term + '"'}, true); | ||
}); | ||
@@ -48,0 +48,0 @@ this.then(function() { |
@@ -16,3 +16,4 @@ /*global phantom, CasperError, patchRequire, require:true, casper:true*/ | ||
var casper = require('casper').create({ | ||
exitOnError: false | ||
exitOnError: false, | ||
silentErrors: true // we subscribe to error events for catching them | ||
}); | ||
@@ -63,4 +64,5 @@ | ||
} | ||
casper.test.options.concise = casper.cli.get('concise') || false; | ||
casper.test.options.failFast = casper.cli.get('fail-fast') || false; | ||
casper.test.options.concise = casper.cli.get('concise', false); | ||
casper.test.options.failFast = casper.cli.get('fail-fast', false); | ||
casper.test.options.autoExit = casper.cli.get('auto-exit') !== "no"; | ||
@@ -104,3 +106,3 @@ // test paths are passed as args | ||
casper.test.on('tests.complete', function() { | ||
this.renderResults(true, undefined, casper.cli.get('xunit') || undefined); | ||
this.renderResults(this.options.autoExit, undefined, casper.cli.get('xunit') || undefined); | ||
if (this.options.failFast && this.testResults.failures.length > 0) { | ||
@@ -107,0 +109,0 @@ casper.warn('Test suite failed fast, all tests may not have been executed.'); |
@@ -62,1 +62,12 @@ /*jshint strict:false*/ | ||
} | ||
casper.test.begin('sendKeys() reset option', 1, function(test) { | ||
casper.start('tests/site/form.html', function() { | ||
this.sendKeys('textarea', 'foo'); | ||
this.sendKeys('textarea', 'bar', {reset: true}); | ||
var values = this.getFormValues('form[action="result.html"]'); | ||
test.assertEquals(values.content, "bar"); | ||
}).run(function() { | ||
test.done(); | ||
}); | ||
}); |
@@ -23,1 +23,14 @@ /*global casper*/ | ||
}); | ||
casper.test.begin('"resource.error" event', 3, function(test) { | ||
casper.on("resource.error", function(error) { | ||
test.assertType(error, "object", '"resource.error" triggered error information'); | ||
test.assert(error.errorCode === 203, '"resource.error" error code is correct'); | ||
test.assertMatch(error.url, /non-existant\.html$/, '"resource.error" url is correct'); | ||
}); | ||
casper.start('tests/site/non-existant.html').run(function() { | ||
casper.removeAllListeners("resource.error"); | ||
test.done(); | ||
}); | ||
}); |
@@ -54,7 +54,7 @@ /*global casper*/ | ||
fakeDocument('<ul class="foo"><li>bar</li><li>baz</li></ul>'); | ||
test.assertType(clientutils.findAll('li'), 'nodelist', | ||
test.assertType(clientutils.findAll('li'), 'array', | ||
'ClientUtils.findAll() can find matching DOM elements'); | ||
test.assertEquals(clientutils.findAll('li').length, 2, | ||
'ClientUtils.findAll() can find matching DOM elements'); | ||
test.assertType(clientutils.findAll('ol'), 'nodelist', | ||
test.assertType(clientutils.findAll('ol'), 'array', | ||
'ClientUtils.findAll() can find matching DOM elements'); | ||
@@ -65,3 +65,3 @@ test.assertEquals(clientutils.findAll('ol').length, 0, | ||
var scope = clientutils.findOne('ul'); | ||
test.assertType(clientutils.findAll('li', scope), 'nodelist', | ||
test.assertType(clientutils.findAll('li', scope), 'array', | ||
'ClientUtils.findAll() can find matching DOM elements within a given scope'); | ||
@@ -68,0 +68,0 @@ test.assertEquals(clientutils.findAll('li', scope).length, 2, |
@@ -30,3 +30,5 @@ /*global casper*/ | ||
if (utils.ltVersion(phantom.version, '1.9.0') || isGecko) { | ||
if (utils.ltVersion(phantom.version, '1.9.0') || | ||
utils.gteVersion(phantom.version, '1.9.2') || | ||
isGecko) { | ||
// https://github.com/ariya/phantomjs/issues/11163 | ||
@@ -33,0 +35,0 @@ this.testCodes = this.testCodes.concat([ |
@@ -132,6 +132,92 @@ /*global casper*/ | ||
}, 'Tester.assertField() only checks for existing fields'); | ||
}).run(function() { | ||
test.done(); | ||
}); | ||
casper.run(function() { | ||
}); | ||
casper.test.begin('Tester.assertField(): CSS selectors', 1, function(test) { | ||
casper.start('tests/site/form.html', function() { | ||
this.fill('form[action="result.html"]', { | ||
'email': 'albert@camus.com' | ||
}); | ||
test.assertField({ | ||
type: 'css', | ||
path: '#email' | ||
}, | ||
'albert@camus.com', | ||
'Tester.assertField() works as expected with CSS selectors' | ||
); | ||
}).run(function() { | ||
test.done(); | ||
}) | ||
}); | ||
}); | ||
casper.test.begin('Tester.assertField(): XPath selectors', 1, function(test) { | ||
casper.start('tests/site/form.html', function() { | ||
this.fill('form[action="result.html"]', { | ||
'email': 'albert@camus.com' | ||
}); | ||
test.assertField({ | ||
type: 'xpath', | ||
path: '/html/body/form[1]/input[1]' | ||
}, | ||
'albert@camus.com', | ||
'Tester.assertField() works as expected with XPath selectors' | ||
); | ||
}).run(function() { | ||
test.done(); | ||
}); | ||
}); | ||
casper.test.begin('Tester.assertField(): invalid selectors', 1, function(test) { | ||
casper.start('tests/site/form.html', function() { | ||
this.fill('form[action="result.html"]', { | ||
'email': 'albert@camus.com' | ||
}); | ||
test.assertRaise(function() { | ||
test.assertField({ | ||
type: 'albert' | ||
}, | ||
'albert@camus.com', | ||
'Tester.assertField() works as expected with XPath selectors' | ||
); | ||
}, [], 'should throw an error for an invalid selector'); | ||
}).run(function() { | ||
test.done(); | ||
}); | ||
}); | ||
casper.test.begin('Tester.assertFieldCSS(): CSS selectors', 1, function(test) { | ||
casper.start('tests/site/form.html', function() { | ||
this.fill('form[action="result.html"]', { | ||
'email': 'albert@camus.com' | ||
}); | ||
test.assertFieldCSS( | ||
'#email', | ||
'albert@camus.com', | ||
'Tester.assertFieldCSS() works as expected with CSS selectors' | ||
); | ||
}).run(function() { | ||
test.done(); | ||
}); | ||
}); | ||
casper.test.begin('Tester.assertFieldXPath(): XPath selectors', 1, function(test) { | ||
casper.start('tests/site/form.html', function() { | ||
this.fill('form[action="result.html"]', { | ||
'email': 'albert@camus.com' | ||
}); | ||
test.assertFieldXPath( | ||
'/html/body/form[1]/input[1]', | ||
'albert@camus.com', | ||
'Tester.assertFieldXPath() works as expected with XPath selectors' | ||
); | ||
}).run(function() { | ||
test.done(); | ||
}); | ||
}); |
@@ -32,3 +32,3 @@ /*global casper*/ | ||
function SuperCow(){} SuperCow.prototype = new Cow(); var superDaisy = new SuperCow(); | ||
var date = new Date(); var regex = new RegExp(); var xmlDoc = document.implementation.createDocument("<y>", "x"); | ||
var date = new Date(); var regex = new RegExp(); var xmlDoc = document.implementation.createDocument("<y>", "x", null); | ||
var testCases = [ | ||
@@ -330,3 +330,4 @@ {subject: 1, fn: Number, expected: true}, | ||
casper.test.begin('mergeObjects() tests', 8, function(test) { | ||
casper.test.begin('mergeObjects() tests', 10, function(test) { | ||
/* jshint eqeqeq:false */ | ||
var testCases = [ | ||
@@ -365,9 +366,20 @@ { | ||
}); | ||
var obj = {x: 1}; | ||
var obj = {x: 1}, | ||
qtruntimeobject = {foo: 'baz'}; | ||
var merged1 = utils.mergeObjects({}, {a: obj}); | ||
var merged2 = utils.mergeObjects({a: {}}, {a: obj}); | ||
merged1.a.x = 2; | ||
test.assertEquals(obj.x, 1, 'mergeObjects() creates deep clones #1'); | ||
var merged2 = utils.mergeObjects({a: {}}, {a: obj}); | ||
merged2.a.x = 2; | ||
test.assertEquals(obj.x, 1, 'mergeObjects() creates deep clones #2'); | ||
var refObj = {a: qtruntimeobject}; | ||
var merged3 = utils.mergeObjects({}, refObj, {keepReferences: false}); | ||
test.assertFalsy(merged3.a == refObj.a, 'disabling references should not point to same object'); | ||
var merged4 = utils.mergeObjects({}, refObj, {keepReferences: true}); | ||
test.assert(merged4.a == refObj.a, 'enabling references should point to same object'); | ||
test.done(); | ||
@@ -374,0 +386,0 @@ }); |
@@ -32,3 +32,3 @@ /*global casper, __utils__*/ | ||
}, 2); | ||
test.assertExists('testsuites[duration]'); | ||
test.assertExists('testsuites[time]'); | ||
test.assertExists('testsuite[name="foo"][package="foo"]'); | ||
@@ -35,0 +35,0 @@ test.assertExists('testsuite[name="bar"][package="bar"]'); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
Misc. License Issues
License(Experimental) A package's licensing information has fine-grained problems.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
1299481
273
0
13774
1
95
+ Addedphantomjs@>=1.8.2
+ Addedansi-regex@2.1.1(transitive)
+ Addedansi-styles@2.2.1(transitive)
+ Addedasn1@0.2.6(transitive)
+ Addedassert-plus@0.2.01.0.0(transitive)
+ Addedasync@2.6.4(transitive)
+ Addedaws-sign2@0.6.0(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbcrypt-pbkdf@1.0.2(transitive)
+ Addedbl@1.0.3(transitive)
+ Addedboom@2.10.1(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedcaseless@0.11.0(transitive)
+ Addedchalk@1.1.3(transitive)
+ Addedcombined-stream@1.0.8(transitive)
+ Addedcommander@2.20.3(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedconcat-stream@1.5.0(transitive)
+ Addedcore-util-is@1.0.21.0.3(transitive)
+ Addedcryptiles@2.0.5(transitive)
+ Addeddashdash@1.14.1(transitive)
+ Addeddebug@0.7.4(transitive)
+ Addeddelayed-stream@1.0.0(transitive)
+ Addedecc-jsbn@0.1.2(transitive)
+ Addedescape-string-regexp@1.0.5(transitive)
+ Addedextend@3.0.2(transitive)
+ Addedextract-zip@1.5.0(transitive)
+ Addedextsprintf@1.3.0(transitive)
+ Addedfd-slicer@1.0.1(transitive)
+ Addedforever-agent@0.6.1(transitive)
+ Addedform-data@1.0.1(transitive)
+ Addedfs-extra@0.26.7(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedgenerate-function@2.3.1(transitive)
+ Addedgenerate-object-property@1.2.0(transitive)
+ Addedgetpass@0.1.7(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedhar-validator@2.0.6(transitive)
+ Addedhas-ansi@2.0.0(transitive)
+ Addedhasha@2.2.0(transitive)
+ Addedhawk@3.1.3(transitive)
+ Addedhoek@2.16.3(transitive)
+ Addedhttp-signature@1.1.1(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedis-my-ip-valid@1.0.1(transitive)
+ Addedis-my-json-valid@2.20.6(transitive)
+ Addedis-property@1.0.2(transitive)
+ Addedis-stream@1.1.0(transitive)
+ Addedis-typedarray@1.0.0(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedisexe@2.0.0(transitive)
+ Addedisstream@0.1.2(transitive)
+ Addedjsbn@0.1.1(transitive)
+ Addedjson-schema@0.4.0(transitive)
+ Addedjson-stringify-safe@5.0.1(transitive)
+ Addedjsonfile@2.4.0(transitive)
+ Addedjsonpointer@5.0.1(transitive)
+ Addedjsprim@1.4.2(transitive)
+ Addedkew@0.7.0(transitive)
+ Addedklaw@1.3.1(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addedmime-db@1.52.0(transitive)
+ Addedmime-types@2.1.35(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedminimist@0.0.8(transitive)
+ Addedmkdirp@0.5.0(transitive)
+ Addednode-uuid@1.4.8(transitive)
+ Addedoauth-sign@0.8.2(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedpend@1.2.0(transitive)
+ Addedphantomjs@2.1.7(transitive)
+ Addedpinkie@2.0.4(transitive)
+ Addedpinkie-promise@2.0.1(transitive)
+ Addedprocess-nextick-args@1.0.7(transitive)
+ Addedprogress@1.1.8(transitive)
+ Addedqs@5.2.1(transitive)
+ Addedreadable-stream@2.0.6(transitive)
+ Addedrequest@2.67.0(transitive)
+ Addedrequest-progress@2.0.1(transitive)
+ Addedrimraf@2.7.1(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedsntp@1.0.9(transitive)
+ Addedsshpk@1.18.0(transitive)
+ Addedstring_decoder@0.10.31(transitive)
+ Addedstringstream@0.0.6(transitive)
+ Addedstrip-ansi@3.0.1(transitive)
+ Addedsupports-color@2.0.0(transitive)
+ Addedthrottleit@1.0.1(transitive)
+ Addedtough-cookie@2.2.2(transitive)
+ Addedtunnel-agent@0.4.3(transitive)
+ Addedtweetnacl@0.14.5(transitive)
+ Addedtypedarray@0.0.7(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
+ Addedverror@1.10.0(transitive)
+ Addedwhich@1.2.14(transitive)
+ Addedwrappy@1.0.2(transitive)
+ Addedxtend@4.0.2(transitive)
+ Addedyauzl@2.4.1(transitive)
- Removedhttp://www.phantomjs.org/@master