Commit e3d59675 e3d59675d13f9bde63f2796d7acec72aa70921b7 by Nicolas Perriault

added Casper.mouseClick() method for native mouse click emulation using native events

1 parent 7a2f3420
...@@ -178,17 +178,7 @@ Casper.prototype = { ...@@ -178,17 +178,7 @@ Casper.prototype = {
178 */ 178 */
179 captureSelector: function(targetFile, selector) { 179 captureSelector: function(targetFile, selector) {
180 return this.capture(targetFile, this.evaluate(function(selector) { 180 return this.capture(targetFile, this.evaluate(function(selector) {
181 try { 181 return __utils__.getElementBounds();
182 var clipRect = document.querySelector(selector).getBoundingClientRect();
183 return {
184 top: clipRect.top,
185 left: clipRect.left,
186 width: clipRect.width,
187 height: clipRect.height
188 };
189 } catch (e) {
190 __utils__.log("Unable to fetch bounds for element " + selector, "warning");
191 }
192 }, { selector: selector })); 182 }, { selector: selector }));
193 }, 183 },
194 184
...@@ -597,6 +587,25 @@ Casper.prototype = { ...@@ -597,6 +587,25 @@ Casper.prototype = {
597 }, 587 },
598 588
599 /** 589 /**
590 * Emulates a click on an HTML element matching a given CSS3 selector,
591 * using the mouse pointer.
592 *
593 * @param String selector A DOM CSS3 compatible selector
594 * @return Casper
595 */
596 mouseClick: function(selector) {
597 var bounds = this.evaluate(function(selector) {
598 return __utils__.getElementBounds(selector);
599 }, { selector: selector });
600 if (utils.isClipRect(bounds)) {
601 var x = bounds.left + Math.floor(bounds.width / 2);
602 var y = bounds.top + Math.floor(bounds.height / 2);
603 this.page.sendEvent('click', x, y);
604 }
605 return this;
606 },
607
608 /**
600 * Opens a page. Takes only one argument, the url to open (using the 609 * Opens a page. Takes only one argument, the url to open (using the
601 * callback argument would defeat the whole purpose of Casper 610 * callback argument would defeat the whole purpose of Casper
602 * actually). 611 * actually).
......
...@@ -351,6 +351,27 @@ ...@@ -351,6 +351,27 @@
351 }; 351 };
352 352
353 /** 353 /**
354 * Retrieves bounding rect coordinates of the HTML element matching the
355 * provided CSS3 selector
356 *
357 * @param String selector
358 * @return Object or null
359 */
360 this.getElementBounds = function(selector) {
361 try {
362 var clipRect = document.querySelector(selector).getBoundingClientRect();
363 return {
364 top: clipRect.top,
365 left: clipRect.left,
366 width: clipRect.width,
367 height: clipRect.height
368 };
369 } catch (e) {
370 this.log("Unable to fetch bounds for element " + selector, "warning");
371 }
372 };
373
374 /**
354 * Logs a message. Will format the message a way CasperJS will be able 375 * Logs a message. Will format the message a way CasperJS will be able
355 * to log phantomjs side. 376 * to log phantomjs side.
356 * 377 *
......
...@@ -85,6 +85,11 @@ function fillBlanks(text, pad) { ...@@ -85,6 +85,11 @@ function fillBlanks(text, pad) {
85 } 85 }
86 exports.fillBlanks = fillBlanks; 86 exports.fillBlanks = fillBlanks;
87 87
88 function isArray(value) {
89 return isType(value, "array");
90 }
91 exports.isArray = isArray;
92
88 /** 93 /**
89 * Checks if passed argument is an instance of Capser object. 94 * Checks if passed argument is an instance of Capser object.
90 * 95 *
...@@ -96,6 +101,22 @@ function isCasperObject(value) { ...@@ -96,6 +101,22 @@ function isCasperObject(value) {
96 } 101 }
97 exports.isCasperObject = isCasperObject; 102 exports.isCasperObject = isCasperObject;
98 103
104 function isClipRect(value) {
105 return isType(value, "cliprect") || (
106 isType(value, "object") &&
107 isType(value.top, "number") &&
108 isType(value.left, "number") &&
109 isType(value.width, "number") &&
110 isType(value.height, "number")
111 );
112 }
113 exports.isClipRect = isClipRect;
114
115 function isFunction(value) {
116 return isType(value, "function");
117 }
118 exports.isFunction = isFunction;
119
99 /** 120 /**
100 * Checks if a file is apparently javascript compatible (.js or .coffee). 121 * Checks if a file is apparently javascript compatible (.js or .coffee).
101 * 122 *
...@@ -108,6 +129,11 @@ function isJsFile(file) { ...@@ -108,6 +129,11 @@ function isJsFile(file) {
108 } 129 }
109 exports.isJsFile = isJsFile; 130 exports.isJsFile = isJsFile;
110 131
132 function isObject(value) {
133 return isType(value, "object");
134 }
135 exports.isObject = isObject;
136
111 /** 137 /**
112 * Shorthands for checking if a value is of the given type. Can check for 138 * Shorthands for checking if a value is of the given type. Can check for
113 * arrays. 139 * arrays.
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
2 var utils = require('utils'); 2 var utils = require('utils');
3 3
4 t.comment('fileExt()'); 4 t.comment('fileExt()');
5
6 (function() { 5 (function() {
7 var testCases = { 6 var testCases = {
8 'foo.ext': 'ext', 7 'foo.ext': 'ext',
...@@ -19,7 +18,6 @@ ...@@ -19,7 +18,6 @@
19 })(); 18 })();
20 19
21 t.comment('fillBlanks()'); 20 t.comment('fillBlanks()');
22
23 (function() { 21 (function() {
24 testCases = { 22 testCases = {
25 'foo': 'foo ', 23 'foo': 'foo ',
...@@ -32,8 +30,22 @@ ...@@ -32,8 +30,22 @@
32 } 30 }
33 })(); 31 })();
34 32
35 t.comment('isJsFile()'); 33 t.comment('isClipRect()');
34 (function() {
35 testCases = [
36 [{}, false],
37 [{top: 2}, false],
38 [{top: 2, left: 2, width: 2, height: 2}, true],
39 [{top: 2, left: 2, height: 2, width: 2}, true],
40 [{top: 2, left: 2, width: 2, height: new Date()}, false]
41 ];
36 42
43 testCases.forEach(function(testCase) {
44 t.assertEquals(utils.isClipRect(testCase[0]), testCase[1], 'isClipRect() checks for a ClipRect');
45 });
46 })();
47
48 t.comment('isJsFile()');
37 (function() { 49 (function() {
38 testCases = { 50 testCases = {
39 '': false, 51 '': false,
...@@ -49,7 +61,6 @@ ...@@ -49,7 +61,6 @@
49 })(); 61 })();
50 62
51 t.comment('mergeObjects()'); 63 t.comment('mergeObjects()');
52
53 (function() { 64 (function() {
54 testCases = [ 65 testCases = [
55 { 66 {
......