Commit 9639c602 9639c6029ffd8666c32dbc9a722906b087e7ccd0 by Laurent Jouanneau

Merge branch 'master' into slimerjs-2

2 parents b6cde77e 12ec6142
...@@ -168,6 +168,7 @@ casper.on('page.resource.requested', function(requestData, request) { ...@@ -168,6 +168,7 @@ casper.on('page.resource.requested', function(requestData, request) {
168 - merged [#427](https://github.com/n1k0/casperjs/issues/427) - Added `keepFocus` option to `Casper#sendKeys()` 168 - merged [#427](https://github.com/n1k0/casperjs/issues/427) - Added `keepFocus` option to `Casper#sendKeys()`
169 - fixed [#441](https://github.com/n1k0/casperjs/issues/441) - added `--ssl-protocol` option support to the `casperjs` executable 169 - fixed [#441](https://github.com/n1k0/casperjs/issues/441) - added `--ssl-protocol` option support to the `casperjs` executable
170 - fixed [#452](https://github.com/n1k0/casperjs/pull/452) - allow uppercase http methods in `Casper#open()` 170 - fixed [#452](https://github.com/n1k0/casperjs/pull/452) - allow uppercase http methods in `Casper#open()`
171 - fixed [#521](https://github.com/n1k0/casperjs/issue/521) - `sendKeys` for inputs without text attribute should not be restricted
171 - Added [`Casper#fillSelectors()`](http://docs.casperjs.org/en/latest/modules/casper.html#fillselectors) and [`Casper#fillXPath()`](http://docs.casperjs.org/en/latest/modules/casper.html#fillxpath) 172 - Added [`Casper#fillSelectors()`](http://docs.casperjs.org/en/latest/modules/casper.html#fillselectors) and [`Casper#fillXPath()`](http://docs.casperjs.org/en/latest/modules/casper.html#fillxpath)
172 - Added [`Casper#getElementsAttribute()`](http://docs.casperjs.org/en/latest/modules/casper.html#getelementsattribute) and [`Casper#getElementsInfo()`](http://docs.casperjs.org/en/latest/modules/casper.html#getelementsinfo) 173 - Added [`Casper#getElementsAttribute()`](http://docs.casperjs.org/en/latest/modules/casper.html#getelementsattribute) and [`Casper#getElementsInfo()`](http://docs.casperjs.org/en/latest/modules/casper.html#getelementsinfo)
173 - Added [`Casper#waitForUrl()`](http://docs.casperjs.org/en/latest/modules/casper.html#waitforurl) 174 - Added [`Casper#waitForUrl()`](http://docs.casperjs.org/en/latest/modules/casper.html#waitforurl)
......
...@@ -58,6 +58,12 @@ Run the script: ...@@ -58,6 +58,12 @@ Run the script:
58 58
59 ![](http://cl.ly/image/271e2i403A0F/Capture%20d%E2%80%99%C3%A9cran%202013-01-20%20%C3%A0%2009.26.15.png) 59 ![](http://cl.ly/image/271e2i403A0F/Capture%20d%E2%80%99%C3%A9cran%202013-01-20%20%C3%A0%2009.26.15.png)
60 60
61 ##Support
62
63 If you're having problems with using the project, use the support forum at CodersClan.
64
65 <a href="http://codersclan.net/forum/index.php?repo_id=32"><img src="http://www.codersclan.net/graphics/getSupport_blue_big.png" width="160"></a>
66
61 ## Contributing 67 ## Contributing
62 68
63 ### Contributing code 69 ### Contributing code
......
...@@ -206,7 +206,7 @@ Asserts that current `HTTP status code <http://www.w3.org/Protocols/rfc2616/rfc2 ...@@ -206,7 +206,7 @@ Asserts that current `HTTP status code <http://www.w3.org/Protocols/rfc2616/rfc2
206 206
207 Asserts that a provided string matches a provided javascript ``RegExp`` pattern:: 207 Asserts that a provided string matches a provided javascript ``RegExp`` pattern::
208 208
209 casper.test.assertMatch('Chuck Norris', /^chuck/i, 'Chuck Norris' first name is Chuck'); 209 casper.test.assertMatch('Chuck Norris', /^chuck/i, 'Chuck Norris\' first name is Chuck');
210 210
211 .. seealso:: 211 .. seealso::
212 212
......
...@@ -448,8 +448,8 @@ Casper.prototype.clickLabel = function clickLabel(label, tag) { ...@@ -448,8 +448,8 @@ Casper.prototype.clickLabel = function clickLabel(label, tag) {
448 "use strict"; 448 "use strict";
449 this.checkStarted(); 449 this.checkStarted();
450 tag = tag || "*"; 450 tag = tag || "*";
451 var escapedLabel = label.toString().replace(/"/g, '\\"'); 451 var escapedLabel = utils.quoteXPathAttributeString(label);
452 var selector = selectXPath(f('//%s[text()="%s"]', tag, escapedLabel)); 452 var selector = selectXPath(f('//%s[text()=%s]', tag, escapedLabel));
453 return this.click(selector); 453 return this.click(selector);
454 }; 454 };
455 455
...@@ -1087,7 +1087,7 @@ Casper.prototype.getGlobal = function getGlobal(name) { ...@@ -1087,7 +1087,7 @@ Casper.prototype.getGlobal = function getGlobal(name) {
1087 try { 1087 try {
1088 result.value = JSON.stringify(window[name]); 1088 result.value = JSON.stringify(window[name]);
1089 } catch (e) { 1089 } catch (e) {
1090 var message = f("Unable to JSON encode window.%s: %s", name, e); 1090 var message = "Unable to JSON encode window." + name + ": " + e;
1091 __utils__.log(message, "error"); 1091 __utils__.log(message, "error");
1092 result.error = message; 1092 result.error = message;
1093 } 1093 }
...@@ -1559,7 +1559,7 @@ Casper.prototype.sendKeys = function(selector, keys, options) { ...@@ -1559,7 +1559,7 @@ Casper.prototype.sendKeys = function(selector, keys, options) {
1559 "hidden", "month", "number", "password", "range", "search", 1559 "hidden", "month", "number", "password", "range", "search",
1560 "tel", "text", "time", "url", "week"], 1560 "tel", "text", "time", "url", "week"],
1561 isTextInput = false; 1561 isTextInput = false;
1562 if (tag === 'textarea' || (tag === 'input' && supported.indexOf(type) !== -1)) { 1562 if (tag === 'textarea' || (tag === 'input' && (typeof type === 'undefined' || supported.indexOf(type) !== -1))) {
1563 // clicking on the input element brings it focus 1563 // clicking on the input element brings it focus
1564 isTextInput = true; 1564 isTextInput = true;
1565 this.click(selector); 1565 this.click(selector);
......
...@@ -673,6 +673,22 @@ function objectValues(obj) { ...@@ -673,6 +673,22 @@ function objectValues(obj) {
673 exports.objectValues = objectValues; 673 exports.objectValues = objectValues;
674 674
675 /** 675 /**
676 * Prepares a string for xpath expression with the condition [text()=].
677 *
678 * @param String string
679 * @return String
680 */
681 function quoteXPathAttributeString(string) {
682 "use strict";
683 if (/"/g.test(string)) {
684 return 'concat("' + string.toString().replace(/"/g, '", \'"\', "') + '")';
685 } else {
686 return '"' + string + '"';
687 }
688 }
689 exports.quoteXPathAttributeString = quoteXPathAttributeString;
690
691 /**
676 * Serializes a value using JSON. 692 * Serializes a value using JSON.
677 * 693 *
678 * @param Mixed value 694 * @param Mixed value
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
10 <a id="test3" href="page1.html" onclick="results.test3 = true; return false">test3</a> 10 <a id="test3" href="page1.html" onclick="results.test3 = true; return false">test3</a>
11 <a id="test4" href="http://www.google.com/">test4</a> 11 <a id="test4" href="http://www.google.com/">test4</a>
12 <a id="test5" href="#">test5</a> 12 <a id="test5" href="#">test5</a>
13 <a id="test6" href="#">Label with double "quotes"</a>
14 <a id="test7" href="#">Label with single 'quotes'</a>
13 <script> 15 <script>
14 (function(window) { 16 (function(window) {
15 window.results = { 17 window.results = {
...@@ -18,6 +20,8 @@ ...@@ -18,6 +20,8 @@
18 test3: false, 20 test3: false,
19 test4: false, 21 test4: false,
20 test5: [], 22 test5: [],
23 test6: false,
24 test7: false,
21 testdown: [], 25 testdown: [],
22 testup: [], 26 testup: [],
23 testmove: [], 27 testmove: [],
...@@ -47,6 +51,14 @@ ...@@ -47,6 +51,14 @@
47 test5elem.addEventListener('mouseup', function(event) { 51 test5elem.addEventListener('mouseup', function(event) {
48 results.test5.push('mouseup'); 52 results.test5.push('mouseup');
49 }); 53 });
54 document.querySelector('#test6').onclick = function(event) {
55 results.test6 = true;
56 event.preventDefault();
57 };
58 document.querySelector('#test7').onclick = function(event) {
59 results.test7 = true;
60 event.preventDefault();
61 };
50 })(window); 62 })(window);
51 </script> 63 </script>
52 </body> 64 </body>
......
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
23 <input type="checkbox" name="checklist[]" value="3"> 23 <input type="checkbox" name="checklist[]" value="3">
24 <input type="submit" name="submit" value="submit"> 24 <input type="submit" name="submit" value="submit">
25 </form> 25 </form>
26 <form id="no-type-test-form" action="#" enctype="multipart/form-data">
27 <input name="notype">
28 <form>
26 <script> 29 <script>
27 (function () { 30 (function () {
28 'use strict'; 31 'use strict';
......
...@@ -35,7 +35,7 @@ casper.test.begin('onclick variants tests', 8, function(test) { ...@@ -35,7 +35,7 @@ casper.test.begin('onclick variants tests', 8, function(test) {
35 }); 35 });
36 }); 36 });
37 37
38 casper.test.begin('clickLabel tests tests', 8, function(test) { 38 casper.test.begin('clickLabel tests tests', 12, function(test) {
39 casper.start('tests/site/click.html', function() { 39 casper.start('tests/site/click.html', function() {
40 test.assert(this.clickLabel('test1'), 40 test.assert(this.clickLabel('test1'),
41 'Casper.clickLabel() can click an `href="javascript:` link'); 41 'Casper.clickLabel() can click an `href="javascript:` link');
...@@ -45,6 +45,10 @@ casper.test.begin('clickLabel tests tests', 8, function(test) { ...@@ -45,6 +45,10 @@ casper.test.begin('clickLabel tests tests', 8, function(test) {
45 'Casper.clickLabel() can click an `onclick=".*; return false"` link'); 45 'Casper.clickLabel() can click an `onclick=".*; return false"` link');
46 test.assert(this.clickLabel('test4'), 46 test.assert(this.clickLabel('test4'),
47 'Casper.clickLabel() can click an unobstrusive js handled link'); 47 'Casper.clickLabel() can click an unobstrusive js handled link');
48 test.assert(this.clickLabel('Label with double "quotes"'),
49 'Casper.clickLabel() can click the link with double quotes in the label');
50 test.assert(this.clickLabel("Label with single 'quotes'"),
51 'Casper.clickLabel() can click the link with the single quotes in the label');
48 var results = this.getGlobal('results'); 52 var results = this.getGlobal('results');
49 if (phantom.casperEngine === 'slimerjs') { 53 if (phantom.casperEngine === 'slimerjs') {
50 // "javascript:" link in Gecko are executed asynchronously, so we don't have result at this time 54 // "javascript:" link in Gecko are executed asynchronously, so we don't have result at this time
...@@ -59,6 +63,10 @@ casper.test.begin('clickLabel tests tests', 8, function(test) { ...@@ -59,6 +63,10 @@ casper.test.begin('clickLabel tests tests', 8, function(test) {
59 'Casper.clickLabel() has clicked an `onclick=".*; return false"` link'); 63 'Casper.clickLabel() has clicked an `onclick=".*; return false"` link');
60 test.assert(results.test4, 64 test.assert(results.test4,
61 'Casper.clickLabel() has clicked an unobstrusive js handled link'); 65 'Casper.clickLabel() has clicked an unobstrusive js handled link');
66 test.assert(results.test6,
67 'Casper.clickLabel() has clicked the link with double quotes in the label');
68 test.assert(results.test7,
69 'Casper.clickLabel() has clicked the link with single quotes in the label');
62 }).run(function() { 70 }).run(function() {
63 test.done(); 71 test.done();
64 }); 72 });
......
...@@ -2,19 +2,25 @@ ...@@ -2,19 +2,25 @@
2 /*global CasperError, casper, console, phantom, require*/ 2 /*global CasperError, casper, console, phantom, require*/
3 var utils = require('utils'); 3 var utils = require('utils');
4 4
5 casper.test.begin('sendKeys() tests', 3, function(test) { 5 casper.test.begin('sendKeys() tests', 4, function(test) {
6 casper.start('tests/site/form.html', function() { 6 casper.start('tests/site/form.html', function() {
7 this.sendKeys('input[name="email"]', 'duke@nuk.em'); 7 this.sendKeys('input[name="email"]', 'duke@nuk.em');
8 this.sendKeys('input[name="language"]', 'fr', {keepFocus: true}); 8 this.sendKeys('input[name="language"]', 'fr', {keepFocus: true});
9 this.click('#autocomplete li:first-child'); 9 this.click('#autocomplete li:first-child');
10 this.sendKeys('textarea', "Damn, I’m looking good."); 10 this.sendKeys('textarea', "Damn, I’m looking good.");
11 var values = this.getFormValues('form'); 11 var values = this.getFormValues('form[action="result.html"]');
12 test.assertEquals(values.email, 'duke@nuk.em', 12 test.assertEquals(values.email, 'duke@nuk.em',
13 'Casper.sendKeys() sends keys to given input'); 13 'Casper.sendKeys() sends keys to given input');
14 test.assertEquals(values.language, 'french', 14 test.assertEquals(values.language, 'french',
15 'Casper.sendKeys() sends keys to given input and keeps focus afterweards'); 15 'Casper.sendKeys() sends keys to given input and keeps focus afterweards');
16 test.assertEquals(values.content, "Damn, I’m looking good.", 16 test.assertEquals(values.content, "Damn, I’m looking good.",
17 'Casper.sendKeys() sends keys to given textarea'); 17 'Casper.sendKeys() sends keys to given textarea');
18
19 this.sendKeys('input[name="notype"]', "I have no type.");
20 values = this.getFormValues('form#no-type-test-form');
21 test.assertEquals(values.notype, "I have no type.",
22 'Casper.sendKeys() sends keys to given input without type attribute');
23
18 }).run(function() { 24 }).run(function() {
19 test.done(); 25 test.done();
20 }); 26 });
......
...@@ -341,6 +341,19 @@ casper.test.begin('objectValues() tests', 2, function(test) { ...@@ -341,6 +341,19 @@ casper.test.begin('objectValues() tests', 2, function(test) {
341 test.done(); 341 test.done();
342 }); 342 });
343 343
344 casper.test.begin('quoteXPathAttributeString() tests', 2, function(test) {
345 casper.start('tests/site/click.html', function() {
346 var selector = utils.format('//a[text()=%s]',
347 utils.quoteXPathAttributeString('Label with double "quotes"'));
348 test.assertExists(x(selector), utils.format('Xpath selector "%s" is found on "tests/site/click.html" page', selector));
349 selector = utils.format('//a[text()=%s]',
350 utils.quoteXPathAttributeString("Label with single 'quotes'"));
351 test.assertExists(x(selector), utils.format('Xpath selector "%s" is found on "tests/site/click.html" page', selector));
352 }).run(function() {
353 test.done();
354 });
355 });
356
344 casper.test.begin('unique() tests', 4, function(test) { 357 casper.test.begin('unique() tests', 4, function(test) {
345 var testCases = [ 358 var testCases = [
346 { 359 {
......