b6660125823b6c525ce57e783abee04fce025a55
[tapestry-5.git] / tapestry-core / src / test / java / org / apache / tapestry5 / integration / app1 / FormTests.java
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12
13 package org.apache.tapestry5.integration.app1;
14
15 import java.text.SimpleDateFormat;
16 import java.util.Date;
17
18 import org.apache.tapestry5.corelib.components.Form;
19 import org.openqa.selenium.By;
20 import org.openqa.selenium.support.ui.ExpectedCondition;
21 import org.openqa.selenium.support.ui.ExpectedConditions;
22 import org.testng.annotations.Test;
23
24 /**
25 * Tests for the {@link Form} component as well as many form control components.
26 */
27 public class FormTests extends App1TestCase
28 {
29
30 @Test
31 public void form_encoding_type()
32 {
33 openLinks("Form Encoding Type");
34
35 assertAttribute("//form/@enctype", "x-override");
36 }
37
38 @Test
39 public void page_context_in_form()
40 {
41 openLinks("Page Context in Form");
42
43 assertTextSeries("//div[@id='results']//li[%d]", 1, "betty", "wilma", "context with spaces", "context/with/slashes");
44 assertFieldValue("t:ac", "betty/wilma/context$0020with$0020spaces/context$002fwith$002fslashes");
45
46 clickAndWait(SUBMIT);
47
48 assertTextSeries("//div[@id='results']//li[%d]", 1, "betty", "wilma", "context with spaces", "context/with/slashes");
49 assertFieldValue("t:ac", "betty/wilma/context$0020with$0020spaces/context$002fwith$002fslashes");
50 }
51
52 @Test
53 public void password_field()
54 {
55 openLinks("PasswordFieldDemo");
56
57 type("userName", "howard");
58 type("password", "wrong-password");
59
60 clickAndWait(SUBMIT);
61
62 assertFieldValue("userName", "howard");
63 // Verify that password fields do not render a non-blank password, even
64 // when it is known.
65 assertFieldValue("password", "");
66
67 assertTextPresent("[howard]");
68 assertTextPresent("[wrong-password]");
69
70 type("password", "tapestry");
71
72 clickAndWait(SUBMIT);
73
74 assertTextPresent("You have provided the correct user name and password.");
75 }
76
77 @Test
78 public void server_side_validation_for_textfield_and_textarea() throws Exception
79 {
80 openLinks("ValidForm");
81
82 clickAndWait(SUBMIT);
83
84 assertTextPresent("You must provide a value for Email.");
85 // is an overridden validation error message:
86 assertTextPresent("Please provide a detailed description of the incident.");
87
88 type("email", "foo@bar.baz");
89 type("message", "Show me the money!");
90 type("hours", "foo");
91
92 clickAndWait(SUBMIT);
93
94 assertTextPresent("[false]");
95 assertTextPresent("You must provide an integer value for Hours.");
96
97 assertAttribute("//input[@id='hours']/@value", "foo");
98
99 type("hours", " 19 ");
100 click("//input[@id='urgent']");
101 clickAndWait(SUBMIT);
102
103 assertTextPresent("[foo@bar.baz]");
104 assertTextPresent("[Show me the money!]");
105 assertTextPresent("[true]");
106 assertTextPresent("[19]");
107 }
108
109 @Test
110 public void client_side_validation()
111 {
112 openLinks("Client Validation Demo");
113
114 clickAndWait("link=Reset Page State");
115
116 // Notice: click, not click and wait.
117
118 click(SUBMIT);
119
120 assertTextPresent("You must provide a value for First Name.");
121
122 type("firstName", "Howard");
123 type("lastName", "Lewis Ship");
124 type("birthYear", "1000");
125 type("password", "supersecret");
126
127 click(SUBMIT);
128
129 type("birthYear", "1966");
130 click("citizen");
131
132 clickAndWait(SUBMIT);
133
134 assertTextPresent("Howard", "Lewis Ship", "1966", "U.S. Citizen");
135 }
136
137 @Test
138 public void cancel_button()
139 {
140 openLinks("Client Validation Demo");
141
142 // Used to ensure that the <script> tag was present, but that's hard to
143 // do with script combining enabled.
144
145 clickAndWait("link=Clear Data");
146
147 clickAndWait("//input[@value='Cancel']");
148
149 assertText("message", "Form was cancelled.");
150 }
151
152 @Test
153 public void radio_group_validator()
154 {
155 openLinks("RadioDemo", "reset");
156
157 // Verify that the "required" validator works.
158 clickAndWait(SUBMIT);
159
160 assertTextPresent("You must provide a value for Department.");
161 }
162
163 // This test has been disabled because the use of the pattern attribute
164 // by the Regexp validator, prevents the form from submitting.
165 @Test(enabled=false)
166 public void regexp_validator()
167 {
168 openLinks("Regexp Demo");
169
170 String update = SUBMIT;
171
172 type("zipCode", "abc");
173
174 click(update); // but don't wait
175
176 assertTextPresent("A zip code consists of five or nine digits, eg: 02134 or 90125-4472.");
177
178 type("zipCode", "12345");
179
180 clickAndWait(update);
181
182 assertTextPresent("Zip code: [12345]");
183
184 type("zipCode", "12345-9876");
185
186 clickAndWait(update);
187
188 assertTextPresent("Zip code: [12345-9876]");
189 }
190
191 @Test
192 public void basic_datefield()
193 {
194 openLinks("DateField Demo", "Reset Page State", "english");
195
196 type("birthday", "24 dec 1966");
197 type("asteroidImpact", "05/28/2046");
198
199 clickAndWait(SUBMIT);
200
201 assertText("birthday-output", "12/24/1966");
202 assertText("impact-output", "05/28/2046");
203
204 assertFieldValue("birthday", "24 Dec 1966");
205 assertFieldValue("asteroidImpact", "5/28/2046");
206
207 clickAndWait("link=french");
208
209 click("css=.x-birthday .btn");
210
211 waitForAjaxRequestsToComplete();
212
213 assertText("//A[@class='topLabel']", "1966 d\u00e9cembre");
214 }
215
216 // TAP5-2197
217 @Test
218 public void datefield_leniency()
219 {
220 openLinks("DateField Demo", "Reset Page State", "english");
221
222 type("asteroidImpact", "00/00/0000");
223 type("lenient", "00/00/0000");
224
225 clickAndWait(SUBMIT);
226
227 // By default, DateField is not lenient anymore
228 assertText("css=div.x-impact p.help-block", "Date value '00/00/0000' is not parseable.");
229
230 // But this one is configured as such by setting the "lenient" parameter to true.
231 assertFalse(isElementPresent("css=div.x-lenient p.help-block"));
232
233 // Check whether a String coerced to a DateFormat results in a lenient or not instance
234 // according to the SymbolConstants.LENIENT_DATE_FORMAT symbol (default false)
235 assertText("coercedStringToDateFormatLenient", "false");
236
237 }
238
239 // TAP5-1057
240 @Test
241 public void xss_datefield()
242 {
243 openLinks("DateField Demo", "Reset Page State", "english");
244
245 type("asteroidImpact", "<script>alert('T5 is great'); </script>");
246
247 click("css=.x-impact .btn");
248
249 waitForAjaxRequestsToComplete();
250
251 assertSourcePresent("Unparseable date: \"&lt;script&gt;alert('T5 is great'); &lt;/script&gt;\"");
252 }
253
254 // TAP5-1409
255 @Test
256 public void datefield_select_newmonth_samedate()
257 {
258 openLinks("DateField Demo", "Reset Page State", "english");
259
260 //start with a known date...
261 type("asteroidImpact", "05/28/2035");
262
263 click("css=.x-impact .btn");
264
265 ExpectedCondition datePickerVisible = ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div.datePicker"));
266
267 waitForCondition(datePickerVisible);
268 assertEquals(getText("css=td.selected"), "28");
269
270 //move to the next month.
271 click("css=button.nextButton");
272
273 //first, make sure that NOTHING shows as selected! The selected date is still 5/28/46
274
275 waitForSelectedToBeRemoved();
276
277
278 //make sure it's still selected if we navigate back...
279 click("css=button.previousButton");
280 waitForCSSSelectedElementToAppear("td.selected");
281
282 click("css=button.nextButton");
283
284 waitForSelectedToBeRemoved();
285
286 click("xpath=//td[text()='28']");
287 String pickerGoneSelector = "css=div.datePicker";
288 waitForInvisible(pickerGoneSelector);
289
290 assertFieldValue("asteroidImpact", "6/28/2035");
291
292 //a few other behaviors to check on as a side-effect of implementing the fix for 1409:
293 //1) If today is selected and it's the current month, pressing the "Today" button should close the popup
294 //2) If today is selected and we're on some other month, pressing the "Today" button should just take us
295 // back to the today.
296 //3) If today is not selected, pressing the "Today" button should set the date and close the popup.
297 //4) Pressing the "None" button should always close the popup and result in no date.
298
299 //#3
300 click("css=.x-impact .btn");
301
302 waitForCondition(datePickerVisible);
303 click("css=div.datePicker .footerTable button");
304 waitForInvisible(pickerGoneSelector);
305
306 String value = getValue("asteroidImpact");
307 assertFieldValue("asteroidImpact", new SimpleDateFormat("M/d/yyyy").format(new Date()));
308
309 //#2...
310 click("css=.x-impact .btn");
311
312 waitForCondition(datePickerVisible);
313 click("css=button.nextButton");
314
315 waitForSelectedToBeRemoved();
316
317 click("css=div.datePicker .footerTable button");
318 waitForCSSSelectedElementToAppear("td.selected");
319
320 //#1
321 click("css=div.datePicker .footerTable button");
322 waitForInvisible(pickerGoneSelector);
323 assertFieldValue("asteroidImpact", value);
324
325 //#4...
326
327 click("css=.x-impact .btn");
328
329 waitForCondition(datePickerVisible);
330
331 String noneButton = "//button[text()='None']";
332
333 click(noneButton);
334
335 waitForInvisible(pickerGoneSelector);
336
337 assertFieldValue("asteroidImpact", "");
338
339 click("css=.x-impact .btn");
340
341 waitForCondition(datePickerVisible);
342 assertFalse(isElementPresent("css=td.selected"));
343
344 click(noneButton);
345
346 waitForInvisible(pickerGoneSelector);
347 assertFieldValue("asteroidImpact", "");
348 }
349
350 private void waitForSelectedToBeRemoved()
351 {
352 waitForCondition("selenium.browserbot.getCurrentWindow().testSupport.findCSSMatchCount('td.selected') == 0", PAGE_LOAD_TIMEOUT);
353 }
354
355 // TAP5-1408, TAP5-2203
356 @Test
357 public void datefield_clickoutside_closes()
358 {
359 openLinks("DateField Demo", "Reset Page State", "english");
360
361 type("asteroidImpact", "05/28/2046");
362
363 click("css=.x-impact .btn");
364
365 ExpectedCondition datePickerVisible = ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div.datePicker"));
366
367 waitForCondition(datePickerVisible);
368
369 click("css=.x-impact .btn");
370 waitForInvisible("css=div.datePicker");
371
372 //make sure that clicking somewhere outside the date picker
373 //closes it
374 click("css=.x-impact .btn");
375 waitForCondition(datePickerVisible);
376
377 click("css=h1");
378 waitForInvisible("css=div.datePicker");
379
380 //also make sure that clicking the month label /doesn't/ close the picker
381 click("css=.x-impact .btn");
382 waitForCondition(datePickerVisible);
383 click("css=a.topLabel");
384 waitForCSSSelectedElementToAppear("div.labelPopup");
385 click("css=div.labelPopup a");
386
387 waitForInvisible("css=div.labelPopup");
388 //It's basically impossible to express "wait until the popup doesn't disappear"
389 //Instead, we take advantage of knowing that the datepicker disappears with this bug /almost/
390 //immediately after picking the month label, so we sleep the test for a few seconds to provide
391 //ammple time for the bug to manifest.
392
393 waitForAjaxRequestsToComplete();
394
395 assertTrue(isVisible("css=div.datePicker"));
396 }
397
398 @Test
399 public void event_based_translate() throws Exception
400 {
401 openLinks("EventMethod Translator");
402
403 type("count", "123");
404 clickAndWait(SUBMIT);
405
406 assertTextPresent("Count: [123]");
407
408 type("count", "0");
409 clickAndWait(SUBMIT);
410
411 assertTextPresent("Count: [0]");
412
413 assertFieldValue("count", "zero");
414
415 type("count", "456");
416 clickAndWait(SUBMIT);
417
418 assertTextPresent("Count: [456]");
419
420 assertFieldValue("count", "456");
421
422 type("count", "ZERO");
423 clickAndWait(SUBMIT);
424
425 assertTextPresent("Count: [0]");
426
427 assertFieldValue("count", "zero");
428
429 // Try the server-side custom exception reporting.
430
431 type("count", "13");
432 clickAndWait(SUBMIT);
433
434 assertTextPresent("Event Handler Method Translate", "Thirteen is an unlucky number.");
435
436 type("count", "i");
437 clickAndWait(SUBMIT);
438
439 assertTextPresent("Event Handler Method Translate", "Rational numbers only, please.");
440 }
441
442 @Test
443 public void radio_button_and_group()
444 {
445 openLinks("RadioDemo");
446
447 String update = SUBMIT;
448
449 webDriver.findElements(By.cssSelector("label")).stream().filter(element-> element.getText().contains("Accounting")).findFirst().get().click();
450 clickAndWait(update);
451
452 assertTextPresent("Selected department: ACCOUNTING");
453
454 webDriver.findElements(By.cssSelector("label")).stream().filter(element-> element.getText().contains("Sales And Marketin")).findFirst().get().click();
455
456 clickAndWait(update);
457
458 assertTextPresent("Selected department: SALES_AND_MARKETING");
459
460 // not in a loop ...
461 webDriver.findElements(By.cssSelector("label")).stream().filter(element-> element.getText().contains("Temp")).findFirst().get().click();
462
463 clickAndWait(update);
464
465 assertTextPresent("Selected position: TEMP");
466
467 webDriver.findElements(By.cssSelector("label")).stream().filter(element-> element.getText().contains("Lifer")).findFirst().get().click();
468
469 clickAndWait(update);
470
471 assertTextPresent("Selected position: LIFER");
472 }
473
474 @Test
475 public void disabled_fields() throws Exception
476 {
477 openLinks("Disabled Fields");
478
479 // The couple of places where there's a _0 suffix is related to
480 // the fix for https://issues.apache.org/jira/browse/TAP5-1632
481 String[] paths = new String[]
482 {"//input[@id='textfield']",
483
484 "//input[@id='passwordfield']",
485
486 "//textarea[@id='textarea']",
487
488 "//input[@id='checkbox']",
489
490 "//select[@id='select_0']",
491
492 "//input[@id='radio1']",
493
494 "//input[@id='radio2']",
495
496 "//input[@id='datefield']",
497
498 "//div[@class='palette']//input[@type='hidden']",
499
500 "//div[@class='palette-available']//select",
501
502 "//div[@class='palette-selected']//select",
503
504 "//input[@name='checklist']",
505
506 // TAP5-2078
507 "//input[@name='radiogroup']",
508
509 "//input[@id='submit_0']"};
510
511 for (String path : paths)
512 {
513 String locator = String.format("%s/@disabled", path);
514
515 assertAttribute(locator, "disabled");
516 }
517
518 assertAttribute("css=div.palette .btn@disabled", "true");
519
520 //TAP5-2078
521 clickAndWait("//input[@value='Continue']");
522
523 assertFalse(isTextPresent("This should not happen"));
524 }
525
526 /**
527 * TAPESTRY-2056
528 */
529 @Test
530 public void null_field_strategy()
531 {
532 openLinks("Null Field Strategy Demo");
533
534 String locator = "//span[@id='value']";
535
536 assertText(locator, "");
537
538 assertAttribute("//input[@id='number']/@value", "0");
539
540 type("number", "");
541
542 clickAndWait(SUBMIT);
543
544 assertText(locator, "0");
545 }
546
547 /**
548 * TAPESTRY-1647
549 */
550 @Test
551 public void label_invokes_validation_decorator_at_correct_time()
552 {
553 openLinks("Override Validation Decorator");
554
555 // This is sub-optimal, as it doesn't esnure that the before/after field
556 // values really do wrap around
557 // the field (they do, but that's hard to prove!). It is also susceptible to
558 // idiosyncrasies around how Tapestry renders attributes, and how the browser
559 // represents them.
560
561 // Along the way we are also testing:
562 // - primitive types are automatically required
563 // - AbstractTextField.isRequired() and the logic inside
564 // ComponentFieldValidator.isRequired()
565
566 assertSourcePresent(
567 "[Before label for Value]<label for=\"value\" class=\"control-label\">Value</label>[After label for Value]",
568 "[Before field Value]",
569 "[After field Value (optional)]",
570 "[Before label for Required Value]<label for=\"requiredValue\" class=\"control-label\">Required Value</label>[After label for Required Value]",
571 "[Before field Required Value]", "[After field Required Value (required)]");
572 }
573
574 /**
575 * TAPESTRY-2085
576 */
577 @Test
578 public void wrapper_types_with_text_field()
579 {
580 openLinks("TextField Wrapper Types", "Reset Page State");
581
582 assertFieldValue("count", "");
583 assertText("value", "null");
584
585 type("count", "0");
586 clickAndWait(SUBMIT);
587
588 assertFieldValue("count", "0");
589 assertText("value", "0");
590
591 type("count", "1");
592 clickAndWait(SUBMIT);
593
594 assertFieldValue("count", "1");
595 assertText("value", "1");
596
597 clickAndWait("link=clear");
598
599 assertFieldValue("count", "");
600 assertText("value", "null");
601 }
602
603 @Test
604 public void submit_with_context()
605 {
606 openLinks("Submit With Context");
607
608 clickAndWait(SUBMIT);
609
610 assertTextPresent("Result: 10.14159");
611 }
612
613 /**
614 * TAPESTRY-2563
615 */
616 @Test
617 public void form_action_via_get()
618 {
619 open(getBaseURL() + "validform.form", "true");
620
621 assertTextPresent("Forms require that the request method be POST and that the t:formdata query parameter have values.");
622 }
623
624 /**
625 * TAPESTRY-2352
626 */
627 @Test
628 public void client_field_format_validation()
629 {
630 openLinks("Client Format Validation");
631
632 type("amount", "abc");
633 type("quantity", "abc");
634
635 click(SUBMIT);
636
637 assertTextPresent("You must provide a numeric value for Amount.",
638 "Provide quantity as a number.");
639 }
640
641 /**
642 * TAPESTRY-2438
643 */
644 @Test
645 public void validation_exception_thrown_from_validate_form_event_handler()
646 {
647 openLinks("ValidationForm ValidationException Demo");
648
649 clickAndWait(SUBMIT);
650
651 assertTextPresent("From event handler method.");
652
653 assertText("event", "failure");
654 }
655
656 @Test
657 public void form_field_outside_form()
658 {
659 openLinks("Form Field Outside Form");
660
661 assertTextPresent(
662 "org.apache.tapestry5.internal.services.RenderQueueException",
663 "Render queue error in SetupRender[FormFieldOutsideForm:textfield]: Component FormFieldOutsideForm:textfield must be enclosed by a Form component.",
664 "context:FormFieldOutsideForm.tml, line 5");
665 }
666
667 /**
668 * TAP5-281
669 */
670 @Test
671 public void nested_form_check()
672 {
673 openLinks("Nested Form Demo");
674
675 assertTextPresent("Form components may not be placed inside other Form components.");
676 }
677
678 /**
679 * TAP5-87
680 */
681 @Test
682 public void blank_password_does_not_update()
683 {
684 openLinks("Blank Password Demo");
685
686 type("password", "secret");
687
688 clickAndWait(SUBMIT);
689
690 assertFieldValue("password", "");
691
692 assertText("visiblepassword", "secret");
693
694 clickAndWait(SUBMIT);
695
696 assertFieldValue("password", "");
697
698 assertText("visiblepassword", "secret");
699 }
700
701 /**
702 * TAP5-228: And to think I almost blew off the integration tests!
703 */
704 @Test
705 public void per_form_validation_messages_and_constraints()
706 {
707 openLinks("Per-Form Validation Messages");
708
709 clickAndWait("//input[@type='submit' and @value='Login']");
710
711 assertTextPresent("Enter the unique user id you provided when you registerred.");
712
713 type("userId", "aaa");
714
715 clickAndWait("//input[@type='submit' and @value='Login']");
716
717 assertTextPresent("You must provide at least 10 characters for User Id.");
718
719 clickAndWait("//input[@type='submit' and @value='Register']");
720
721 assertTextPresent("Enter a unique user id, such as your initials.");
722
723 type("userId_0", "aaa");
724
725 clickAndWait("//input[@type='submit' and @value='Register']");
726
727 assertTextPresent("You must provide at least 20 characters for User Id.");
728 }
729
730 /**
731 * TAP5-719
732 */
733 @Test
734 public void link_submit_without_validator()
735 {
736 openLinks("LinkSubmit Without Validator Demo");
737
738 type("searchField", "Anders Haraldsson");
739
740 clickAndWait("//a[@id='searchLink']");
741
742 assertTextPresent("Result: Anders Haraldsson not found!");
743 }
744
745 /**
746 * TAP5-211
747 */
748 @Test
749 public void client_side_numeric_validation()
750 {
751 openLinks("Client-Side Numeric Validation", "Reset Page State", "Setup Values");
752
753 assertText("outputLongValue", "1000");
754 assertText("outputDoubleValue", "1234.67");
755
756 assertFieldValue("longValue", "1000");
757 assertFieldValue("doubleValue", "1,234.67");
758
759 type("longValue", "2,000 ");
760 type("doubleValue", " -456,789.12");
761
762 clickAndWait(SUBMIT);
763
764 assertText("outputLongValue", "2000");
765 assertText("outputDoubleValue", "-456789.12");
766
767 assertFieldValue("longValue", "2000");
768 assertFieldValue("doubleValue", "-456,789.12");
769
770 clickAndWait("link=Switch to German");
771
772 assertText("outputLongValue", "2000");
773 assertText("outputDoubleValue", "-456789.12");
774
775 assertFieldValue("longValue", "2000");
776 assertFieldValue("doubleValue", "-456.789,12");
777
778 type("longValue", "3.000");
779 type("doubleValue", "5.444.333,22");
780
781 clickAndWait(SUBMIT);
782
783 assertFieldValue("longValue", "3000");
784 assertFieldValue("doubleValue", "5.444.333,22");
785
786 assertText("outputLongValue", "3000");
787 assertText("outputDoubleValue", "5444333.22");
788
789 clickAndWait("link=Setup Values");
790
791 type("longValue", "4000.");
792 click(SUBMIT);
793
794 assertTextPresent("You must provide an integer value for Long Value.");
795
796 type("doubleValue", "abc");
797
798 click(SUBMIT);
799
800 assertTextPresent("You must provide a numeric value for Double Value.");
801 }
802
803 @Test
804 public void client_validation_for_numeric_fields_that_are_not_required()
805 {
806 openLinks("Form Zone Demo");
807
808 type("longValue", "alpha");
809
810 click(SUBMIT);
811
812 assertTextPresent("You must provide an integer value for Long Value.");
813
814 type("longValue", "37");
815
816 click(SUBMIT);
817
818 waitForElementToAppear("outputvalue");
819
820 assertText("outputvalue", "37");
821 }
822
823 @Test
824 public void hidden_field()
825 {
826 openLinks("Hidden Demo", "setup");
827
828 clickAndWait(SUBMIT);
829
830 assertText("stored", "12345");
831 }
832
833 @Test
834 public void validation_constraints_from_messages()
835 {
836 openLinks("Validation Constraints From Messages");
837
838 click(SUBMIT);
839
840 assertTextPresent("You must provide a value for Name.");
841 assertTextPresent("You must provide a value for Age.");
842
843 type("name", "behemoth");
844 type("age", "0");
845 select("type", "label=Snake");
846
847 click(SUBMIT);
848 assertTextPresent("Age requires a value of at least 1.");
849
850 type("age", "121");
851 click(SUBMIT);
852 assertTextPresent("Age requires a value no larger than 120.");
853
854 type("age", "5");
855 clickAndWait(SUBMIT);
856 }
857
858 /**
859 * TAP5-157
860 */
861 @Test
862 public void link_submit_component()
863 {
864 openLinks("LinkSubmit Demo");
865
866 click("//a[@id='fred']");
867
868 assertTextPresent("You must provide a value for Name.");
869
870 type("name", "Wilma");
871
872 clickAndWait("link=Fred");
873
874 assertText("name-value", "Wilma");
875 assertText("last-clicked", "Fred");
876 assertTextPresent("Result: 10.14159");
877
878 type("name", "Betty");
879
880 clickAndWait("link=Barney");
881
882 assertText("name-value", "Betty");
883 assertText("last-clicked", "Barney");
884 }
885
886 /**
887 * TAP5-2183
888 */
889 @Test
890 public void link_submit_component_with_nested_element()
891 {
892 openLinks("LinkSubmit Demo");
893
894 type("name", "Wilma");
895
896 clickAndWait("css=.glyphicon-star");
897
898 assertText("name-value", "Wilma");
899 assertText("last-clicked", "Pebbles");
900 }
901
902 @Test
903 public void calendar_field_inside_bean_editor()
904 {
905 openLinks("BeanEditor / Calendar Demo", "Reset Page State");
906
907 type("calendar", "04/06/1978");
908
909 clickAndWait(SUBMIT);
910
911 assertTextPresent("Apr 6, 1978");
912
913 // TAP5-1043
914 clickAndWait("link=clear");
915 }
916
917 @Test
918 public void image_submit_triggers_selected_event()
919 {
920 openLinks("Submit with an Image Demo");
921
922 type("value", "barney gumble");
923
924 clickAndWait("//input[@type='image']");
925
926 assertText("outputvalue", "barney gumble");
927
928 assertText("eventfired", "true");
929 }
930
931 /**
932 * Tests for forms and form submissions and basic form control components.
933 * also tests a few other things, such as
934 * computed default bindings and invisible instrumentation.
935 */
936 @Test
937 public void simple_form()
938 {
939 openLinks("SimpleForm");
940
941 assertText("//label[@for='disabled']", "Disabled");
942
943 // This demonstrates TAPESTRY-1642:
944 assertText("//label[@for='email']", "User Email");
945
946 assertText("//label[@for='message']", "Incident Message");
947 assertText("//label[@for='operatingSystem']", "Operating System");
948 assertText("//label[@for='department']", "Department");
949 assertText("//label[@for='urgent']", "Urgent Processing Requested");
950
951 assertFieldValue("email", "");
952 assertFieldValue("message", "");
953 assertFieldValue("operatingSystem", "osx");
954 assertFieldValue("department", "");
955 assertFieldValue("urgent", "on");
956
957 clickAndWait(SUBMIT);
958
959 assertTextPresent("department: []");
960
961 type("email", "foo@bar.baz");
962 type("message", "Message for you, sir!");
963 select("operatingSystem", "Windows NT");
964 select("department", "R&D");
965 click("urgent");
966
967 clickAndWait(SUBMIT);
968
969 assertFieldValue("email", "foo@bar.baz");
970 assertFieldValue("message", "Message for you, sir!");
971 assertFieldValue("urgent", "off");
972
973 // Tried to use "email:" and "exact:email:" but Selenium 0.8.1 doesn't
974 // seem to accept that.
975
976 assertTextPresent("[foo@bar.baz]", "[Message for you, sir!]", "[false]", "[winnt]", "[RESEARCH_AND_DESIGN]");
977
978 // Haven't figured out how to get selenium to check that fields are
979 // disabled.
980 }
981
982 /**
983 * TAP5-915
984 */
985 @Test
986 public void override_datefield_message_catalog()
987 {
988 open(getBaseURL() + "overridedatefieldmessagecatalogdemo");
989
990 type("birthday", "aaaaa");
991
992 clickAndWait("//input[@type='submit' and @value='Go']");
993
994 assertTextPresent("The input 'aaaaa' is not a valid date");
995 }
996
997 /**
998 * TAP5-52.
999 */
1000 @Test
1001 public void single_error_message()
1002 {
1003 open(getBaseURL() + "singleerrordemo");
1004
1005 clickAndWait(SUBMIT);
1006
1007 assertTextPresent("You must provide a value for Username");
1008 assertTextPresent("You must provide a value for Password");
1009
1010 type("username", "Igor");
1011
1012 clickAndWait(SUBMIT);
1013
1014 assertFalse(isTextPresent("You must provide a value for Username"));
1015 assertTextPresent("You must provide a value for Password");
1016
1017 type("password", "secret");
1018
1019 clickAndWait(SUBMIT);
1020
1021 assertFalse(isTextPresent("You must provide a value for Username"));
1022 assertFalse(isTextPresent("You must provide a value for Password"));
1023 }
1024
1025 /**
1026 * TAP5-1024
1027 */
1028 @Test
1029 public void use_of_cancel_mode_on_submit_button()
1030 {
1031 openLinks("Cancel Demo");
1032
1033 clickAndWait("//input[@value='Cancel Form']");
1034
1035 assertText("message", "Form was canceled.");
1036 }
1037
1038 @Test
1039 public void use_of_cancel_mode_with_submitlink()
1040 {
1041 openLinks("Cancel Demo");
1042
1043 clickAndWait("link=Cancel Form");
1044
1045 assertText("message", "Form was canceled.");
1046 }
1047
1048 @Test
1049 public void validation_decoration_for_select() throws Exception
1050 {
1051 openLinks("Select Demo");
1052
1053 clickAndWait(SUBMIT);
1054
1055 assertTextPresent("You must provide a value for Color.");
1056
1057 select("color", "label=Green");
1058
1059 clickAndWait(SUBMIT);
1060
1061 assertTextPresent("Selected color: Green");
1062 }
1063
1064 /**
1065 * TAP5-1098.
1066 */
1067 @Test
1068 public void create_select_model_from_objects_and_property_name() throws Exception
1069 {
1070 openLinks("SelectModel from objects and property name");
1071
1072 select("track", "label=The Calling");
1073
1074 clickAndWait(SUBMIT);
1075
1076 assertTextPresent("Selected track: The Calling, Synaesthetic");
1077 }
1078
1079 @Test
1080 public void create_select_model_from_objects() throws Exception
1081 {
1082 openLinks("SelectModel from objects");
1083
1084 select("track", "label=The Calling");
1085
1086 clickAndWait(SUBMIT);
1087
1088 assertTextPresent("Selected track: The Calling, Synaesthetic");
1089 }
1090
1091 @Test
1092 public void create_select_model_coercion() throws Exception
1093 {
1094 openLinks("SelectModel coercion");
1095
1096 select("track", "label=The Calling");
1097
1098 clickAndWait(SUBMIT);
1099
1100 assertTextPresent("Selected track: The Calling, Synaesthetic");
1101 }
1102
1103 @Test
1104 public void validation_macro() throws Exception
1105 {
1106 openLinks("Validator Macro Demo");
1107
1108 clickAndWait(SUBMIT);
1109
1110 assertTextPresent("You must provide a value for Password.");
1111 assertTextPresent("You must provide a value for Password2.");
1112
1113 type("password", "abcdefg");
1114 type("password2", "x");
1115
1116 clickAndWait(SUBMIT);
1117
1118 assertTextPresent("You may provide at most 3 characters for Password.");
1119 assertTextPresent("You must provide at least 2 characters for Password2.");
1120
1121 type("password", "a");
1122 type("password2", "wxyz");
1123
1124 clickAndWait(SUBMIT);
1125
1126 assertTextPresent("You must provide at least 2 characters for Password.");
1127 assertTextPresent("You may provide at most 3 characters for Password2.");
1128
1129 type("password", "ab");
1130 type("password2", "xyz");
1131
1132 clickAndWait(SUBMIT);
1133
1134 assertTextPresent("Password: ab");
1135 assertTextPresent("Password2: xyz");
1136 }
1137
1138 @Test
1139 public void checklist_select() throws Exception
1140 {
1141 openLinks("Checklist Demo");
1142
1143 clickAndWait(SUBMIT);
1144 assertTextPresent("You must provide a value for Color.");
1145
1146 check("//input[@value='Green']");
1147
1148 clickAndWait(SUBMIT);
1149
1150 assertTextPresent("Selected colors: [Green]");
1151
1152 check("//input[@value='Red']");
1153
1154 clickAndWait(SUBMIT);
1155
1156 assertTextPresent("Selected colors: [Green, Red]");
1157
1158 check("//input[@value='Blue']");
1159 uncheck("//input[@value='Green']");
1160
1161 clickAndWait(SUBMIT);
1162
1163 assertTextPresent("Selected colors: [Blue, Red]");
1164 }
1165
1166 @Test
1167 public void checkFormLinkParameters() throws Exception
1168 {
1169 openLinks("FormLinkParameters Demo");
1170 assertAttribute("//input[@name='myparam']/@value", "!@#$%^&*()_+=");
1171
1172 clickAndWait("link=SetValue");
1173 assertTextPresent("Result = '!@#$%^&*()_+='");
1174
1175 clickAndWait(SUBMIT);
1176 assertTextPresent("Result = '!@#$%^&*()_+='");
1177 }
1178
1179 /**
1180 * TAP5-2223.
1181 */
1182 @Test
1183 public void optionGroup_form()
1184 {
1185 openLinks("OptionGroupForm Demo");
1186
1187 assertTextPresent("entity.id: [1]");
1188
1189 select("entity", "label2");
1190
1191 clickAndWait(SUBMIT);
1192
1193 assertTextPresent("entity.id: [2]");
1194 }
1195
1196 /** TAP5-2331 */
1197 @Test
1198 public void form_fields_client_id_parameter()
1199 {
1200 final String[] clientIds = {"clientId-0", "clientId-1"};
1201
1202 openLinks("Form Field clientId Parameter Demo");
1203
1204 for (int i = 0; i < 4; i++) {
1205
1206 for (String clientId : clientIds)
1207 {
1208 assertTrue(selenium.isElementPresent(clientId));
1209 }
1210
1211 click("updateZone");
1212 waitForAjaxRequestsToComplete();
1213
1214 }
1215
1216 }
1217
1218 /** TAP5-2301 */
1219 @Test
1220 public void select_context() {
1221
1222 openLinks("MultiZone Update inside a Form");
1223 selenium.select("selectValue1", "label=3 pre ajax");
1224 waitForAjaxRequestsToComplete();
1225 assertEquals(
1226 "4 post ajax, number 013, retention policy RUNTIME",
1227 selenium.getText("//select[@id='selectValue2']/option"));
1228
1229 }
1230
1231 /** TAP5-1815. In this webapp, HTML5 support is disabled, so we check whether it actually is disabled */
1232 @Test
1233 public void html5_support_disabled() throws Exception
1234 {
1235 openLinks("ValidForm");
1236 assertEquals("text", getAttribute("emailValidator@type")); // if HTML5 support was enabled, this would be "email"
1237 }
1238
1239 /** TAP5-736 **/
1240 @Test
1241 public void textfield_requires_non_null_validate_parameter() throws Exception
1242 {
1243 openLinks("TextField with null validate parameter");
1244 if(isTextPresent("java.lang.NullPointerException")){
1245 reportAndThrowAssertionError("Unexpected NullPointerException was thrown");
1246 }
1247 assertTextPresent("This parameter is not allowed to be null.");
1248 }
1249
1250 /** TAP5-2467 **/
1251 @Test
1252 public void validate_in_error_event() {
1253 openLinks("Validate in error Event");
1254
1255 click(SUBMIT);
1256
1257 waitForElementToAppear("validate-in-error");
1258
1259 assertTextPresent("Validate in error");
1260 }
1261
1262 // TAP5-2204
1263 @Test
1264 public void select_model_with_auto_security_and_non_persistent_model() throws Exception
1265 {
1266 openLinks("Select Demo");
1267
1268 select("month", "label=August");
1269
1270 clickAndWait(SUBMIT);
1271
1272 assertTextPresent("Selected month: August");
1273 }
1274 }