Merge remote-tracking branch 'nrabinowitz/mouse-events' into mouse-events
closes #89 - Support for more mouse events Conflicts: modules/casper.js modules/clientutils.js
Showing
5 changed files
with
128 additions
and
32 deletions
... | @@ -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 selector A CSS3 selector to the element to click | 55 | * @param String type Type of event to dispatch |
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 | }; | ... | ... |
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> |
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 | }); |
-
Please register or sign in to post a comment