Merge pull request #948 from botandrose/findLabels
Introduce fillLabels method to fill out a form based on label text.
Showing
4 changed files
with
88 additions
and
14 deletions
... | @@ -821,7 +821,7 @@ Casper.prototype.fillForm = function fillForm(selector, vals, options) { | ... | @@ -821,7 +821,7 @@ Casper.prototype.fillForm = function fillForm(selector, vals, options) { |
821 | var fileFieldSelector; | 821 | var fileFieldSelector; |
822 | if (file.type === "names") { | 822 | if (file.type === "names") { |
823 | fileFieldSelector = [selector, 'input[name="' + file.selector + '"]'].join(' '); | 823 | fileFieldSelector = [selector, 'input[name="' + file.selector + '"]'].join(' '); |
824 | } else if (file.type === "css") { | 824 | } else if (file.type === "css" || file.type === "labels") { |
825 | fileFieldSelector = [selector, file.selector].join(' '); | 825 | fileFieldSelector = [selector, file.selector].join(' '); |
826 | } | 826 | } |
827 | this.page.uploadFile(fileFieldSelector, file.path); | 827 | this.page.uploadFile(fileFieldSelector, file.path); |
... | @@ -867,6 +867,21 @@ Casper.prototype.fillNames = function fillNames(formSelector, vals, submit) { | ... | @@ -867,6 +867,21 @@ Casper.prototype.fillNames = function fillNames(formSelector, vals, submit) { |
867 | }; | 867 | }; |
868 | 868 | ||
869 | /** | 869 | /** |
870 | * Fills a form with provided field values using associated label text. | ||
871 | * | ||
872 | * @param String formSelector A DOM CSS3/XPath selector to the target form to fill | ||
873 | * @param Object vals Field values | ||
874 | * @param Boolean submit Submit the form? | ||
875 | */ | ||
876 | Casper.prototype.fillLabels = function fillLabels(formSelector, vals, submit) { | ||
877 | "use strict"; | ||
878 | return this.fillForm(formSelector, vals, { | ||
879 | submit: submit, | ||
880 | selectorType: 'labels' | ||
881 | }); | ||
882 | }; | ||
883 | |||
884 | /** | ||
870 | * Fills a form with provided field values using CSS3 selectors. | 885 | * Fills a form with provided field values using CSS3 selectors. |
871 | * | 886 | * |
872 | * @param String formSelector A DOM CSS3/XPath selector to the target form to fill | 887 | * @param String formSelector A DOM CSS3/XPath selector to the target form to fill | ... | ... |
... | @@ -273,6 +273,12 @@ | ... | @@ -273,6 +273,12 @@ |
273 | css: function(inputSelector, formSelector) { | 273 | css: function(inputSelector, formSelector) { |
274 | return this.findAll(inputSelector, form); | 274 | return this.findAll(inputSelector, form); |
275 | }, | 275 | }, |
276 | labels: function(labelText, formSelector, value) { | ||
277 | var label = this.findOne({type: "xpath", path: '//label[text()="' + labelText + '"]'}, form); | ||
278 | if(label && label.htmlFor) { | ||
279 | return this.findAll('#' + label.htmlFor, form); | ||
280 | } | ||
281 | }, | ||
276 | names: function(elementName, formSelector) { | 282 | names: function(elementName, formSelector) { |
277 | return this.findAll('[name="' + elementName + '"]', form); | 283 | return this.findAll('[name="' + elementName + '"]', form); |
278 | }, | 284 | }, |
... | @@ -295,9 +301,15 @@ | ... | @@ -295,9 +301,15 @@ |
295 | out.fields[fieldSelector] = this.setField(field, value); | 301 | out.fields[fieldSelector] = this.setField(field, value); |
296 | } catch (err) { | 302 | } catch (err) { |
297 | if (err.name === "FileUploadError") { | 303 | if (err.name === "FileUploadError") { |
304 | var selector; | ||
305 | if(findType === "labels") { | ||
306 | selector = '#' + field[0].id; | ||
307 | } else { | ||
308 | selector = fieldSelector; | ||
309 | } | ||
298 | out.files.push({ | 310 | out.files.push({ |
299 | type: findType, | 311 | type: findType, |
300 | selector: fieldSelector, | 312 | selector: selector, |
301 | path: err.path | 313 | path: err.path |
302 | }); | 314 | }); |
303 | } else if (err.name === "FieldNotFound") { | 315 | } else if (err.name === "FieldNotFound") { |
... | @@ -851,10 +863,14 @@ | ... | @@ -851,10 +863,14 @@ |
851 | }; | 863 | }; |
852 | case "radio": | 864 | case "radio": |
853 | if (fields) { | 865 | if (fields) { |
866 | if (fields.length > 1) { | ||
854 | Array.prototype.forEach.call(fields, function _forEach(e) { | 867 | Array.prototype.forEach.call(fields, function _forEach(e) { |
855 | e.checked = (e.value === value); | 868 | e.checked = (e.value === value); |
856 | }); | 869 | }); |
857 | } else { | 870 | } else { |
871 | field.checked = value ? true : false; | ||
872 | } | ||
873 | } else { | ||
858 | out = 'Provided radio elements are empty'; | 874 | out = 'Provided radio elements are empty'; |
859 | } | 875 | } |
860 | break; | 876 | break; | ... | ... |
... | @@ -6,27 +6,40 @@ | ... | @@ -6,27 +6,40 @@ |
6 | </head> | 6 | </head> |
7 | <body> | 7 | <body> |
8 | <form action="result.html" enctype="multipart/form-data"> | 8 | <form action="result.html" enctype="multipart/form-data"> |
9 | <label for="email">Email</label> | ||
9 | <input type="email" name="email" placeholder="email" id="email"> | 10 | <input type="email" name="email" placeholder="email" id="email"> |
10 | <input type="password" name="password" placeholder="password"> | 11 | <label for="password">Password</label> |
12 | <input type="password" name="password" placeholder="password" id="password"> | ||
11 | <input type="text" name="language" placeholder="language"> | 13 | <input type="text" name="language" placeholder="language"> |
12 | <input type="whatever" name="strange"> | 14 | <label for="strange">Strange</label> |
13 | <textarea name="content"></textarea> | 15 | <input type="whatever" name="strange" id="strange"> |
14 | <select name="topic"> | 16 | <label for="content">Content</label> |
17 | <textarea name="content" id="content"></textarea> | ||
18 | <label for="topic">Topic</label> | ||
19 | <select name="topic" id="topic"> | ||
15 | <option>foo</option> | 20 | <option>foo</option> |
16 | <option value="bar">baz</option> | 21 | <option value="bar">baz</option> |
17 | </select> | 22 | </select> |
18 | <select multiple name="multitopic"> | 23 | <label for="multitopic">Multitopic</label> |
24 | <select multiple name="multitopic" id="multitopic"> | ||
19 | <option>foo</option> | 25 | <option>foo</option> |
20 | <option value="bar">baz</option> | 26 | <option value="bar">baz</option> |
21 | <option value="car">caz</option> | 27 | <option value="car">caz</option> |
22 | </select> | 28 | </select> |
23 | <input type="checkbox" name="check"> | 29 | <label for="check">Check</label> |
24 | <input type="radio" name="choice" value="yes"> | 30 | <input type="checkbox" name="check" id="check"> |
25 | <input type="radio" name="choice" value="no"> | 31 | <label for="choice_yes">Yes</label> |
26 | <input type="file" name="file"> | 32 | <input type="radio" name="choice" value="yes" id="choice_yes"> |
27 | <input type="checkbox" name="checklist[]" value="1"> | 33 | <label for="choice_no">No</label> |
28 | <input type="checkbox" name="checklist[]" value="2"> | 34 | <input type="radio" name="choice" value="no" id="choice_no"> |
29 | <input type="checkbox" name="checklist[]" value="3"> | 35 | <label for="file">File</label> |
36 | <input type="file" name="file" id="file"> | ||
37 | <label for="checklist_1">1</label> | ||
38 | <input type="checkbox" name="checklist[]" value="1" id="checklist_1"> | ||
39 | <label for="checklist_2">2</label> | ||
40 | <input type="checkbox" name="checklist[]" value="2" id="checklist_2"> | ||
41 | <label for="checklist_3">3</label> | ||
42 | <input type="checkbox" name="checklist[]" value="3" id="checklist_3"> | ||
30 | <input type="submit" name="submit" value="submit"> | 43 | <input type="submit" name="submit" value="submit"> |
31 | </form> | 44 | </form> |
32 | <form id="no-type-test-form" action="#" enctype="multipart/form-data"> | 45 | <form id="no-type-test-form" action="#" enctype="multipart/form-data"> | ... | ... |
... | @@ -67,6 +67,36 @@ casper.test.begin('fill() & fillNames() tests', 17, function(test) { | ... | @@ -67,6 +67,36 @@ casper.test.begin('fill() & fillNames() tests', 17, function(test) { |
67 | }); | 67 | }); |
68 | }); | 68 | }); |
69 | 69 | ||
70 | casper.test.begin('fillLabels() tests', 17, function(test) { | ||
71 | var fpath = fs.pathJoin(phantom.casperPath, 'README.md'); | ||
72 | |||
73 | casper.start('tests/site/form.html', function() { | ||
74 | this.fillLabels('form[action="result.html"]', { | ||
75 | Email: 'chuck@norris.com', | ||
76 | Password: 'chuck', | ||
77 | Content: 'Am watching thou', | ||
78 | Check: true, | ||
79 | No: true, | ||
80 | Topic: 'bar', | ||
81 | Multitopic: ['bar', 'car'], | ||
82 | File: fpath, | ||
83 | "1": true, | ||
84 | "3": true, | ||
85 | Strange: "very" | ||
86 | }); | ||
87 | testFormValues(test); | ||
88 | test.assertEvalEquals(function() { | ||
89 | return __utils__.findOne('input[name="file"]').files.length === 1; | ||
90 | }, true, 'can select a file to upload'); | ||
91 | }); | ||
92 | casper.thenClick('input[type="submit"]', function() { | ||
93 | testUrl(test); | ||
94 | }); | ||
95 | casper.run(function() { | ||
96 | test.done(); | ||
97 | }); | ||
98 | }); | ||
99 | |||
70 | casper.test.begin('fillSelectors() tests', 17, function(test) { | 100 | casper.test.begin('fillSelectors() tests', 17, function(test) { |
71 | var fpath = fs.pathJoin(phantom.casperPath, 'README.md'); | 101 | var fpath = fs.pathJoin(phantom.casperPath, 'README.md'); |
72 | 102 | ... | ... |
-
Please register or sign in to post a comment