decoupled form filling strategies from casper object
Showing
5 changed files
with
215 additions
and
139 deletions
... | @@ -114,6 +114,7 @@ Last, all the casper test suites have been upgraded to use the new testing featu | ... | @@ -114,6 +114,7 @@ Last, all the casper test suites have been upgraded to use the new testing featu |
114 | - Added [`Casper#eachThen()`](http://docs.casperjs.org/en/latest/modules/casper.html#eachThen) | 114 | - Added [`Casper#eachThen()`](http://docs.casperjs.org/en/latest/modules/casper.html#eachThen) |
115 | - merged [#427](https://github.com/n1k0/casperjs/issues/427) - Added `keepFocus` option to `Casper#sendKeys()` | 115 | - merged [#427](https://github.com/n1k0/casperjs/issues/427) - Added `keepFocus` option to `Casper#sendKeys()` |
116 | - fixed [#441](https://github.com/n1k0/casperjs/issues/441) - added `--ssl-protocol` option support to the `casperjs` executable | 116 | - fixed [#441](https://github.com/n1k0/casperjs/issues/441) - added `--ssl-protocol` option support to the `casperjs` executable |
117 | - 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) | ||
117 | - `cli`: Now dropping an arg or an option will be reflected in their *raw* equivalent | 118 | - `cli`: Now dropping an arg or an option will be reflected in their *raw* equivalent |
118 | - `cli.get()` now supports fallback values | 119 | - `cli.get()` now supports fallback values |
119 | 120 | ... | ... |
... | @@ -839,7 +839,10 @@ Logs a message with an optional level in an optional space. Available levels are | ... | @@ -839,7 +839,10 @@ Logs a message with an optional level in an optional space. Available levels are |
839 | 839 | ||
840 | **Signature:** ``fill(String selector, Object values[, Boolean submit])`` | 840 | **Signature:** ``fill(String selector, Object values[, Boolean submit])`` |
841 | 841 | ||
842 | Fills the fields of a form with given values and optionally submits it. | 842 | Fills the fields of a form with given values and optionally submits it. Fields |
843 | are referenced by their ``name`` attribute. | ||
844 | |||
845 | .. versionchanged:: 1.1 To use :doc:`CSS3 or XPath selectors <../selectors>` instead, check the `fillSelectors()`_ and `fillXPath()`_ methods. | ||
843 | 846 | ||
844 | Example with this sample html form: | 847 | Example with this sample html form: |
845 | 848 | ||
... | @@ -883,9 +886,56 @@ A script to fill and submit this form:: | ... | @@ -883,9 +886,56 @@ A script to fill and submit this form:: |
883 | 886 | ||
884 | .. warning:: | 887 | .. warning:: |
885 | 888 | ||
886 | 1. The ``fill()`` method currently can't fill **file fields using XPath selectors**; PhantomJS natively only allows the use of CSS3 selectors in its uploadFile method, hence this limitation. | 889 | 1. The ``fill()`` method currently can't fill **file fields using XPath selectors**; PhantomJS natively only allows the use of CSS3 selectors in its ``uploadFile()`` method, hence this limitation. |
887 | 2. Please Don't use CasperJS nor PhantomJS to send spam, or I'll be calling the Chuck. More seriously, please just don't. | 890 | 2. Please Don't use CasperJS nor PhantomJS to send spam, or I'll be calling the Chuck. More seriously, please just don't. |
888 | 891 | ||
892 | ``fillSelectors()`` | ||
893 | ------------------------------------------------------------------------------- | ||
894 | |||
895 | **Signature:** ``fillSelectors(String selector, Object values[, Boolean submit])`` | ||
896 | |||
897 | .. versionadded:: 1.1 | ||
898 | |||
899 | Fills form fields with given values and optionally submits it. Fields | ||
900 | are referenced by ``CSS3`` selectors:: | ||
901 | |||
902 | casper.start('http://some.tld/contact.form', function() { | ||
903 | this.fill('form#contact-form', { | ||
904 | 'input[name="subject"]': 'I am watching you', | ||
905 | 'input[name="content"]': 'So be careful.', | ||
906 | 'input[name="civility"]': 'Mr', | ||
907 | 'input[name="name"]': 'Chuck Norris', | ||
908 | 'input[name="email"]': 'chuck@norris.com', | ||
909 | 'input[name="cc"]': true, | ||
910 | 'input[name="attachment"]': '/Users/chuck/roundhousekick.doc' | ||
911 | }, true); | ||
912 | }); | ||
913 | |||
914 | |||
915 | ``fillXPath()`` | ||
916 | ------------------------------------------------------------------------------- | ||
917 | |||
918 | **Signature:** ``fillXPath(String selector, Object values[, Boolean submit])`` | ||
919 | |||
920 | .. versionadded:: 1.1 | ||
921 | |||
922 | Fills form fields with given values and optionally submits it. While the ``form`` element is always referenced by a CSS3 selector, fields are referenced by ``XPath`` selectors:: | ||
923 | |||
924 | casper.start('http://some.tld/contact.form', function() { | ||
925 | this.fill('form#contact-form', { | ||
926 | '//input[@name="subject"]': 'I am watching you', | ||
927 | '//input[@name="content"]': 'So be careful.', | ||
928 | '//input[@name="civility"]': 'Mr', | ||
929 | '//input[@name="name"]': 'Chuck Norris', | ||
930 | '//input[@name="email"]': 'chuck@norris.com', | ||
931 | '//input[@name="cc"]': true, | ||
932 | }, true); | ||
933 | }); | ||
934 | |||
935 | .. warning:: | ||
936 | |||
937 | The ``fillXPath()`` method currently can't fill **file fields using XPath selectors**; PhantomJS natively only allows the use of CSS3 selectors in its ``uploadFile()`` method, hence this limitation. | ||
938 | |||
889 | .. index:: URL | 939 | .. index:: URL |
890 | 940 | ||
891 | ``getCurrentUrl()`` | 941 | ``getCurrentUrl()`` |
... | @@ -1905,6 +1955,7 @@ is changed to a different value before processing the next step. Uses `waitFor() | ... | @@ -1905,6 +1955,7 @@ is changed to a different value before processing the next step. Uses `waitFor() |
1905 | ------------------------------------------------------------------------------- | 1955 | ------------------------------------------------------------------------------- |
1906 | 1956 | ||
1907 | **Signature:** ``waitForText(String text[, Function then, Function onTimeout, Number timeout])`` | 1957 | **Signature:** ``waitForText(String text[, Function then, Function onTimeout, Number timeout])`` |
1958 | |||
1908 | .. versionadded:: 1.0 | 1959 | .. versionadded:: 1.0 |
1909 | 1960 | ||
1910 | Waits until the passed text is present in the page contents before processing the immediate next step. Uses `waitFor()`_:: | 1961 | Waits until the passed text is present in the page contents before processing the immediate next step. Uses `waitFor()`_:: | ... | ... |
... | @@ -752,41 +752,51 @@ Casper.prototype.fetchText = function fetchText(selector) { | ... | @@ -752,41 +752,51 @@ Casper.prototype.fetchText = function fetchText(selector) { |
752 | */ | 752 | */ |
753 | Casper.prototype.fillForm = function fillForm(selector, vals, options) { | 753 | Casper.prototype.fillForm = function fillForm(selector, vals, options) { |
754 | "use strict"; | 754 | "use strict"; |
755 | var submit, selectorFunction; | ||
756 | this.checkStarted(); | 755 | this.checkStarted(); |
757 | 756 | ||
758 | selectorFunction = options && options.selectorFunction; | 757 | var selectorType = options && options.selectorType || "names", |
759 | submit = options.submit === true ? options.submit : false; | 758 | submit = !!(options && options.submit); |
760 | 759 | ||
761 | this.emit('fill', selector, vals, options); | 760 | this.emit('fill', selector, vals, options); |
762 | 761 | ||
763 | var fillResults = this.evaluate(function _evaluate(selector, vals, selectorFunction) { | 762 | var fillResults = this.evaluate(function _evaluate(selector, vals, selectorType) { |
764 | return __utils__.fill(selector, vals, selectorFunction); | 763 | try { |
765 | }, selector, vals, selectorFunction); | 764 | return __utils__.fill(selector, vals, selectorType); |
765 | } catch (exception) { | ||
766 | return {exception: exception.toString()}; | ||
767 | } | ||
768 | }, selector, vals, selectorType); | ||
769 | |||
766 | if (!fillResults) { | 770 | if (!fillResults) { |
767 | throw new CasperError("Unable to fill form"); | 771 | throw new CasperError("Unable to fill form"); |
772 | } else if (fillResults && fillResults.exception) { | ||
773 | throw new CasperError("Unable to fill form: " + fillResults.exception); | ||
768 | } else if (fillResults.errors.length > 0) { | 774 | } else if (fillResults.errors.length > 0) { |
769 | throw new CasperError(f('Errors encountered while filling form: %s', | 775 | throw new CasperError(f('Errors encountered while filling form: %s', |
770 | fillResults.errors.join('; '))); | 776 | fillResults.errors.join('; '))); |
771 | } | 777 | } |
778 | |||
772 | // File uploads | 779 | // File uploads |
773 | if (fillResults.files && fillResults.files.length > 0) { | 780 | if (fillResults.files && fillResults.files.length > 0) { |
774 | if (utils.isObject(selector) && selector.type === 'xpath') { | 781 | if (utils.isObject(selector) && selector.type === 'xpath') { |
775 | this.warn('Filling file upload fields is currently not supported using ' + | 782 | this.warn('Filling file upload fields is currently not supported using ' + |
776 | 'XPath selectors; Please use a CSS selector instead.'); | 783 | 'XPath selectors; Please use a CSS selector instead.'); |
777 | } else { | 784 | } else { |
778 | (function _each(self) { | 785 | fillResults.files.forEach(function _forEach(file) { |
779 | fillResults.files.forEach(function _forEach(file) { | 786 | if (!file || !file.path) { |
780 | if (!file || !file.path) { | 787 | return; |
781 | return; | 788 | } |
782 | } | 789 | if (!fs.exists(file.path)) { |
783 | if (!fs.exists(file.path)) { | 790 | throw new CasperError('Cannot upload nonexistent file: ' + file.path); |
784 | throw new CasperError('Cannot upload nonexistent file: ' + file.path); | 791 | } |
785 | } | 792 | var fileFieldSelector; |
786 | var fileFieldSelector = selectorFunction.call(this, file.name, selector).fullSelector; | 793 | if (file.type === "names") { |
787 | self.page.uploadFile(fileFieldSelector, file.path); | 794 | fileFieldSelector = [selector, 'input[name="' + file.selector + '"]'].join(' '); |
788 | }); | 795 | } else if (file.type === "css") { |
789 | })(this); | 796 | fileFieldSelector = [selector, file.selector].join(' '); |
797 | } | ||
798 | this.page.uploadFile(fileFieldSelector, file.path); | ||
799 | }.bind(this)); | ||
790 | } | 800 | } |
791 | } | 801 | } |
792 | // Form submission? | 802 | // Form submission? |
... | @@ -817,47 +827,52 @@ Casper.prototype.fillForm = function fillForm(selector, vals, options) { | ... | @@ -817,47 +827,52 @@ Casper.prototype.fillForm = function fillForm(selector, vals, options) { |
817 | * | 827 | * |
818 | * @param String formSelector A DOM CSS3/XPath selector to the target form to fill | 828 | * @param String formSelector A DOM CSS3/XPath selector to the target form to fill |
819 | * @param Object vals Field values | 829 | * @param Object vals Field values |
820 | * @param Boolean submit Submit the form? | 830 | * @param Boolean submit Submit the form? |
821 | */ | 831 | */ |
822 | Casper.prototype.fillNames = function fillNames(formSelector, vals, submit) { | 832 | Casper.prototype.fillNames = function fillNames(formSelector, vals, submit) { |
823 | "use strict"; | 833 | "use strict"; |
824 | return this.fillForm(formSelector, vals, { | 834 | return this.fillForm(formSelector, vals, { |
825 | submit: submit, | 835 | submit: submit, |
826 | selectorFunction: function _nameSelector(elementName, formSelector) { | 836 | selectorType: 'names' |
827 | return { | ||
828 | fullSelector: [formSelector, '[name="' + elementName + '"]'].join(' '), | ||
829 | elts: (this.findAll ? this.findAll('[name="' + elementName + '"]', formSelector) : null) | ||
830 | }; | ||
831 | } | ||
832 | }); | 837 | }); |
833 | }; | 838 | }; |
834 | 839 | ||
835 | /** | 840 | /** |
836 | * Fills a form with provided field values using the Name attribute. | 841 | * Fills a form with provided field values using CSS3 selectors. |
842 | * | ||
843 | * @param String formSelector A DOM CSS3/XPath selector to the target form to fill | ||
844 | * @param Object vals Field values | ||
845 | * @param Boolean submit Submit the form? | ||
846 | */ | ||
847 | Casper.prototype.fillSelectors = function fillSelectors(formSelector, vals, submit) { | ||
848 | "use strict"; | ||
849 | return this.fillForm(formSelector, vals, { | ||
850 | submit: submit, | ||
851 | selectorType: 'css' | ||
852 | }); | ||
853 | }; | ||
854 | |||
855 | /** | ||
856 | * Fills a form with provided field values using the Name attribute by default. | ||
837 | * | 857 | * |
838 | * @param String formSelector A DOM CSS3/XPath selector to the target form to fill | 858 | * @param String formSelector A DOM CSS3/XPath selector to the target form to fill |
839 | * @param Object vals Field values | 859 | * @param Object vals Field values |
840 | * @param Boolean submit Submit the form? | 860 | * @param Boolean submit Submit the form? |
841 | */ | 861 | */ |
842 | Casper.prototype.fill = Casper.prototype.fillNames | 862 | Casper.prototype.fill = Casper.prototype.fillNames; |
843 | 863 | ||
844 | /** | 864 | /** |
845 | * Fills a form with provided field values using CSS3 selectors. | 865 | * Fills a form with provided field values using XPath selectors. |
846 | * | 866 | * |
847 | * @param String formSelector A DOM CSS3/XPath selector to the target form to fill | 867 | * @param String formSelector A DOM CSS3/XPath selector to the target form to fill |
848 | * @param Object vals Field values | 868 | * @param Object vals Field values |
849 | * @param Boolean submit Submit the form? | 869 | * @param Boolean submit Submit the form? |
850 | */ | 870 | */ |
851 | Casper.prototype.fillSelectors = function fillSelectors(formSelector, vals, submit) { | 871 | Casper.prototype.fillXPath = function fillXPath(formSelector, vals, submit) { |
852 | "use strict"; | 872 | "use strict"; |
853 | return this.fillForm(formSelector, vals, { | 873 | return this.fillForm(formSelector, vals, { |
854 | submit: submit, | 874 | submit: submit, |
855 | selectorFunction: function _css3Selector(inputSelector, formSelector) { | 875 | selectorType: 'xpath' |
856 | return { | ||
857 | fullSelector: [formSelector, inputSelector].join(' '), | ||
858 | elts: (this.findAll ? this.findAll(inputSelector, formSelector) : null) | ||
859 | }; | ||
860 | } | ||
861 | }); | 876 | }); |
862 | }; | 877 | }; |
863 | 878 | ... | ... |
... | @@ -196,12 +196,12 @@ | ... | @@ -196,12 +196,12 @@ |
196 | /** | 196 | /** |
197 | * Fills a form with provided field values, and optionally submits it. | 197 | * Fills a form with provided field values, and optionally submits it. |
198 | * | 198 | * |
199 | * @param HTMLElement|String form A form element, or a CSS3 selector to a form element | 199 | * @param HTMLElement|String form A form element, or a CSS3 selector to a form element |
200 | * @param Object vals Field values | 200 | * @param Object vals Field values |
201 | * @param Function findFunction A function to be used for getting the selector for the element or a list of matching elements (optional) | 201 | * @param Function findType Element finder type (css, names, xpath) |
202 | * @return Object An object containing setting result for each field, including file uploads | 202 | * @return Object An object containing setting result for each field, including file uploads |
203 | */ | 203 | */ |
204 | this.fill = function fill(form, vals, findFunction) { | 204 | this.fill = function fill(form, vals, findType) { |
205 | /*jshint maxcomplexity:8*/ | 205 | /*jshint maxcomplexity:8*/ |
206 | var out = { | 206 | var out = { |
207 | errors: [], | 207 | errors: [], |
... | @@ -209,13 +209,6 @@ | ... | @@ -209,13 +209,6 @@ |
209 | files: [] | 209 | files: [] |
210 | }; | 210 | }; |
211 | 211 | ||
212 | findFunction = findFunction || function _nameSelector(elementName, formSelector) { | ||
213 | return { | ||
214 | fullSelector: [formSelector, '[name="' + elementName + '"]'].join(' '), | ||
215 | elts: this.findAll('[name="' + elementName + '"]', formSelector) | ||
216 | }; | ||
217 | }; | ||
218 | |||
219 | if (!(form instanceof HTMLElement) || typeof form === "string") { | 212 | if (!(form instanceof HTMLElement) || typeof form === "string") { |
220 | this.log("attempting to fetch form element from selector: '" + form + "'", "info"); | 213 | this.log("attempting to fetch form element from selector: '" + form + "'", "info"); |
221 | try { | 214 | try { |
... | @@ -227,30 +220,45 @@ | ... | @@ -227,30 +220,45 @@ |
227 | } | 220 | } |
228 | } | 221 | } |
229 | } | 222 | } |
223 | |||
230 | if (!form) { | 224 | if (!form) { |
231 | out.errors.push("form not found"); | 225 | out.errors.push("form not found"); |
232 | return out; | 226 | return out; |
233 | } | 227 | } |
234 | for (var name in vals) { | 228 | |
235 | if (!vals.hasOwnProperty(name)) { | 229 | var finders = { |
230 | css: function(inputSelector, formSelector) { | ||
231 | return this.findAll(inputSelector, form); | ||
232 | }, | ||
233 | names: function(elementName, formSelector) { | ||
234 | return this.findAll('[name="' + elementName + '"]', form); | ||
235 | }, | ||
236 | xpath: function(xpath, formSelector) { | ||
237 | return this.findAll({type: "xpath", path: xpath}, form); | ||
238 | } | ||
239 | }; | ||
240 | |||
241 | for (var fieldSelector in vals) { | ||
242 | if (!vals.hasOwnProperty(fieldSelector)) { | ||
236 | continue; | 243 | continue; |
237 | } | 244 | } |
238 | var field = findFunction.call(this, name, form).elts; | 245 | var field = finders[findType || "names"].call(this, fieldSelector, form), |
239 | var value = vals[name]; | 246 | value = vals[fieldSelector]; |
240 | if (!field || field.length === 0) { | 247 | if (!field || field.length === 0) { |
241 | out.errors.push('no field named "' + name + '" in form'); | 248 | out.errors.push('no field matching ' + findType + ' selector "' + fieldSelector + '" in form'); |
242 | continue; | 249 | continue; |
243 | } | 250 | } |
244 | try { | 251 | try { |
245 | out.fields[name] = this.setField(field, value); | 252 | out.fields[fieldSelector] = this.setField(field, value); |
246 | } catch (err) { | 253 | } catch (err) { |
247 | if (err.name === "FileUploadError") { | 254 | if (err.name === "FileUploadError") { |
248 | out.files.push({ | 255 | out.files.push({ |
249 | name: name, | 256 | type: findType, |
257 | selector: fieldSelector, | ||
250 | path: err.path | 258 | path: err.path |
251 | }); | 259 | }); |
252 | } else if(err.name === "FieldNotFound") { | 260 | } else if (err.name === "FieldNotFound") { |
253 | out.errors.push('Form field named "' + name + '" was not found.'); | 261 | out.errors.push('Unable to find field element in form: ' + err.toString()); |
254 | } else { | 262 | } else { |
255 | out.errors.push(err.toString()); | 263 | out.errors.push(err.toString()); |
256 | } | 264 | } |
... | @@ -680,26 +688,33 @@ | ... | @@ -680,26 +688,33 @@ |
680 | /*jshint maxcomplexity:99 */ | 688 | /*jshint maxcomplexity:99 */ |
681 | var logValue, fields, out; | 689 | var logValue, fields, out; |
682 | value = logValue = (value || ""); | 690 | value = logValue = (value || ""); |
683 | if (field instanceof NodeList) { | 691 | |
692 | if (field instanceof NodeList || field instanceof Array) { | ||
684 | fields = field; | 693 | fields = field; |
685 | field = fields[0]; | 694 | field = fields[0]; |
686 | } | 695 | } |
696 | |||
687 | if (!(field instanceof HTMLElement)) { | 697 | if (!(field instanceof HTMLElement)) { |
688 | var error = new Error('Invalid field type; only HTMLElement and NodeList are supported'); | 698 | var error = new Error('Invalid field type; only HTMLElement and NodeList are supported'); |
689 | error.name = 'FieldNotFound'; | 699 | error.name = 'FieldNotFound'; |
690 | throw error; | 700 | throw error; |
691 | } | 701 | } |
702 | |||
692 | if (this.options && this.options.safeLogs && field.getAttribute('type') === "password") { | 703 | if (this.options && this.options.safeLogs && field.getAttribute('type') === "password") { |
693 | // obfuscate password value | 704 | // obfuscate password value |
694 | logValue = new Array(value.length + 1).join("*"); | 705 | logValue = new Array(value.length + 1).join("*"); |
695 | } | 706 | } |
707 | |||
696 | this.log('Set "' + field.getAttribute('name') + '" field value to ' + logValue, "debug"); | 708 | this.log('Set "' + field.getAttribute('name') + '" field value to ' + logValue, "debug"); |
709 | |||
697 | try { | 710 | try { |
698 | field.focus(); | 711 | field.focus(); |
699 | } catch (e) { | 712 | } catch (e) { |
700 | this.log("Unable to focus() input field " + field.getAttribute('name') + ": " + e, "warning"); | 713 | this.log("Unable to focus() input field " + field.getAttribute('name') + ": " + e, "warning"); |
701 | } | 714 | } |
715 | |||
702 | var nodeName = field.nodeName.toLowerCase(); | 716 | var nodeName = field.nodeName.toLowerCase(); |
717 | |||
703 | switch (nodeName) { | 718 | switch (nodeName) { |
704 | case "input": | 719 | case "input": |
705 | var type = field.getAttribute('type') || "text"; | 720 | var type = field.getAttribute('type') || "text"; | ... | ... |
... | @@ -2,7 +2,40 @@ | ... | @@ -2,7 +2,40 @@ |
2 | /*jshint strict:false*/ | 2 | /*jshint strict:false*/ |
3 | var fs = require('fs'); | 3 | var fs = require('fs'); |
4 | 4 | ||
5 | casper.test.begin('fill() tests', 15, function(test) { | 5 | function testFormValues(test) { |
6 | test.assertField('email', 'chuck@norris.com', | ||
7 | 'can fill an input[type=text] form field'); | ||
8 | test.assertField('password', 'chuck', | ||
9 | 'can fill an input[type=password] form field') | ||
10 | test.assertField('content', 'Am watching thou', | ||
11 | 'can fill a textarea form field'); | ||
12 | test.assertField('topic', 'bar', | ||
13 | 'can pick a value from a select form field'); | ||
14 | test.assertField('check', true, | ||
15 | 'can check a form checkbox'); | ||
16 | test.assertEvalEquals(function() { | ||
17 | return __utils__.findOne('input[name="choice"][value="no"]').checked; | ||
18 | }, true, 'can check a form radio button 1/2'); | ||
19 | test.assertEvalEquals(function() { | ||
20 | return __utils__.findOne('input[name="choice"][value="yes"]').checked; | ||
21 | }, false, 'can check a form radio button 2/2'); | ||
22 | test.assertEvalEquals(function() { | ||
23 | return (__utils__.findOne('input[name="checklist[]"][value="1"]').checked && | ||
24 | !__utils__.findOne('input[name="checklist[]"][value="2"]').checked && | ||
25 | __utils__.findOne('input[name="checklist[]"][value="3"]').checked); | ||
26 | }, true, 'can fill a list of checkboxes'); | ||
27 | } | ||
28 | |||
29 | function testUrl(test) { | ||
30 | test.assertUrlMatch(/email=chuck@norris.com/, 'input[type=email] field was submitted'); | ||
31 | test.assertUrlMatch(/password=chuck/, 'input[type=password] field was submitted'); | ||
32 | test.assertUrlMatch(/content=Am\+watching\+thou/, 'textarea field was submitted'); | ||
33 | test.assertUrlMatch(/check=on/, 'input[type=checkbox] field was submitted'); | ||
34 | test.assertUrlMatch(/choice=no/, 'input[type=radio] field was submitted'); | ||
35 | test.assertUrlMatch(/topic=bar/, 'select field was submitted'); | ||
36 | } | ||
37 | |||
38 | casper.test.begin('fill() & fillNames() tests', 15, function(test) { | ||
6 | var fpath = fs.pathJoin(phantom.casperPath, 'README.md'); | 39 | var fpath = fs.pathJoin(phantom.casperPath, 'README.md'); |
7 | 40 | ||
8 | casper.start('tests/site/form.html', function() { | 41 | casper.start('tests/site/form.html', function() { |
... | @@ -16,101 +49,62 @@ casper.test.begin('fill() tests', 15, function(test) { | ... | @@ -16,101 +49,62 @@ casper.test.begin('fill() tests', 15, function(test) { |
16 | file: fpath, | 49 | file: fpath, |
17 | 'checklist[]': ['1', '3'] | 50 | 'checklist[]': ['1', '3'] |
18 | }); | 51 | }); |
19 | test.assertEvalEquals(function() { | 52 | testFormValues(test); |
20 | return __utils__.findOne('input[name="email"]').value; | ||
21 | }, 'chuck@norris.com', 'Casper.fill() can fill an input[type=text] form field'); | ||
22 | test.assertEvalEquals(function() { | ||
23 | return __utils__.findOne('input[name="password"]').value; | ||
24 | }, 'chuck', 'Casper.fill() can fill an input[type=password] form field'); | ||
25 | test.assertEvalEquals(function() { | ||
26 | return __utils__.findOne('textarea[name="content"]').value; | ||
27 | }, 'Am watching thou', 'Casper.fill() can fill a textarea form field'); | ||
28 | test.assertEvalEquals(function() { | ||
29 | return __utils__.findOne('select[name="topic"]').value; | ||
30 | }, 'bar', 'Casper.fill() can pick a value from a select form field'); | ||
31 | test.assertEvalEquals(function() { | ||
32 | return __utils__.findOne('input[name="check"]').checked; | ||
33 | }, true, 'Casper.fill() can check a form checkbox'); | ||
34 | test.assertEvalEquals(function() { | ||
35 | return __utils__.findOne('input[name="choice"][value="no"]').checked; | ||
36 | }, true, 'Casper.fill() can check a form radio button 1/2'); | ||
37 | test.assertEvalEquals(function() { | ||
38 | return __utils__.findOne('input[name="choice"][value="yes"]').checked; | ||
39 | }, false, 'Casper.fill() can check a form radio button 2/2'); | ||
40 | test.assertEvalEquals(function() { | 53 | test.assertEvalEquals(function() { |
41 | return __utils__.findOne('input[name="file"]').files.length === 1; | 54 | return __utils__.findOne('input[name="file"]').files.length === 1; |
42 | }, true, 'Casper.fill() can select a file to upload'); | 55 | }, true, 'can select a file to upload'); |
43 | test.assertEvalEquals(function() { | ||
44 | return (__utils__.findOne('input[name="checklist[]"][value="1"]').checked && | ||
45 | !__utils__.findOne('input[name="checklist[]"][value="2"]').checked && | ||
46 | __utils__.findOne('input[name="checklist[]"][value="3"]').checked); | ||
47 | }, true, 'Casper.fill() can fill a list of checkboxes'); | ||
48 | }); | 56 | }); |
49 | casper.thenClick('input[type="submit"]', function() { | 57 | casper.thenClick('input[type="submit"]', function() { |
50 | test.assertUrlMatch(/email=chuck@norris.com/, 'Casper.fill() input[type=email] field was submitted'); | 58 | testUrl(test); |
51 | test.assertUrlMatch(/password=chuck/, 'Casper.fill() input[type=password] field was submitted'); | ||
52 | test.assertUrlMatch(/content=Am\+watching\+thou/, 'Casper.fill() textarea field was submitted'); | ||
53 | test.assertUrlMatch(/check=on/, 'Casper.fill() input[type=checkbox] field was submitted'); | ||
54 | test.assertUrlMatch(/choice=no/, 'Casper.fill() input[type=radio] field was submitted'); | ||
55 | test.assertUrlMatch(/topic=bar/, 'Casper.fill() select field was submitted'); | ||
56 | }); | 59 | }); |
57 | casper.run(function() { | 60 | casper.run(function() { |
58 | test.done(); | 61 | test.done(); |
59 | }); | 62 | }); |
60 | }); | 63 | }); |
61 | 64 | ||
62 | casper.test.begin('fillSelector() tests', 15, function(test) { | 65 | casper.test.begin('fillSelectors() tests', 15, function(test) { |
63 | var fpath = fs.pathJoin(phantom.casperPath, 'README.md'); | 66 | var fpath = fs.pathJoin(phantom.casperPath, 'README.md'); |
64 | 67 | ||
65 | casper.start('tests/site/form.html', function() { | 68 | casper.start('tests/site/form.html', function() { |
66 | this.fillSelectors('form[action="result.html"]', { | 69 | this.fillSelectors('form[action="result.html"]', { |
67 | "input[name='email']": 'chuck@norris.com', | 70 | "input[name='email']": 'chuck@norris.com', |
68 | "input[name='password']": 'chuck', | 71 | "input[name='password']": 'chuck', |
69 | "textarea[name='content']": 'Am watching thou', | 72 | "textarea[name='content']": 'Am watching thou', |
70 | "input[name='check']": true, | 73 | "input[name='check']": true, |
71 | "input[name='choice']": 'no', | 74 | "input[name='choice']": 'no', |
72 | "select[name='topic']": 'bar', | 75 | "select[name='topic']": 'bar', |
73 | "input[name='file']": fpath, | 76 | "input[name='file']": fpath, |
74 | "input[name='checklist[]']": ['1', '3'] | 77 | "input[name='checklist[]']": ['1', '3'] |
75 | } | 78 | }); |
76 | ); | 79 | testFormValues(test); |
77 | test.assertEvalEquals(function() { | ||
78 | return __utils__.findOne('input[name="email"]').value; | ||
79 | }, 'chuck@norris.com', 'Casper.fill() can fill an input[type=text] form field'); | ||
80 | test.assertEvalEquals(function() { | ||
81 | return __utils__.findOne('input[name="password"]').value; | ||
82 | }, 'chuck', 'Casper.fill() can fill an input[type=password] form field'); | ||
83 | test.assertEvalEquals(function() { | ||
84 | return __utils__.findOne('textarea[name="content"]').value; | ||
85 | }, 'Am watching thou', 'Casper.fill() can fill a textarea form field'); | ||
86 | test.assertEvalEquals(function() { | ||
87 | return __utils__.findOne('select[name="topic"]').value; | ||
88 | }, 'bar', 'Casper.fill() can pick a value from a select form field'); | ||
89 | test.assertEvalEquals(function() { | ||
90 | return __utils__.findOne('input[name="check"]').checked; | ||
91 | }, true, 'Casper.fill() can check a form checkbox'); | ||
92 | test.assertEvalEquals(function() { | ||
93 | return __utils__.findOne('input[name="choice"][value="no"]').checked; | ||
94 | }, true, 'Casper.fill() can check a form radio button 1/2'); | ||
95 | test.assertEvalEquals(function() { | ||
96 | return __utils__.findOne('input[name="choice"][value="yes"]').checked; | ||
97 | }, false, 'Casper.fill() can check a form radio button 2/2'); | ||
98 | test.assertEvalEquals(function() { | 80 | test.assertEvalEquals(function() { |
99 | return __utils__.findOne('input[name="file"]').files.length === 1; | 81 | return __utils__.findOne('input[name="file"]').files.length === 1; |
100 | }, true, 'Casper.fill() can select a file to upload'); | 82 | }, true, 'can select a file to upload'); |
101 | test.assertEvalEquals(function() { | 83 | }); |
102 | return (__utils__.findOne('input[name="checklist[]"][value="1"]').checked && | 84 | casper.thenClick('input[type="submit"]', function() { |
103 | !__utils__.findOne('input[name="checklist[]"][value="2"]').checked && | 85 | testUrl(test); |
104 | __utils__.findOne('input[name="checklist[]"][value="3"]').checked); | 86 | }); |
105 | }, true, 'Casper.fill() can fill a list of checkboxes'); | 87 | casper.run(function() { |
88 | test.done(); | ||
89 | }); | ||
90 | }); | ||
91 | |||
92 | casper.test.begin('fillXPath() tests', 14, function(test) { | ||
93 | casper.start('tests/site/form.html', function() { | ||
94 | this.fillXPath('form[action="result.html"]', { | ||
95 | '//input[@name="email"]': 'chuck@norris.com', | ||
96 | '//input[@name="password"]': 'chuck', | ||
97 | '//textarea[@name="content"]': 'Am watching thou', | ||
98 | '//input[@name="check"]': true, | ||
99 | '//input[@name="choice"]': 'no', | ||
100 | '//select[@name="topic"]': 'bar', | ||
101 | '//input[@name="checklist[]"]': ['1', '3'] | ||
102 | }); | ||
103 | testFormValues(test); | ||
104 | // note: file inputs cannot be filled using XPath | ||
106 | }); | 105 | }); |
107 | casper.thenClick('input[type="submit"]', function() { | 106 | casper.thenClick('input[type="submit"]', function() { |
108 | test.assertUrlMatch(/email=chuck@norris.com/, 'Casper.fill() input[type=email] field was submitted'); | 107 | testUrl(test); |
109 | test.assertUrlMatch(/password=chuck/, 'Casper.fill() input[type=password] field was submitted'); | ||
110 | test.assertUrlMatch(/content=Am\+watching\+thou/, 'Casper.fill() textarea field was submitted'); | ||
111 | test.assertUrlMatch(/check=on/, 'Casper.fill() input[type=checkbox] field was submitted'); | ||
112 | test.assertUrlMatch(/choice=no/, 'Casper.fill() input[type=radio] field was submitted'); | ||
113 | test.assertUrlMatch(/topic=bar/, 'Casper.fill() select field was submitted'); | ||
114 | }); | 108 | }); |
115 | casper.run(function() { | 109 | casper.run(function() { |
116 | test.done(); | 110 | test.done(); | ... | ... |
-
Please register or sign in to post a comment