sync with latest master
Showing
35 changed files
with
471 additions
and
283 deletions
1 | CasperJS Changelog | 1 | CasperJS Changelog |
2 | ================== | 2 | ================== |
3 | 3 | ||
4 | 2012-06-04, v0.6.10 | ||
5 | ------------------- | ||
6 | |||
7 | - fixed [#73](https://github.com/n1k0/casperjs/issues/73) - `Casper.download()` not working correctly with binaries | ||
8 | - fixed [#129](https://github.com/n1k0/casperjs/issues/129) - Can't put `//` comments in evaluate() function | ||
9 | - closed [#130](https://github.com/n1k0/casperjs/issues/130) - Added a `Dummy` [colorizer](http://casperjs.org/api.html#colorizer) class, in order to disable colors in console output | ||
10 | - fixed [#133](https://github.com/n1k0/casperjs/issues/133) - updated and fixed documentation about [extensibility](http://casperjs.org/extending.html) | ||
11 | - added `Casper.clickLabel()` for clicking on an element found by its `innerText` content | ||
12 | |||
13 | As a side note, the official website monolithic page has been split across several ones: http://casperjs.org/ | ||
14 | |||
15 | 2012-05-29, v0.6.9 | ||
16 | ------------------ | ||
17 | |||
18 | - **BC BREAK:** PhantomJS 1.5 is now the minimal PhantomJS version supported. | ||
19 | - fixed [#114](https://github.com/n1k0/casperjs/issues/114) - ensured client-side utils are injected before any `evaluate()` call | ||
20 | - merged [#89](https://github.com/n1k0/casperjs/pull/89) - Support for more mouse events (@nrabinowitz) | ||
21 | - [added a new `error` event, better error reporting](https://github.com/n1k0/casperjs/commit/2e6988ae821b3251e063d11ba28af59b0683852a) | ||
22 | - fixed [#117](https://github.com/n1k0/casperjs/issues/117) - `fill()` coulnd't `submit()` a form with a submit input named *submit* | ||
23 | - merged [#122](https://github.com/n1k0/casperjs/pull/122) - allow downloads to be triggered by more than just `GET` requests | ||
24 | - closed [#57](https://github.com/n1k0/casperjs/issues/57) - added context to emitted test events + complete assertion framework refactor | ||
25 | - fixed loaded resources array is now reset adequately [reference discussion](https://groups.google.com/forum/?hl=fr?fromgroups#!topic/casperjs/TCkNzrj1IoA) | ||
26 | - fixed incomplete error message logged when passed an erroneous selector (xpath and css) | ||
27 | |||
4 | 2012-05-20, v0.6.8 | 28 | 2012-05-20, v0.6.8 |
5 | ------------------ | 29 | ------------------ |
6 | 30 | ... | ... |
... | @@ -4,7 +4,7 @@ CasperJS is a navigation scripting & testing utility for [PhantomJS](http://www. | ... | @@ -4,7 +4,7 @@ CasperJS is a navigation scripting & testing utility for [PhantomJS](http://www. |
4 | It eases the process of defining a full navigation scenario and provides useful | 4 | It eases the process of defining a full navigation scenario and provides useful |
5 | high-level functions, methods & syntaxic sugar for doing common tasks such as: | 5 | high-level functions, methods & syntaxic sugar for doing common tasks such as: |
6 | 6 | ||
7 | - defining & ordering [navigation steps](http://casperjs.org/#phantom_Casper_run) | 7 | - defining & ordering [navigation steps](http://casperjs.org/#quickstart) |
8 | - [filling forms](http://casperjs.org/#phantom_Casper_fill) | 8 | - [filling forms](http://casperjs.org/#phantom_Casper_fill) |
9 | - [clicking links](http://casperjs.org/#phantom_Casper_click) | 9 | - [clicking links](http://casperjs.org/#phantom_Casper_click) |
10 | - [capturing screenshots](http://casperjs.org/#phantom_Casper_captureSelector) of a page (or an area) | 10 | - [capturing screenshots](http://casperjs.org/#phantom_Casper_captureSelector) of a page (or an area) |
... | @@ -12,15 +12,16 @@ high-level functions, methods & syntaxic sugar for doing common tasks such as: | ... | @@ -12,15 +12,16 @@ high-level functions, methods & syntaxic sugar for doing common tasks such as: |
12 | - [logging](http://casperjs.org/#logging) & [events](http://casperjs.org/#events-filters) | 12 | - [logging](http://casperjs.org/#logging) & [events](http://casperjs.org/#events-filters) |
13 | - [downloading base64](http://casperjs.org/#phantom_Casper_download) encoded resources, even binary ones | 13 | - [downloading base64](http://casperjs.org/#phantom_Casper_download) encoded resources, even binary ones |
14 | - catching errors and react accordingly | 14 | - catching errors and react accordingly |
15 | - writing [functional test suite](http://casperjs.org/#testing), exporting results as JUnit XML (xUnit) | 15 | - writing [functional test suites](http://casperjs.org/#testing), exporting results as JUnit XML (xUnit) |
16 | 16 | ||
17 | Feel free to browse our [sample examples repository](https://github.com/n1k0/casperjs/tree/master/samples). | 17 | Browse the [sample examples repository](https://github.com/n1k0/casperjs/tree/master/samples). |
18 | Don't hesitate to pull request for any cool example of yours as well! | 18 | Don't hesitate to pull request for any cool example of yours as well! |
19 | 19 | ||
20 | **Read the [full documentation](http://casperjs.org/) on casperjs dedicated website.** | 20 | **Read the [full documentation](http://casperjs.org/) on casperjs dedicated website.** |
21 | 21 | ||
22 | Subscribe to the [project mailing-list](https://groups.google.com/forum/#!forum/casperjs) | 22 | Subscribe to the [project mailing-list](https://groups.google.com/forum/#!forum/casperjs) |
23 | 23 | ||
24 | Follow [@casperjs_org on twitter](https://twitter.com/casperjs_org). | ||
24 | 25 | ||
25 | ## Contributing to the docs | 26 | ## Contributing to the docs |
26 | 27 | ... | ... |
... | @@ -27,6 +27,10 @@ | ... | @@ -27,6 +27,10 @@ |
27 | * DEALINGS IN THE SOFTWARE. | 27 | * DEALINGS IN THE SOFTWARE. |
28 | * | 28 | * |
29 | */ | 29 | */ |
30 | if (phantom.version.major !== 1 || phantom.version.minor < 5) { | ||
31 | console.error('CasperJS needs at least PhantomJS v1.5.0'); | ||
32 | phantom.exit(1); | ||
33 | } | ||
30 | 34 | ||
31 | /** | 35 | /** |
32 | * Loads and initialize the CasperJS environment. | 36 | * Loads and initialize the CasperJS environment. |
... | @@ -151,7 +155,7 @@ phantom.loadCasper = function loadCasper() { | ... | @@ -151,7 +155,7 @@ phantom.loadCasper = function loadCasper() { |
151 | * TODO: remove when PhantomJS has full module support | 155 | * TODO: remove when PhantomJS has full module support |
152 | */ | 156 | */ |
153 | require = (function _require(require, requireDir) { | 157 | require = (function _require(require, requireDir) { |
154 | var phantomBuiltins = ['fs', 'webpage', 'webserver']; | 158 | var phantomBuiltins = ['fs', 'webpage', 'webserver', 'system']; |
155 | var phantomRequire = phantom.__orig__require = require; | 159 | var phantomRequire = phantom.__orig__require = require; |
156 | var requireCache = {}; | 160 | var requireCache = {}; |
157 | return function _require(path) { | 161 | return function _require(path) { |
... | @@ -229,32 +233,6 @@ phantom.loadCasper = function loadCasper() { | ... | @@ -229,32 +233,6 @@ phantom.loadCasper = function loadCasper() { |
229 | }; | 233 | }; |
230 | 234 | ||
231 | /** | 235 | /** |
232 | * Custom global error handler. | ||
233 | */ | ||
234 | phantom.onError = function phantom_onError(msg, backtrace) { | ||
235 | var c = require('colorizer').create(); | ||
236 | var match = /^(.*): __mod_error(.*):: (.*)/.exec(msg); | ||
237 | var notices = []; | ||
238 | if (match && match.length === 4) { | ||
239 | notices.push(' in module ' + match[2]); | ||
240 | notices.push(' NOTICE: errors within modules cannot be backtraced yet.'); | ||
241 | msg = match[3]; | ||
242 | } | ||
243 | console.error(c.colorize(msg, 'RED_BAR', 80)); | ||
244 | notices.forEach(function(notice) { | ||
245 | console.error(c.colorize(notice, 'COMMENT')); | ||
246 | }); | ||
247 | backtrace.forEach(function(item) { | ||
248 | var message = require('fs').absolute(item.file) + ":" + c.colorize(item.line, "COMMENT"); | ||
249 | if (item['function']) { | ||
250 | message += " in " + c.colorize(item['function'], "PARAMETER"); | ||
251 | } | ||
252 | console.error(" " + message); | ||
253 | }); | ||
254 | phantom.exit(1); | ||
255 | }; | ||
256 | |||
257 | /** | ||
258 | * Initializes the CasperJS Command Line Interface. | 236 | * Initializes the CasperJS Command Line Interface. |
259 | */ | 237 | */ |
260 | phantom.initCasperCli = function initCasperCli() { | 238 | phantom.initCasperCli = function initCasperCli() { | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -29,13 +29,13 @@ | ... | @@ -29,13 +29,13 @@ |
29 | */ | 29 | */ |
30 | (function(exports) { | 30 | (function(exports) { |
31 | exports.create = function create() { | 31 | exports.create = function create() { |
32 | return new ClientUtils(); | 32 | return new this.ClientUtils(); |
33 | }; | 33 | }; |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * Casper client-side helpers. | 36 | * Casper client-side helpers. |
37 | */ | 37 | */ |
38 | ClientUtils = function ClientUtils() { | 38 | exports.ClientUtils = function ClientUtils() { |
39 | var BASE64_ENCODE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 39 | var BASE64_ENCODE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
40 | var BASE64_DECODE_CHARS = new Array( | 40 | var BASE64_DECODE_CHARS = new Array( |
41 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | 41 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
... | @@ -56,16 +56,7 @@ | ... | @@ -56,16 +56,7 @@ |
56 | * @return Boolean | 56 | * @return Boolean |
57 | */ | 57 | */ |
58 | this.click = function click(selector) { | 58 | this.click = function click(selector) { |
59 | var elem = this.findOne(selector); | 59 | return this.mouseEvent('click', selector); |
60 | if (!elem) { | ||
61 | this.log("click(): Couldn't find any element matching '" + selector + "' selector", "error"); | ||
62 | return false; | ||
63 | } | ||
64 | var evt = document.createEvent("MouseEvents"); | ||
65 | evt.initMouseEvent("click", true, true, window, 1, 1, 1, 1, 1, false, false, false, false, 0, elem); | ||
66 | // dispatchEvent return value is false if at least one of the event | ||
67 | // handlers which handled this event called preventDefault | ||
68 | return elem.dispatchEvent(evt); | ||
69 | }; | 60 | }; |
70 | 61 | ||
71 | /** | 62 | /** |
... | @@ -380,19 +371,6 @@ | ... | @@ -380,19 +371,6 @@ |
380 | }; | 371 | }; |
381 | 372 | ||
382 | /** | 373 | /** |
383 | * Removes all DOM elements matching a given XPath expression. | ||
384 | * | ||
385 | * @param String expression The XPath expression | ||
386 | * @return Array | ||
387 | */ | ||
388 | this.removeElementsByXPath = function removeElementsByXPath(expression) { | ||
389 | var a = document.evaluate(expression, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); | ||
390 | for (var i = 0; i < a.snapshotLength; i++) { | ||
391 | a.snapshotItem(i).parentNode.removeChild(a.snapshotItem(i)); | ||
392 | } | ||
393 | }; | ||
394 | |||
395 | /** | ||
396 | * Logs a message. Will format the message a way CasperJS will be able | 374 | * Logs a message. Will format the message a way CasperJS will be able |
397 | * to log phantomjs side. | 375 | * to log phantomjs side. |
398 | * | 376 | * |
... | @@ -404,6 +382,26 @@ | ... | @@ -404,6 +382,26 @@ |
404 | }; | 382 | }; |
405 | 383 | ||
406 | /** | 384 | /** |
385 | * Dispatches a mouse event to the DOM element behind the provided selector. | ||
386 | * | ||
387 | * @param String type Type of event to dispatch | ||
388 | * @param String selector A CSS3 selector to the element to click | ||
389 | * @return Boolean | ||
390 | */ | ||
391 | this.mouseEvent = function mouseEvent(type, selector) { | ||
392 | var elem = this.findOne(selector); | ||
393 | if (!elem) { | ||
394 | this.log("mouseEvent(): Couldn't find any element matching '" + selector + "' selector", "error"); | ||
395 | return false; | ||
396 | } | ||
397 | var evt = document.createEvent("MouseEvents"); | ||
398 | evt.initMouseEvent(type, true, true, window, 1, 1, 1, 1, 1, false, false, false, false, 0, elem); | ||
399 | // dispatchEvent return value is false if at least one of the event | ||
400 | // handlers which handled this event called preventDefault | ||
401 | return elem.dispatchEvent(evt); | ||
402 | }; | ||
403 | |||
404 | /** | ||
407 | * Processes a selector input, either as a string or an object. | 405 | * Processes a selector input, either as a string or an object. |
408 | * | 406 | * |
409 | * If passed an object, if must be of the form: | 407 | * If passed an object, if must be of the form: |
... | @@ -420,7 +418,7 @@ | ... | @@ -420,7 +418,7 @@ |
420 | this.processSelector = function processSelector(selector) { | 418 | this.processSelector = function processSelector(selector) { |
421 | var selectorObject = { | 419 | var selectorObject = { |
422 | toString: function toString() { | 420 | toString: function toString() { |
423 | return this.type + ' selector: ' + this.selector; | 421 | return this.type + ' selector: ' + this.path; |
424 | } | 422 | } |
425 | }; | 423 | }; |
426 | if (typeof selector === "string") { | 424 | if (typeof selector === "string") { |
... | @@ -444,6 +442,19 @@ | ... | @@ -444,6 +442,19 @@ |
444 | }; | 442 | }; |
445 | 443 | ||
446 | /** | 444 | /** |
445 | * Removes all DOM elements matching a given XPath expression. | ||
446 | * | ||
447 | * @param String expression The XPath expression | ||
448 | * @return Array | ||
449 | */ | ||
450 | this.removeElementsByXPath = function removeElementsByXPath(expression) { | ||
451 | var a = document.evaluate(expression, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); | ||
452 | for (var i = 0; i < a.snapshotLength; i++) { | ||
453 | a.snapshotItem(i).parentNode.removeChild(a.snapshotItem(i)); | ||
454 | } | ||
455 | }; | ||
456 | |||
457 | /** | ||
447 | * Sets a field (or a set of fields) value. Fails silently, but log | 458 | * Sets a field (or a set of fields) value. Fails silently, but log |
448 | * error messages. | 459 | * error messages. |
449 | * | 460 | * |
... | @@ -546,14 +557,19 @@ | ... | @@ -546,14 +557,19 @@ |
546 | */ | 557 | */ |
547 | this.visible = function visible(selector) { | 558 | this.visible = function visible(selector) { |
548 | try { | 559 | try { |
549 | var el = this.findOne(selector); | 560 | var comp, |
550 | return el && el.style.visibility !== 'hidden' && el.offsetHeight > 0 && el.offsetWidth > 0; | 561 | el = this.findOne(selector); |
562 | |||
563 | if (el) { | ||
564 | comp = window.getComputedStyle(el, null); | ||
565 | return comp.visibility !== 'hidden' && comp.display !== 'none' && el.offsetHeight > 0 && el.offsetWidth > 0; | ||
566 | } | ||
567 | return false; | ||
551 | } catch (e) { | 568 | } catch (e) { |
552 | return false; | 569 | return false; |
553 | } | 570 | } |
554 | }; | 571 | }; |
555 | }; | 572 | }; |
556 | exports.ClientUtils = ClientUtils; | ||
557 | 573 | ||
558 | // silly "hack" to force having an instance available | 574 | // silly "hack" to force having an instance available |
559 | exports.__utils__ = new exports.ClientUtils(); | 575 | exports.__utils__ = new exports.ClientUtils(); | ... | ... |
... | @@ -31,13 +31,19 @@ | ... | @@ -31,13 +31,19 @@ |
31 | var fs = require('fs'); | 31 | var fs = require('fs'); |
32 | var utils = require('utils'); | 32 | var utils = require('utils'); |
33 | 33 | ||
34 | exports.create = function create() { | 34 | exports.create = function create(type) { |
35 | return new Colorizer(); | 35 | if (!type) { |
36 | return; | ||
37 | } | ||
38 | if (!(type in exports)) { | ||
39 | throw new Error(utils.format('Unsupported colorizer type "%s"', type)); | ||
40 | } | ||
41 | return new exports[type](); | ||
36 | }; | 42 | }; |
37 | 43 | ||
38 | /** | 44 | /** |
39 | * This is a port of lime colorizer. | 45 | * This is a port of lime colorizer. |
40 | * http://trac.symfony-project.org/browser/tools/lime/trunk/lib/lime.php) | 46 | * http://trac.symfony-project.org/browser/tools/lime/trunk/lib/lime.php |
41 | * | 47 | * |
42 | * (c) Fabien Potencier, Symfony project, MIT license | 48 | * (c) Fabien Potencier, Symfony project, MIT license |
43 | */ | 49 | */ |
... | @@ -102,3 +108,17 @@ var Colorizer = function Colorizer() { | ... | @@ -102,3 +108,17 @@ var Colorizer = function Colorizer() { |
102 | }; | 108 | }; |
103 | }; | 109 | }; |
104 | exports.Colorizer = Colorizer; | 110 | exports.Colorizer = Colorizer; |
111 | |||
112 | /** | ||
113 | * Dummy colorizer. Does basically nothing. | ||
114 | * | ||
115 | */ | ||
116 | var Dummy = function Dummy() { | ||
117 | this.colorize = function colorize(text, styleName, pad) { | ||
118 | return text; | ||
119 | }; | ||
120 | this.format = function format(text, style, pad){ | ||
121 | return text; | ||
122 | }; | ||
123 | }; | ||
124 | exports.Dummy = Dummy; | ... | ... |
... | @@ -67,7 +67,9 @@ var FunctionArgsInjector = function FunctionArgsInjector(fn) { | ... | @@ -67,7 +67,9 @@ var FunctionArgsInjector = function FunctionArgsInjector(fn) { |
67 | throw new CasperError("Unable to process function " + this.fn.toString()); | 67 | throw new CasperError("Unable to process function " + this.fn.toString()); |
68 | } | 68 | } |
69 | var inject = this.getArgsInjectionString(fnObj.args, values); | 69 | var inject = this.getArgsInjectionString(fnObj.args, values); |
70 | return 'function ' + (fnObj.name || '') + '(){' + inject + fnObj.body + '}'; | 70 | var newFn = new Function([inject, fnObj.body].join('\n')); |
71 | newFn.name = fnObj.name || ''; | ||
72 | return newFn; | ||
71 | }; | 73 | }; |
72 | 74 | ||
73 | this.getArgsInjectionString = function getArgsInjectionString(args, values) { | 75 | this.getArgsInjectionString = function getArgsInjectionString(args, values) { | ... | ... |
... | @@ -39,7 +39,11 @@ var Mouse = function Mouse(casper) { | ... | @@ -39,7 +39,11 @@ var Mouse = function Mouse(casper) { |
39 | throw new CasperError('Mouse() needs a Casper instance'); | 39 | throw new CasperError('Mouse() needs a Casper instance'); |
40 | } | 40 | } |
41 | 41 | ||
42 | var supportedEvents = ['mouseup', 'mousedown', 'click', 'mousemove']; | 42 | var slice = Array.prototype.slice; |
43 | |||
44 | var nativeEvents = ['mouseup', 'mousedown', 'click', 'mousemove']; | ||
45 | var emulatedEvents = ['mouseover', 'mouseout']; | ||
46 | var supportedEvents = nativeEvents.concat(emulatedEvents); | ||
43 | 47 | ||
44 | function computeCenter(selector) { | 48 | function computeCenter(selector) { |
45 | var bounds = casper.getElementBounds(selector); | 49 | var bounds = casper.getElementBounds(selector); |
... | @@ -54,7 +58,10 @@ var Mouse = function Mouse(casper) { | ... | @@ -54,7 +58,10 @@ var Mouse = function Mouse(casper) { |
54 | if (!utils.isString(type) || supportedEvents.indexOf(type) === -1) { | 58 | if (!utils.isString(type) || supportedEvents.indexOf(type) === -1) { |
55 | throw new CasperError('Mouse.processEvent(): Unsupported mouse event type: ' + type); | 59 | throw new CasperError('Mouse.processEvent(): Unsupported mouse event type: ' + type); |
56 | } | 60 | } |
57 | args = Array.prototype.slice.call(args); // cast Arguments -> Array | 61 | if (emulatedEvents.indexOf(type) > -1) { |
62 | casper.log("Mouse.processEvent(): no native fallback for type " + type, "warning"); | ||
63 | } | ||
64 | args = slice.call(args); // cast Arguments -> Array | ||
58 | casper.emit('mouse.' + type.replace('mouse', ''), args); | 65 | casper.emit('mouse.' + type.replace('mouse', ''), args); |
59 | switch (args.length) { | 66 | switch (args.length) { |
60 | case 0: | 67 | case 0: |
... | @@ -62,9 +69,6 @@ var Mouse = function Mouse(casper) { | ... | @@ -62,9 +69,6 @@ var Mouse = function Mouse(casper) { |
62 | case 1: | 69 | case 1: |
63 | // selector | 70 | // selector |
64 | var selector = args[0]; | 71 | var selector = args[0]; |
65 | if (!utils.isString(selector)) { | ||
66 | throw new CasperError('Mouse.processEvent(): No valid CSS selector passed: ' + selector); | ||
67 | } | ||
68 | casper.page.sendEvent.apply(casper.page, [type].concat(computeCenter(selector))); | 72 | casper.page.sendEvent.apply(casper.page, [type].concat(computeCenter(selector))); |
69 | break; | 73 | break; |
70 | case 2: | 74 | case 2: |
... | @@ -79,6 +83,10 @@ var Mouse = function Mouse(casper) { | ... | @@ -79,6 +83,10 @@ var Mouse = function Mouse(casper) { |
79 | } | 83 | } |
80 | } | 84 | } |
81 | 85 | ||
86 | this.processEvent = function() { | ||
87 | processEvent(arguments[0], slice.call(arguments, 1)); | ||
88 | }; | ||
89 | |||
82 | this.click = function click() { | 90 | this.click = function click() { |
83 | processEvent('click', arguments); | 91 | processEvent('click', arguments); |
84 | }; | 92 | }; | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -131,27 +131,22 @@ function format(f) { | ... | @@ -131,27 +131,22 @@ function format(f) { |
131 | exports.format = format; | 131 | exports.format = format; |
132 | 132 | ||
133 | /** | 133 | /** |
134 | * Inherit the prototype methods from one constructor into another, also | 134 | * Inherit the prototype methods from one constructor into another. |
135 | * exposes the `__super__` property to child class. | ||
136 | * | 135 | * |
137 | * @param Function child Constructor function which needs to inherit the | 136 | * @param {function} ctor Constructor function which needs to inherit the |
138 | * prototype. | 137 | * prototype. |
139 | * @param Function parent Constructor function to inherit prototype from. | 138 | * @param {function} superCtor Constructor function to inherit prototype from. |
140 | * @return Function The child class | ||
141 | */ | 139 | */ |
142 | function inherits(child, parent) { | 140 | function inherits(ctor, superCtor) { |
143 | for (var key in parent) { | 141 | ctor.super_ = ctor.__super__ = superCtor; |
144 | if (Object.prototype.hasOwnProperty.call(parent, key)) { | 142 | ctor.prototype = Object.create(superCtor.prototype, { |
145 | child[key] = parent[key]; | 143 | constructor: { |
144 | value: ctor, | ||
145 | enumerable: false, | ||
146 | writable: true, | ||
147 | configurable: true | ||
146 | } | 148 | } |
147 | } | 149 | }); |
148 | function ctor() { | ||
149 | this.constructor = child; | ||
150 | } | ||
151 | ctor.prototype = parent.prototype; | ||
152 | child.prototype = new ctor(); | ||
153 | child.__super__ = parent.prototype; | ||
154 | return child; | ||
155 | } | 150 | } |
156 | exports.inherits = inherits; | 151 | exports.inherits = inherits; |
157 | 152 | ||
... | @@ -305,23 +300,23 @@ exports.isWebPage = isWebPage; | ... | @@ -305,23 +300,23 @@ exports.isWebPage = isWebPage; |
305 | /** | 300 | /** |
306 | * Object recursive merging utility. | 301 | * Object recursive merging utility. |
307 | * | 302 | * |
308 | * @param Object obj1 the destination object | 303 | * @param Object origin the origin object |
309 | * @param Object obj2 the source object | 304 | * @param Object add the object to merge data into origin |
310 | * @return Object | 305 | * @return Object |
311 | */ | 306 | */ |
312 | function mergeObjects(obj1, obj2) { | 307 | function mergeObjects(origin, add) { |
313 | for (var p in obj2) { | 308 | for (var p in add) { |
314 | try { | 309 | try { |
315 | if (obj2[p].constructor === Object) { | 310 | if (add[p].constructor === Object) { |
316 | obj1[p] = mergeObjects(obj1[p], obj2[p]); | 311 | origin[p] = mergeObjects(origin[p], add[p]); |
317 | } else { | 312 | } else { |
318 | obj1[p] = obj2[p]; | 313 | origin[p] = add[p]; |
319 | } | 314 | } |
320 | } catch(e) { | 315 | } catch(e) { |
321 | obj1[p] = obj2[p]; | 316 | origin[p] = add[p]; |
322 | } | 317 | } |
323 | } | 318 | } |
324 | return obj1; | 319 | return origin; |
325 | } | 320 | } |
326 | exports.mergeObjects = mergeObjects; | 321 | exports.mergeObjects = mergeObjects; |
327 | 322 | ... | ... |
1 | { | 1 | { |
2 | "name": "casperjs", | 2 | "name": "casperjs", |
3 | "description": "Navigation scripting & testing utility for PhantomJS", | 3 | "description": "Navigation scripting & testing utility for PhantomJS", |
4 | "version": "0.6.8", | 4 | "version": "0.6.10", |
5 | "keywords": [ | 5 | "keywords": [ |
6 | "phantomjs", | 6 | "phantomjs", |
7 | "javascript" | 7 | "javascript" |
... | @@ -14,7 +14,7 @@ | ... | @@ -14,7 +14,7 @@ |
14 | } | 14 | } |
15 | ], | 15 | ], |
16 | "dependencies": { | 16 | "dependencies": { |
17 | "http://www.phantomjs.org/": "1.3" | 17 | "http://www.phantomjs.org/": "1.5" |
18 | }, | 18 | }, |
19 | "bugs": { | 19 | "bugs": { |
20 | "url": "https://github.com/n1k0/casperjs/issues" | 20 | "url": "https://github.com/n1k0/casperjs/issues" | ... | ... |
1 | casper = require("casper").create() | 1 | casper = require("casper").create() |
2 | 2 | ||
3 | ### listening to a custom event ### | 3 | # listening to a custom event |
4 | casper.on "google.loaded", (title) -> | 4 | casper.on "google.loaded", (title) -> |
5 | casper.echo "Google page title is #{title}" | 5 | @echo "Google page title is #{title}" |
6 | 6 | ||
7 | casper.start "http://google.com/", -> | 7 | casper.start "http://google.com/", -> |
8 | ### emitting a custom event ### | 8 | # emitting a custom event |
9 | @emit "google.loaded", @getTitle() | 9 | @emit "google.loaded", @getTitle() |
10 | 10 | ||
11 | casper.run() | 11 | casper.run() | ... | ... |
1 | var casper; | 1 | var casper = require("casper").create(); |
2 | 2 | ||
3 | casper = require("casper").create(); | 3 | // listening to a custom event |
4 | |||
5 | /* listening to a custom event */ | ||
6 | casper.on("google.loaded", function(title) { | 4 | casper.on("google.loaded", function(title) { |
7 | casper.echo("Google page title is " + title); | 5 | this.echo("Google page title is " + title); |
8 | }); | 6 | }); |
9 | 7 | ||
10 | casper.start("http://google.com/", function() { | 8 | casper.start("http://google.com/", function() { |
11 | /* emitting a custom event */ | 9 | // emitting a custom event |
12 | this.emit("google.loaded", this.getTitle()); | 10 | this.emit("google.loaded", this.getTitle()); |
13 | }); | 11 | }); |
14 | 12 | ... | ... |
1 | ### | 1 | ### |
2 | A basic custom logging implementation. The idea is to (extremely) verbosely log | 2 | A basic custom logging implementation. The idea is to (extremely) verbosely |
3 | every received resource. | 3 | log every received resource. |
4 | ### | 4 | ### |
5 | 5 | ||
6 | casper = require("casper").create | 6 | casper = require("casper").create |
7 | ### | 7 | ### |
8 | Every time a resource is received, a new log entry is added to the stack at | 8 | Every time a resource is received, a new log entry is added to the stack |
9 | the 'verbose' level. | 9 | at the 'verbose' level. |
10 | |||
11 | @param Object resource A phantomjs resource object | ||
10 | ### | 12 | ### |
11 | onResourceReceived: (self, resource) -> | 13 | onResourceReceived: (self, resource) -> |
12 | infos = [] | 14 | infos = [] |
... | @@ -23,9 +25,9 @@ casper = require("casper").create | ... | @@ -23,9 +25,9 @@ casper = require("casper").create |
23 | verbose: true # we want to see the log printed out to the console | 25 | verbose: true # we want to see the log printed out to the console |
24 | logLevel: "verbose" # of course we want to see logs to our new level :) | 26 | logLevel: "verbose" # of course we want to see logs to our new level :) |
25 | 27 | ||
26 | ### add a new 'verbose' logging level at the lowest priority ### | 28 | # add a new 'verbose' logging level at the lowest priority |
27 | casper.logLevels = ["verbose"].concat casper.logLevels | 29 | casper.logLevels = ["verbose"].concat casper.logLevels |
28 | 30 | ||
29 | ### test our new logger with google ### | 31 | # test our new logger with google |
30 | casper.start "http://www.google.com/" | 32 | casper.start("http://www.google.com/").run -> |
31 | casper.run() | 33 | @exit() | ... | ... |
1 | /* | 1 | /* |
2 | A basic custom logging implementation. The idea is to (extremely) verbosely log | 2 | * A basic custom logging implementation. The idea is to (extremely) verbosely |
3 | every received resource. | 3 | * log every received resource. |
4 | */ | 4 | */ |
5 | |||
6 | var casper; | ||
7 | 5 | ||
8 | casper = require("casper").create({ | 6 | var casper = require("casper").create({ |
9 | /* | 7 | /* |
10 | Every time a resource is received, a new log entry is added to the stack at | 8 | Every time a resource is received, a new log entry is added to the stack at |
11 | the 'verbose' level. | 9 | the 'verbose' level. |
... | @@ -38,7 +36,7 @@ casper = require("casper").create({ | ... | @@ -38,7 +36,7 @@ casper = require("casper").create({ |
38 | /* add a new 'verbose' logging level at the lowest priority */ | 36 | /* add a new 'verbose' logging level at the lowest priority */ |
39 | casper.logLevels = ["verbose"].concat(casper.logLevels); | 37 | casper.logLevels = ["verbose"].concat(casper.logLevels); |
40 | 38 | ||
41 | /* test our new logger with google */ | ||
42 | casper.start("http://www.google.com/"); | ||
43 | |||
44 | casper.run(); | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
39 | // test our new logger with google | ||
40 | casper.start("http://www.google.com/").run(function() { | ||
41 | this.exit(); | ||
42 | }); | ... | ... |
1 | ### | 1 | ### |
2 | Download the google logo image as base64 | 2 | Download the google logo image onto the local filesystem |
3 | ### | 3 | ### |
4 | 4 | ||
5 | casper = require("casper").create verbose: true | 5 | casper = require("casper").create() |
6 | 6 | ||
7 | casper.start "http://www.google.fr/", -> | 7 | casper.start "http://www.google.fr/", -> |
8 | @echo @base64encode "http://www.google.fr/images/srpr/logo3w.png" | 8 | @echo @download "http://www.google.fr/images/srpr/logo3w.png", "logo.png" |
9 | 9 | ||
10 | casper.run() | 10 | casper.run() | ... | ... |
1 | /* | 1 | /* |
2 | Download the google logo image as base64 | 2 | * download the google logo image onto the local filesystem |
3 | */ | 3 | */ |
4 | 4 | ||
5 | var casper; | 5 | var casper = require("casper").create(); |
6 | |||
7 | casper = require("casper").create({ | ||
8 | verbose: true | ||
9 | }); | ||
10 | 6 | ||
11 | casper.start("http://www.google.fr/", function() { | 7 | casper.start("http://www.google.fr/", function() { |
12 | this.echo(this.base64encode("http://www.google.fr/images/srpr/logo3w.png")); | 8 | this.download("http://www.google.fr/images/srpr/logo3w.png", "logo.png"); |
13 | }); | 9 | }); |
14 | 10 | ||
15 | casper.run(); | 11 | casper.run(); | ... | ... |
... | @@ -29,21 +29,18 @@ links = [ | ... | @@ -29,21 +29,18 @@ links = [ |
29 | "http://bing.com/" | 29 | "http://bing.com/" |
30 | ]; | 30 | ]; |
31 | 31 | ||
32 | /* Just opens the page and prints the title */ | 32 | // Just opens the page and prints the title |
33 | start = function(link) { | 33 | var start = function(link) { |
34 | this.start(link, function() { | 34 | this.start(link, function() { |
35 | this.echo("Page title: " + this.getTitle()); | 35 | this.echo('Page title: ' + this.getTitle()); |
36 | }); | 36 | }); |
37 | }; | 37 | }; |
38 | 38 | ||
39 | /* | 39 | // Get the links, and add them to the links array |
40 | Get the links, and add them to the links array | 40 | // (It could be done all in one step, but it is intentionally splitted) |
41 | (It could be done all in one step, but it is intentionally splitted) | 41 | var addLinks = function(link) { |
42 | */ | ||
43 | addLinks = function(link) { | ||
44 | this.then(function() { | 42 | this.then(function() { |
45 | var found; | 43 | var found = this.evaluate(searchLinks); |
46 | found = this.evaluate(searchLinks); | ||
47 | this.echo(found.length + " links found on " + link); | 44 | this.echo(found.length + " links found on " + link); |
48 | links = links.concat(found); | 45 | links = links.concat(found); |
49 | }); | 46 | }); |
... | @@ -57,10 +54,10 @@ casper.then(function() { | ... | @@ -57,10 +54,10 @@ casper.then(function() { |
57 | 54 | ||
58 | currentLink = 0; | 55 | currentLink = 0; |
59 | 56 | ||
60 | /* As long as it has a next link, and is under the maximum limit, will keep running */ | 57 | // As long as it has a next link, and is under the maximum limit, will keep running |
61 | check = function() { | 58 | function check() { |
62 | if (links[currentLink] && currentLink < upTo) { | 59 | if (links[currentLink] && currentLink < upTo) { |
63 | this.echo("--- Link " + currentLink + " ---"); | 60 | this.echo('--- Link ' + currentLink + ' ---'); |
64 | start.call(this, links[currentLink]); | 61 | start.call(this, links[currentLink]); |
65 | addLinks.call(this, links[currentLink]); | 62 | addLinks.call(this, links[currentLink]); |
66 | currentLink++; | 63 | currentLink++; | ... | ... |
1 | getLinks = -> | 1 | getLinks = -> |
2 | links = document.querySelectorAll "h3.r a" | 2 | links = document.querySelectorAll("h3.r a") |
3 | Array::map.call links, (e) -> e.getAttribute "href" | 3 | Array::map.call links, (e) -> |
4 | 4 | e.getAttribute "href" | |
5 | links = [] | ||
6 | casper = require("casper").create() | ||
7 | 5 | ||
8 | casper.start "http://google.fr/", -> | 6 | casper.start "http://google.fr/", -> |
9 | ### search for 'casperjs' from google form ### | 7 | # search for 'casperjs' from google form |
10 | @fill 'form[action="/search"]', q: "casperjs", true | 8 | @fill "form[action=\"/search\"]", q: "casperjs" , true |
11 | 9 | ||
12 | casper.then -> | 10 | casper.then -> |
13 | ### aggregate results for the 'casperjs' search ### | 11 | # aggregate results for the 'casperjs' search |
14 | links = @evaluate getLinks | 12 | links = @evaluate(getLinks) |
15 | ### search for 'phantomjs' from google form ### | 13 | # now search for 'phantomjs' by fillin the form again |
16 | @fill 'form[action="/search"]', q: "phantomjs", true | 14 | @fill "form[action=\"/search\"]", q: "phantomjs" , true |
17 | 15 | ||
18 | casper.then -> | 16 | casper.then -> |
19 | ### concat results for the 'phantomjs' search ### | 17 | # aggregate results for the 'phantomjs' search |
20 | links = links.concat @evaluate(getLinks) | 18 | links = links.concat(@evaluate(getLinks)) |
21 | 19 | ||
22 | casper.run -> | 20 | casper.run -> |
23 | ### display results ### | 21 | # echo results in some pretty fashion |
24 | @echo "#{links.length} links found:" | 22 | @echo links.length + " links found:" |
25 | @echo " - " + links.join "\n - " | 23 | @echo(" - " + links.join("\n - ")) |
26 | @exit() | 24 | @exit() | ... | ... |
1 | var casper, getLinks, links; | 1 | var casper, getLinks, links; |
2 | 2 | ||
3 | getLinks = function() { | 3 | getLinks = function() { |
4 | var links; | 4 | var links = document.querySelectorAll("h3.r a"); |
5 | links = document.querySelectorAll("h3.r a"); | ||
6 | return Array.prototype.map.call(links, function(e) { | 5 | return Array.prototype.map.call(links, function(e) { |
7 | return e.getAttribute("href"); | 6 | return e.getAttribute("href"); |
8 | }); | 7 | }); |
9 | }; | 8 | }; |
10 | 9 | ||
11 | links = []; | ||
12 | |||
13 | casper = require("casper").create(); | ||
14 | |||
15 | casper.start("http://google.fr/", function() { | 10 | casper.start("http://google.fr/", function() { |
16 | /* search for 'casperjs' from google form */ | 11 | // search for 'casperjs' from google form |
17 | this.fill('form[action="/search"]', { | 12 | this.fill('form[action="/search"]', { q: "casperjs" }, true); |
18 | q: "casperjs" | ||
19 | }, true); | ||
20 | }); | 13 | }); |
21 | 14 | ||
22 | casper.then(function() { | 15 | casper.then(function() { |
23 | /* aggregate results for the 'casperjs' search */ | 16 | // aggregate results for the 'casperjs' search |
24 | links = this.evaluate(getLinks); | 17 | links = this.evaluate(getLinks); |
25 | /* search for 'phantomjs' from google form */ | 18 | // now search for 'phantomjs' by fillin the form again |
26 | this.fill('form[action="/search"]', { | 19 | this.fill('form[action="/search"]', { q: "phantomjs" }, true); |
27 | q: "phantomjs" | ||
28 | }, true); | ||
29 | }); | 20 | }); |
30 | 21 | ||
31 | casper.then(function() { | 22 | casper.then(function() { |
32 | /* concat results for the 'phantomjs' search */ | 23 | // aggregate results for the 'phantomjs' search |
33 | links = links.concat(this.evaluate(getLinks)); | 24 | links = links.concat(this.evaluate(getLinks)); |
34 | }); | 25 | }); |
35 | 26 | ||
36 | casper.run(function() { | 27 | casper.run(function() { |
37 | /* display results */ | 28 | // echo results in some pretty fashion |
38 | this.echo(links.length + " links found:"); | 29 | this.echo(links.length + " links found:"); |
39 | this.echo(" - " + links.join("\n - ")); | 30 | this.echo(" - " + links.join("\n - ")) |
40 | this.exit(); | 31 | this.exit(); |
41 | }); | 32 | }); | ... | ... |
... | @@ -15,7 +15,7 @@ casper = require("casper").create verbose: true | ... | @@ -15,7 +15,7 @@ casper = require("casper").create verbose: true |
15 | casper.fetchScore = -> | 15 | casper.fetchScore = -> |
16 | @evaluate -> | 16 | @evaluate -> |
17 | result = document.querySelector('#resultStats').innerText | 17 | result = document.querySelector('#resultStats').innerText |
18 | ~~(/Environ ([0-9\s]{1,}).*/.exec(result)[1].replace(/\s/g, '')) | 18 | parseInt /Environ ([0-9\s]{1,}).*/.exec(result)[1].replace(/\s/g, '') |
19 | 19 | ||
20 | terms = casper.cli.args # terms are passed through command-line arguments | 20 | terms = casper.cli.args # terms are passed through command-line arguments |
21 | 21 | ||
... | @@ -35,10 +35,13 @@ casper.each terms, (self, term) -> | ... | @@ -35,10 +35,13 @@ casper.each terms, (self, term) -> |
35 | @then -> | 35 | @then -> |
36 | score = @fetchScore() | 36 | score = @fetchScore() |
37 | scores.push term: term, score: score | 37 | scores.push term: term, score: score |
38 | self.echo "#{term}: #{score}" | 38 | @echo "#{term}: #{score}" |
39 | 39 | ||
40 | casper.run -> | 40 | casper.run -> |
41 | scores.sort (a, b) -> b.score - a.score; | 41 | if scores.length is 0 |
42 | @echo "No result found" | ||
43 | else | ||
44 | scores.sort (a, b) -> b.score - a.score | ||
42 | winner = scores[0] | 45 | winner = scores[0] |
43 | @echo "Winner is \"#{winner.term}\" with #{winner.score} results" | 46 | @echo "Winner is \"" + winner.term + "\" with " + winner.score + " results" |
44 | @exit() | 47 | @exit() | ... | ... |
1 | /* | 1 | /* |
2 | Takes provided terms passed as arguments and query google for the number of | 2 | * Takes provided terms passed as arguments and query google for the number of |
3 | estimated results each have. | 3 | * estimated results each have. |
4 | 4 | * | |
5 | Usage: | 5 | * Usage: |
6 | $ casperjs googlematch.js nicolas chuck borris | 6 | * $ casperjs googlematch.js nicolas chuck borris |
7 | nicolas: 69600000 | 7 | * nicolas: 69600000 |
8 | chuck: 49500000 | 8 | * chuck: 49500000 |
9 | borris: 2370000 | 9 | * borris: 2370000 |
10 | winner is "nicolas" with 69600000 results | 10 | * winner is "nicolas" with 69600000 results |
11 | */ | 11 | */ |
12 | 12 | ||
13 | var casper, scores, terms; | 13 | var casper, scores, terms; |
14 | 14 | ||
... | @@ -18,9 +18,8 @@ casper = require("casper").create({ | ... | @@ -18,9 +18,8 @@ casper = require("casper").create({ |
18 | 18 | ||
19 | casper.fetchScore = function() { | 19 | casper.fetchScore = function() { |
20 | return this.evaluate(function() { | 20 | return this.evaluate(function() { |
21 | var result; | 21 | var result = document.querySelector('#resultStats').innerText; |
22 | result = document.querySelector('#resultStats').innerText; | 22 | return parseInt(/Environ ([0-9\s]{1,}).*/.exec(result)[1].replace(/\s/g, ''), 10); |
23 | return ~~(/Environ ([0-9\s]{1,}).*/.exec(result)[1].replace(/\s/g, '')); | ||
24 | }); | 23 | }); |
25 | }; | 24 | }; |
26 | 25 | ||
... | @@ -39,29 +38,30 @@ casper.echo("Let the match begin between \"" + (terms.join('", "')) + "\"!"); | ... | @@ -39,29 +38,30 @@ casper.echo("Let the match begin between \"" + (terms.join('", "')) + "\"!"); |
39 | 38 | ||
40 | casper.start("http://google.fr/"); | 39 | casper.start("http://google.fr/"); |
41 | 40 | ||
42 | casper.each(terms, function(self, term) { | 41 | casper.each(terms, function(casper, term, i) { |
42 | this.echo('Fecthing score for ' + term); | ||
43 | this.then(function() { | 43 | this.then(function() { |
44 | this.fill('form[action="/search"]', { | 44 | this.fill('form[action="/search"]', {q: term}, true); |
45 | q: term | ||
46 | }, true); | ||
47 | }); | 45 | }); |
48 | this.then(function() { | 46 | this.then(function() { |
49 | var score; | 47 | var score = this.fetchScore(); |
50 | score = this.fetchScore(); | ||
51 | scores.push({ | 48 | scores.push({ |
52 | term: term, | 49 | term: term, |
53 | score: score | 50 | score: score |
54 | }); | 51 | }); |
55 | self.echo(term + ": " + score); | 52 | this.echo(term + ': ' + score); |
56 | }); | 53 | }); |
57 | }); | 54 | }); |
58 | 55 | ||
59 | casper.run(function() { | 56 | casper.run(function() { |
60 | var winner; | 57 | if (scores.length === 0) { |
58 | this.echo("No result found"); | ||
59 | } else { | ||
61 | scores.sort(function(a, b) { | 60 | scores.sort(function(a, b) { |
62 | return b.score - a.score; | 61 | return b.score - a.score; |
63 | }); | 62 | }); |
64 | winner = scores[0]; | 63 | var winner = scores[0]; |
65 | this.echo("Winner is \"" + winner.term + "\" with " + winner.score + " results"); | 64 | this.echo("Winner is \"" + winner.term + "\" with " + winner.score + " results"); |
65 | } | ||
66 | this.exit(); | 66 | this.exit(); |
67 | }); | 67 | }); | ... | ... |
1 | failed = []; | 1 | failed = [] |
2 | start = null | ||
3 | links = [ | ||
4 | "http://google.com/" | ||
5 | "http://akei.com/" | ||
6 | "http://lemonde.fr/" | ||
7 | "http://liberation.fr/" | ||
8 | "http://cdiscount.fr/" | ||
9 | ] | ||
2 | 10 | ||
3 | casper = require("casper").create | 11 | casper = require("casper").create |
4 | onStepTimeout: -> failed.push @requestUrl | 12 | onStepTimeout: -> |
13 | failed.push @requestUrl | ||
14 | @test.fail "#{@requestUrl} loads in less than #{timeout}ms." | ||
5 | 15 | ||
6 | links = [ | 16 | casper.on "load.finished", -> |
7 | 'http://google.com/' | 17 | @echo "#{@requestUrl} loaded in #{new Date() - start}ms", "PARAMETER" |
8 | 'http://akei.com/' | ||
9 | 'http://lemonde.fr/' | ||
10 | 'http://liberation.fr/' | ||
11 | 'http://cdiscount.fr/' | ||
12 | ] | ||
13 | 18 | ||
14 | timeout = ~~casper.cli.get(0) | 19 | timeout = ~~casper.cli.get(0) |
15 | timeout = 1000 if timeout < 1 | 20 | timeout = 1000 if timeout < 1 |
16 | casper.options.stepTimeout = timeout | 21 | casper.options.stepTimeout = timeout |
17 | 22 | ||
18 | casper.echo "Testing with timeout=#{casper.options.stepTimeout}ms." | 23 | casper.echo "Testing with timeout=#{timeout}ms, please be patient." |
19 | 24 | ||
20 | casper.start() | 25 | casper.start() |
21 | 26 | ||
22 | casper.each links, (self, link) -> | 27 | casper.each links, (self, link) -> |
23 | @test.comment "Adding #{link} to test suite" | 28 | @then -> |
24 | @thenOpen link, -> | 29 | @test.comment "Loading #{link}" |
25 | if @requestUrl in failed | 30 | start = new Date() |
26 | @test.fail "#{@requestUrl} loaded in less than #{timeout}ms." | 31 | @open link |
27 | else | 32 | @then -> |
33 | if @requestUrl not in failed | ||
28 | @test.pass "#{@requestUrl} loaded in less than #{timeout}ms." | 34 | @test.pass "#{@requestUrl} loaded in less than #{timeout}ms." |
29 | 35 | ||
30 | casper.run -> | 36 | casper.run -> | ... | ... |
1 | var casper, failed, links, timeout, | 1 | var failed = []; |
2 | __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; | 2 | var start = null; |
3 | 3 | var links = [ | |
4 | failed = []; | 4 | "http://google.com/'", |
5 | "http://akei.com/'", | ||
6 | "http://lemonde.fr/'", | ||
7 | "http://liberation.fr/'", | ||
8 | "http://cdiscount.fr/" | ||
9 | ]; | ||
5 | 10 | ||
6 | casper = require("casper").create({ | 11 | var casper = require("casper").create({ |
7 | onStepTimeout: function() { | 12 | onStepTimeout: function() { |
8 | failed.push(this.requestUrl); | 13 | failed.push(this.requestUrl); |
14 | this.test.fail(this.requestUrl + " loads in less than " + timeout + "ms."); | ||
9 | } | 15 | } |
10 | }); | 16 | }); |
11 | 17 | ||
12 | links = [ | 18 | casper.on("load.finished", function() { |
13 | 'http://google.com/', | 19 | this.echo(this.requestUrl + " loaded in " + (new Date() - start) + "ms", "PARAMETER"); |
14 | 'http://akei.com/', | 20 | }); |
15 | 'http://lemonde.fr/', | ||
16 | 'http://liberation.fr/', | ||
17 | 'http://cdiscount.fr/' | ||
18 | ]; | ||
19 | |||
20 | timeout = ~~casper.cli.get(0); | ||
21 | |||
22 | if (timeout < 1) { | ||
23 | timeout = 1000; | ||
24 | } | ||
25 | 21 | ||
26 | casper.options.stepTimeout = timeout; | 22 | var timeout = ~~casper.cli.get(0); |
23 | casper.options.stepTimeout = timeout > 0 ? timeout : 1000; | ||
27 | 24 | ||
28 | casper.echo("Testing with timeout=" + casper.options.stepTimeout + "ms."); | 25 | casper.echo("Testing with timeout=" + casper.options.stepTimeout + "ms, please be patient."); |
29 | 26 | ||
30 | casper.start(); | 27 | casper.start(); |
31 | 28 | ||
32 | casper.each(links, function(self, link) { | 29 | casper.each(links, function(casper, link) { |
33 | this.test.comment("Adding " + link + " to test suite"); | 30 | this.then(function() { |
34 | this.thenOpen(link, function() { | 31 | this.test.comment("Loading " + link); |
35 | var _ref; | 32 | start = new Date(); |
36 | if (_ref = this.requestUrl, __indexOf.call(failed, _ref) >= 0) { | 33 | this.open(link); |
37 | this.test.fail("" + this.requestUrl + " loaded in less than " + timeout + "ms."); | 34 | }); |
38 | } else { | 35 | this.then(function() { |
39 | this.test.pass("" + this.requestUrl + " loaded in less than " + timeout + "ms."); | 36 | var message = this.requestUrl + " loads in less than " + timeout + "ms."; |
37 | if (failed.indexOf(this.requestUrl) === -1) { | ||
38 | this.test.pass(message); | ||
40 | } | 39 | } |
41 | }); | 40 | }); |
42 | }); | 41 | }); | ... | ... |
... | @@ -4,12 +4,15 @@ Just a silly game. | ... | @@ -4,12 +4,15 @@ Just a silly game. |
4 | $ casperjs samples/timeout.js 500 | 4 | $ casperjs samples/timeout.js 500 |
5 | Will google.com load in less than 500ms? | 5 | Will google.com load in less than 500ms? |
6 | NOPE. | 6 | NOPE. |
7 | |||
7 | $ casperjs samples/timeout.js 1000 | 8 | $ casperjs samples/timeout.js 1000 |
8 | Will google.com load in less than 1000ms? | 9 | Will google.com load in less than 1000ms? |
9 | NOPE. | 10 | NOPE. |
11 | |||
10 | $ casperjs samples/timeout.js 1500 | 12 | $ casperjs samples/timeout.js 1500 |
11 | Will google.com load in less than 1500ms? | 13 | Will google.com load in less than 1500ms? |
12 | NOPE. | 14 | NOPE. |
15 | |||
13 | $ casperjs samples/timeout.js 2000 | 16 | $ casperjs samples/timeout.js 2000 |
14 | Will google.com load in less than 2000ms? | 17 | Will google.com load in less than 2000ms? |
15 | YES! | 18 | YES! | ... | ... |
1 | /* | 1 | /* |
2 | Just a silly game. | 2 | * Just a silly game. |
3 | 3 | * | |
4 | $ casperjs samples/timeout.js 500 | 4 | * $ casperjs samples/timeout.js 500 |
5 | Will google.com load in less than 500ms? | 5 | * Will google.com load in less than 500ms? |
6 | NOPE. | 6 | * NOPE. |
7 | $ casperjs samples/timeout.js 1000 | 7 | * |
8 | Will google.com load in less than 1000ms? | 8 | * $ casperjs samples/timeout.js 1000 |
9 | NOPE. | 9 | * Will google.com load in less than 1000ms? |
10 | $ casperjs samples/timeout.js 1500 | 10 | * NOPE. |
11 | Will google.com load in less than 1500ms? | 11 | * |
12 | NOPE. | 12 | * $ casperjs samples/timeout.js 1500 |
13 | $ casperjs samples/timeout.js 2000 | 13 | * Will google.com load in less than 1500ms? |
14 | Will google.com load in less than 2000ms? | 14 | * NOPE. |
15 | YES! | 15 | * |
16 | */ | 16 | * $ casperjs samples/timeout.js 2000 |
17 | * Will google.com load in less than 2000ms? | ||
18 | * YES! | ||
19 | */ | ||
17 | 20 | ||
18 | var casper, timeout; | 21 | var casper, timeout; |
19 | 22 | ||
... | @@ -39,7 +42,7 @@ casper.echo("Will google.com load in less than " + timeout + "ms?"); | ... | @@ -39,7 +42,7 @@ casper.echo("Will google.com load in less than " + timeout + "ms?"); |
39 | casper.options.timeout = timeout; | 42 | casper.options.timeout = timeout; |
40 | 43 | ||
41 | casper.start("http://www.google.com/", function() { | 44 | casper.start("http://www.google.com/", function() { |
42 | this.echo("YES!", 'GREEN_BAR'); | 45 | this.echo("YES!", "GREEN_BAR"); |
43 | this.exit(); | 46 | this.exit(); |
44 | }); | 47 | }); |
45 | 48 | ... | ... |
... | @@ -7,7 +7,7 @@ var fs = require('fs'); | ... | @@ -7,7 +7,7 @@ var fs = require('fs'); |
7 | var utils = require('utils'); | 7 | var utils = require('utils'); |
8 | var f = utils.format; | 8 | var f = utils.format; |
9 | var casper = require('casper').create({ | 9 | var casper = require('casper').create({ |
10 | faultTolerant: false | 10 | exitOnError: false |
11 | }); | 11 | }); |
12 | 12 | ||
13 | // Options from cli | 13 | // Options from cli | ... | ... |
... | @@ -19,7 +19,7 @@ | ... | @@ -19,7 +19,7 @@ |
19 | <input type="checkbox" name="checklist[]" value="1" /> | 19 | <input type="checkbox" name="checklist[]" value="1" /> |
20 | <input type="checkbox" name="checklist[]" value="2" /> | 20 | <input type="checkbox" name="checklist[]" value="2" /> |
21 | <input type="checkbox" name="checklist[]" value="3" /> | 21 | <input type="checkbox" name="checklist[]" value="3" /> |
22 | <input type="submit"/> | 22 | <input type="submit" name="submit" value="submit" /> |
23 | </form> | 23 | </form> |
24 | </body> | 24 | </body> |
25 | </html> | 25 | </html> | ... | ... |
tests/site/mouse-events.html
0 → 100644
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head> | ||
4 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | ||
5 | <title>CasperJS test mouse events</title> | ||
6 | </head> | ||
7 | <body> | ||
8 | <a id="test1" href="#" onmousedown="results.test1 = true;">test</a> | ||
9 | <a id="test2" href="#">test</a> | ||
10 | <a id="test3" href="#" onmouseup="results.test3 = true;">test</a> | ||
11 | <a id="test4" href="#">test</a> | ||
12 | <a id="test5" href="#" onmouseover="results.test5 = true;">test</a> | ||
13 | <a id="test6" href="#">test</a> | ||
14 | <a id="test7" href="#" onmouseout="results.test7 = true;">test</a> | ||
15 | <a id="test8" href="#">test</a> | ||
16 | <script> | ||
17 | (function(window) { | ||
18 | window.results = { | ||
19 | test1: false, | ||
20 | test2: false, | ||
21 | test3: false, | ||
22 | test4: false, | ||
23 | test5: false, | ||
24 | test6: false, | ||
25 | test7: false, | ||
26 | test8: false | ||
27 | }; | ||
28 | document.querySelector('#test2').onmousedown = function(event) { | ||
29 | results.test2 = true; | ||
30 | event.preventDefault(); | ||
31 | }; | ||
32 | document.querySelector('#test4').onmouseup = function(event) { | ||
33 | results.test4 = true; | ||
34 | event.preventDefault(); | ||
35 | }; | ||
36 | document.querySelector('#test6').onmouseover = function(event) { | ||
37 | results.test6 = true; | ||
38 | event.preventDefault(); | ||
39 | }; | ||
40 | document.querySelector('#test8').onmouseout = function(event) { | ||
41 | results.test8 = true; | ||
42 | event.preventDefault(); | ||
43 | }; | ||
44 | })(window); | ||
45 | </script> | ||
46 | </body> | ||
47 | </html> |
... | @@ -12,16 +12,30 @@ casper.then(function() { | ... | @@ -12,16 +12,30 @@ casper.then(function() { |
12 | 12 | ||
13 | // onclick variants tests | 13 | // onclick variants tests |
14 | casper.thenOpen('tests/site/click.html', function() { | 14 | casper.thenOpen('tests/site/click.html', function() { |
15 | this.test.comment('CasperUtils.click()'); | 15 | this.test.comment('Casper.click()'); |
16 | this.test.assert(this.click('#test1'), 'CasperUtils.click() can click an `href="javascript:` link'); | 16 | this.test.assert(this.click('#test1'), 'Casper.click() can click an `href="javascript:` link'); |
17 | this.test.assert(this.click('#test2'), 'CasperUtils.click() can click an `href="#"` link'); | 17 | this.test.assert(this.click('#test2'), 'Casper.click() can click an `href="#"` link'); |
18 | this.test.assert(this.click('#test3'), 'CasperUtils.click() can click an `onclick=".*; return false"` link'); | 18 | this.test.assert(this.click('#test3'), 'Casper.click() can click an `onclick=".*; return false"` link'); |
19 | this.test.assert(this.click('#test4'), 'CasperUtils.click() can click an unobstrusive js handled link'); | 19 | this.test.assert(this.click('#test4'), 'Casper.click() can click an unobstrusive js handled link'); |
20 | var results = this.getGlobal('results'); | ||
21 | this.test.assert(results.test1, 'Casper.click() has clicked an `href="javascript:` link'); | ||
22 | this.test.assert(results.test2, 'Casper.click() has clicked an `href="#"` link'); | ||
23 | this.test.assert(results.test3, 'Casper.click() has clicked an `onclick=".*; return false"` link'); | ||
24 | this.test.assert(results.test4, 'Casper.click() has clicked an unobstrusive js handled link'); | ||
25 | }); | ||
26 | |||
27 | // clickLabel tests | ||
28 | casper.thenOpen('tests/site/click.html', function() { | ||
29 | this.test.comment('Casper.clickLabel()'); | ||
30 | this.test.assert(this.clickLabel('test1'), 'Casper.clickLabel() can click an `href="javascript:` link'); | ||
31 | this.test.assert(this.clickLabel('test2'), 'Casper.clickLabel() can click an `href="#"` link'); | ||
32 | this.test.assert(this.clickLabel('test3'), 'Casper.clickLabel() can click an `onclick=".*; return false"` link'); | ||
33 | this.test.assert(this.clickLabel('test4'), 'Casper.clickLabel() can click an unobstrusive js handled link'); | ||
20 | var results = this.getGlobal('results'); | 34 | var results = this.getGlobal('results'); |
21 | this.test.assert(results.test1, 'CasperUtils.click() has clicked an `href="javascript:` link'); | 35 | this.test.assert(results.test1, 'Casper.clickLabel() has clicked an `href="javascript:` link'); |
22 | this.test.assert(results.test2, 'CasperUtils.click() has clicked an `href="#"` link'); | 36 | this.test.assert(results.test2, 'Casper.clickLabel() has clicked an `href="#"` link'); |
23 | this.test.assert(results.test3, 'CasperUtils.click() has clicked an `onclick=".*; return false"` link'); | 37 | this.test.assert(results.test3, 'Casper.clickLabel() has clicked an `onclick=".*; return false"` link'); |
24 | this.test.assert(results.test4, 'CasperUtils.click() has clicked an unobstrusive js handled link'); | 38 | this.test.assert(results.test4, 'Casper.clickLabel() has clicked an unobstrusive js handled link'); |
25 | }); | 39 | }); |
26 | 40 | ||
27 | // casper.mouse | 41 | // casper.mouse | ... | ... |
tests/suites/casper/mouseevents.js
0 → 100644
1 | casper.start('tests/site/mouse-events.html'); | ||
2 | |||
3 | casper.then(function() { | ||
4 | this.test.comment('CasperUtils.mouseEvent()'); | ||
5 | this.test.assert(this.mouseEvent('mousedown', '#test1'), 'CasperUtils.mouseEvent() can dispatch a mousedown event'); | ||
6 | this.test.assert(this.mouseEvent('mousedown', '#test2'), 'CasperUtils.mouseEvent() can dispatch a mousedown event handled by unobstrusive js'); | ||
7 | this.test.assert(this.mouseEvent('mouseup', '#test3'), 'CasperUtils.mouseEvent() can dispatch a mouseup event'); | ||
8 | this.test.assert(this.mouseEvent('mouseup', '#test4'), 'CasperUtils.mouseEvent() can dispatch a mouseup event handled by unobstrusive js'); | ||
9 | this.test.assert(this.mouseEvent('mouseover', '#test5'), 'CasperUtils.mouseEvent() can dispatch a mouseover event'); | ||
10 | this.test.assert(this.mouseEvent('mouseover', '#test6'), 'CasperUtils.mouseEvent() can dispatch a mouseover event handled by unobstrusive js'); | ||
11 | this.test.assert(this.mouseEvent('mouseout', '#test7'), 'CasperUtils.mouseEvent() can dispatch a mouseout event'); | ||
12 | this.test.assert(this.mouseEvent('mouseout', '#test8'), 'CasperUtils.mouseEvent() can dispatch a mouseout event handled by unobstrusive js'); | ||
13 | |||
14 | var results = this.getGlobal('results'); | ||
15 | this.test.assert(results.test1, 'CasperUtils.mouseEvent() triggered mousedown'); | ||
16 | this.test.assert(results.test2, 'CasperUtils.mouseEvent() triggered mousedown via unobstrusive js'); | ||
17 | this.test.assert(results.test3, 'CasperUtils.mouseEvent() triggered mouseup'); | ||
18 | this.test.assert(results.test4, 'CasperUtils.mouseEvent() triggered mouseup via unobstrusive js'); | ||
19 | this.test.assert(results.test5, 'CasperUtils.mouseEvent() triggered mouseover'); | ||
20 | this.test.assert(results.test6, 'CasperUtils.mouseEvent() triggered mouseover via unobstrusive js'); | ||
21 | this.test.assert(results.test7, 'CasperUtils.mouseEvent() triggered mouseout'); | ||
22 | this.test.assert(results.test8, 'CasperUtils.mouseEvent() triggered mouseout via unobstrusive js'); | ||
23 | }); | ||
24 | |||
25 | casper.run(function() { | ||
26 | this.test.done(); | ||
27 | }); |
... | @@ -19,6 +19,11 @@ function Plip() { return 'plop'; } | ... | @@ -19,6 +19,11 @@ function Plip() { return 'plop'; } |
19 | function foo_bar(boz) {} | 19 | function foo_bar(boz) {} |
20 | var gni = function ($bubu_bibi, __popo__) {}; | 20 | var gni = function ($bubu_bibi, __popo__) {}; |
21 | var gno = function ( arg1, /*plop*/ arg2 ) { }; | 21 | var gno = function ( arg1, /*plop*/ arg2 ) { }; |
22 | function issue129(term) { | ||
23 | // see issue #129 | ||
24 | return term; | ||
25 | // see issue #129 | ||
26 | } | ||
22 | t.assertEquals(injector.extract(Plop), { | 27 | t.assertEquals(injector.extract(Plop), { |
23 | name: 'Plop', | 28 | name: 'Plop', |
24 | args: ['foo', 'bar'], | 29 | args: ['foo', 'bar'], |
... | @@ -52,4 +57,8 @@ eval('processed = ' + injector.process({ a: 1, b: 2 })); | ... | @@ -52,4 +57,8 @@ eval('processed = ' + injector.process({ a: 1, b: 2 })); |
52 | t.assertType(processed, "function", 'FunctionArgsInjector.process() processed a function'); | 57 | t.assertType(processed, "function", 'FunctionArgsInjector.process() processed a function'); |
53 | t.assertEquals(processed(), 3, 'FunctionArgsInjector.process() processed the function correctly'); | 58 | t.assertEquals(processed(), 3, 'FunctionArgsInjector.process() processed the function correctly'); |
54 | 59 | ||
60 | // Issue #129 | ||
61 | var fnIssue129 = createInjector(issue129).process({term: 'fixed'}); | ||
62 | t.assertEquals(fnIssue129('fixed'), 'fixed', 'FunctionArgsInjector.process() has issue #129 fixed'); | ||
63 | |||
55 | t.done(); | 64 | t.done(); | ... | ... |
... | @@ -2,6 +2,8 @@ var fs = require('fs'); | ... | @@ -2,6 +2,8 @@ var fs = require('fs'); |
2 | 2 | ||
3 | var t = casper.test; | 3 | var t = casper.test; |
4 | 4 | ||
5 | casper.start(); | ||
6 | |||
5 | t.comment('Tester.testEquals()'); | 7 | t.comment('Tester.testEquals()'); |
6 | t.assert(t.testEquals(null, null), 'Tester.testEquals() null equality'); | 8 | t.assert(t.testEquals(null, null), 'Tester.testEquals() null equality'); |
7 | t.assertNot(t.testEquals(null, undefined), 'Tester.testEquals() null vs. undefined inequality'); | 9 | t.assertNot(t.testEquals(null, undefined), 'Tester.testEquals() null vs. undefined inequality'); |
... | @@ -26,8 +28,6 @@ t.assertNot(t.testEquals({1:{name:"bob",age:28}, 2:{name:"john",age:26}}, {1:{na | ... | @@ -26,8 +28,6 @@ t.assertNot(t.testEquals({1:{name:"bob",age:28}, 2:{name:"john",age:26}}, {1:{na |
26 | t.assert(t.testEquals(function(x){return x;}, function(x){return x;}), 'Tester.testEquals() function equality'); | 28 | t.assert(t.testEquals(function(x){return x;}, function(x){return x;}), 'Tester.testEquals() function equality'); |
27 | t.assertNot(t.testEquals(function(x){return x;}, function(y){return y+2;}), 'Tester.testEquals() function inequality'); | 29 | t.assertNot(t.testEquals(function(x){return x;}, function(y){return y+2;}), 'Tester.testEquals() function inequality'); |
28 | 30 | ||
29 | t.assertNotEquals(42, 43, 'Tester.assertNotEquals() works as expected'); | ||
30 | |||
31 | t.comment('Tester.sortFiles()'); | 31 | t.comment('Tester.sortFiles()'); |
32 | var testDirRoot = fs.pathJoin(phantom.casperPath, 'tests', 'testdir'); | 32 | var testDirRoot = fs.pathJoin(phantom.casperPath, 'tests', 'testdir'); |
33 | var files = t.findTestFiles(testDirRoot); | 33 | var files = t.findTestFiles(testDirRoot); |
... | @@ -44,11 +44,65 @@ var expected = [ | ... | @@ -44,11 +44,65 @@ var expected = [ |
44 | }); | 44 | }); |
45 | t.assertEquals(files, expected, 'findTestFiles() find test files and sort them'); | 45 | t.assertEquals(files, expected, 'findTestFiles() find test files and sort them'); |
46 | 46 | ||
47 | t.comment('Tester.assertTextExists()'); | 47 | casper.thenOpen('tests/site/index.html', function() { |
48 | casper.start('tests/site/index.html', function() { | 48 | t.comment('Tester.assertTextExists()'); |
49 | t.assertTextExists('form', 'Tester.assertTextExists() checks that page body contains text'); | 49 | t.assertTextExists('form', 'Tester.assertTextExists() checks that page body contains text'); |
50 | }); | 50 | }); |
51 | 51 | ||
52 | casper.then(function() { | ||
53 | t.comment('Tester.assert()'); | ||
54 | t.assert(true, 'Tester.assert() works as expected'); | ||
55 | |||
56 | t.comment('Tester.assertNot()'); | ||
57 | t.assertNot(false, 'Tester.assertNot() works as expected'); | ||
58 | |||
59 | t.comment('Tester.assertEquals()'); | ||
60 | t.assertEquals(true, true, 'Tester.assertEquals() works as expected'); | ||
61 | |||
62 | t.comment('Tester.assertNotEquals()'); | ||
63 | t.assertNotEquals(true, false, 'Tester.assertNotEquals() works as expected'); | ||
64 | |||
65 | t.comment('Tester.assertEval()'); | ||
66 | t.assertEval(function() { | ||
67 | return true; | ||
68 | }, 'Tester.assertEval() works as expected'); | ||
69 | |||
70 | t.comment('Tester.assertEvalEquals()'); | ||
71 | t.assertEvalEquals(function() { | ||
72 | return 42; | ||
73 | }, 42, 'Tester.assertEvalEquals() works as expected'); | ||
74 | |||
75 | t.comment('Tester.assertExists()'); | ||
76 | t.assertExists('body', 'Tester.assertExists() works as expected'); | ||
77 | |||
78 | t.comment('Tester.assertDoesntExist()'); | ||
79 | t.assertDoesntExist('foobar', 'Tester.assertDoesntExist() works as expected'); | ||
80 | |||
81 | t.comment('Tester.assertHttpStatus()'); | ||
82 | // using file:// protocol, HTTP status is always null | ||
83 | t.assertHttpStatus(null, 'Tester.assertHttpStatus() works as expected'); | ||
84 | |||
85 | t.comment('Tester.assertMatch()'); | ||
86 | t.assertMatch("the lazy dog", /lazy/, 'Tester.assertMatch() works as expected'); | ||
87 | |||
88 | t.comment('Tester.assertRaises()'); | ||
89 | t.assertRaises(function() { | ||
90 | throw new Error('plop'); | ||
91 | }, [], 'Tester.assertRaises() works as expected'); | ||
92 | |||
93 | t.comment('Tester.assertResourceExists()'); | ||
94 | t.assertResourceExists(/index\.html/, 'Tester.assertResourceExists() works as expected'); | ||
95 | |||
96 | t.comment('Tester.assertTitle()'); | ||
97 | t.assertTitle('CasperJS test index', 'Tester.assertTitle() works as expected'); | ||
98 | |||
99 | t.comment('Tester.assertType()'); | ||
100 | t.assertType("plop", "string", "Tester.assertType() works as expected"); | ||
101 | |||
102 | t.comment('Tester.assertUrlMatch()'); | ||
103 | t.assertUrlMatch(/index\.html$/, "Tester.assertUrlMatch() works as expected"); | ||
104 | }); | ||
105 | |||
52 | casper.run(function() { | 106 | casper.run(function() { |
53 | t.done(); | 107 | t.done(); |
54 | }); | 108 | }); | ... | ... |
-
Please register or sign in to post a comment