Commit 6c10a819 6c10a819df85627b1a93bb63dc75011204d0b58f by Nicolas Perriault

Merge remote-tracking branch 'nrabinowitz/mouse-events' into mouse-events

closes #89 - Support for more mouse events

Conflicts:
	modules/casper.js
	modules/clientutils.js
2 parents 13b6dd03 fe240a71
...@@ -257,22 +257,36 @@ Casper.prototype.clear = function clear() { ...@@ -257,22 +257,36 @@ Casper.prototype.clear = function clear() {
257 * @return Boolean 257 * @return Boolean
258 */ 258 */
259 Casper.prototype.click = function click(selector) { 259 Casper.prototype.click = function click(selector) {
260 this.log("Click on selector: " + selector, "debug"); 260 return this.mouseEvent('click', selector);
261 if (arguments.length > 1) { 261 };
262 this.emit("deprecated", "The click() method does not process the fallbackToHref argument since 0.6"); 262
263 } 263 /**
264 * Emulates an event on the element from the provided selector using the mouse
265 * pointer, if possible.
266 *
267 * In case of success, `true` is returned, `false` otherwise.
268 *
269 * @param String type Type of event to emulate
270 * @param String selector A DOM CSS3 compatible selector
271 * @return Boolean
272 */
273 Casper.prototype.mouseEvent = function mouseEvent(type, selector) {
274 this.log("Mouse event '" + type + "' on selector: " + selector, "debug");
264 if (!this.exists(selector)) { 275 if (!this.exists(selector)) {
265 throw new CasperError("Cannot click on unexistent selector: " + selector); 276 throw new CasperError("Cannot dispatch an event on nonexistent selector: " + selector);
266 } 277 }
267 var clicked = this.evaluate(function _evaluate(selector) { 278 var eventSuccess = this.evaluate(function(type, selector) {
268 return __utils__.click(selector); 279 return __utils__.mouseEvent(type, selector);
269 }, { selector: selector }); 280 }, {
270 if (!clicked) { 281 type: type,
282 selector: selector
283 });
284 if (!eventSuccess) {
271 // fallback onto native QtWebKit mouse events 285 // fallback onto native QtWebKit mouse events
272 try { 286 try {
273 this.mouse.click(selector); 287 this.mouse.processEvent(type, selector);
274 } catch (e) { 288 } catch (e) {
275 this.log(f("Error while trying to click on selector %s: %s", selector, e), "error"); 289 this.log(f("Error while trying to emulate event %s on selector %s: %s", type, selector, e), "error");
276 return false; 290 return false;
277 } 291 }
278 } 292 }
...@@ -679,20 +693,6 @@ Casper.prototype.log = function log(message, level, space) { ...@@ -679,20 +693,6 @@ Casper.prototype.log = function log(message, level, space) {
679 }; 693 };
680 694
681 /** 695 /**
682 * Emulates a click on an HTML element matching a given CSS3 selector,
683 * using the mouse pointer.
684 *
685 * @param String selector A DOM CSS3 compatible selector
686 * @return Casper
687 * @deprecated
688 * @since 0.6
689 */
690 Casper.prototype.mouseClick = function mouseClick(selector) {
691 this.emit("deprecated", "The mouseClick() method has been deprecated since 0.6; use click() instead");
692 return this.click(selector);
693 };
694
695 /**
696 * Performs an HTTP request. 696 * Performs an HTTP request.
697 * 697 *
698 * @param String location The url to open 698 * @param String location The url to open
......
...@@ -50,25 +50,36 @@ ...@@ -50,25 +50,36 @@
50 var SUPPORTED_SELECTOR_TYPES = ['css', 'xpath']; 50 var SUPPORTED_SELECTOR_TYPES = ['css', 'xpath'];
51 51
52 /** 52 /**
53 * Clicks on the DOM element behind the provided selector. 53 * Dispatches a mouse event to the DOM element behind the provided selector.
54 * 54 *
55 * @param String type Type of event to dispatch
55 * @param String selector A CSS3 selector to the element to click 56 * @param String selector A CSS3 selector to the element to click
56 * @return Boolean 57 * @return Boolean
57 */ 58 */
58 this.click = function click(selector) { 59 this.mouseEvent = function(type, selector) {
59 var elem = this.findOne(selector); 60 var elem = this.findOne(selector);
60 if (!elem) { 61 if (!elem) {
61 this.log("click(): Couldn't find any element matching '" + selector + "' selector", "error"); 62 this.log("mouseEvent(): Couldn't find any element matching '" + selector + "' selector", "error");
62 return false; 63 return false;
63 } 64 }
64 var evt = document.createEvent("MouseEvents"); 65 var evt = document.createEvent("MouseEvents");
65 evt.initMouseEvent("click", true, true, window, 1, 1, 1, 1, 1, false, false, false, false, 0, elem); 66 evt.initMouseEvent(type, 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 // dispatchEvent return value is false if at least one of the event
67 // handlers which handled this event called preventDefault 68 // handlers which handled this event called preventDefault
68 return elem.dispatchEvent(evt); 69 return elem.dispatchEvent(evt);
69 }; 70 };
70 71
71 /** 72 /**
73 * Clicks on the DOM element behind the provided selector.
74 *
75 * @param String selector A CSS3 selector to the element to click
76 * @return Boolean
77 */
78 this.click = function(selector) {
79 return this.mouseEvent('click', selector);
80 };
81
82 /**
72 * Decodes a base64 encoded string. Succeeds where window.atob() fails. 83 * Decodes a base64 encoded string. Succeeds where window.atob() fails.
73 * 84 *
74 * @param String str The base64 encoded contents 85 * @param String str The base64 encoded contents
......
...@@ -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 (supportedEvents.indexOf(type) > 0) {
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:
...@@ -79,6 +86,10 @@ var Mouse = function Mouse(casper) { ...@@ -79,6 +86,10 @@ var Mouse = function Mouse(casper) {
79 } 86 }
80 } 87 }
81 88
89 this.processEvent = function() {
90 processEvent(arguments[0], slice.call(arguments, 1));
91 };
92
82 this.click = function click() { 93 this.click = function click() {
83 processEvent('click', arguments); 94 processEvent('click', arguments);
84 }; 95 };
......
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>
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 });