View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.html;
16  
17  import org.htmlunit.WebDriverTestCase;
18  import org.htmlunit.junit.BrowserRunner;
19  import org.htmlunit.junit.annotation.Alerts;
20  import org.junit.Test;
21  import org.junit.runner.RunWith;
22  import org.openqa.selenium.By;
23  import org.openqa.selenium.WebDriver;
24  import org.openqa.selenium.WebElement;
25  import org.openqa.selenium.htmlunit.HtmlUnitDriver;
26  
27  /**
28   * Tests for {@link HtmlTextArea}.
29   *
30   * @author Ronald Brill
31   * @author Ahmed Ashour
32   */
33  @RunWith(BrowserRunner.class)
34  public class HtmlTextArea2Test extends WebDriverTestCase {
35  
36      /**
37       * @throws Exception if the test fails
38       */
39      @Test
40      @Alerts({"-", "-", "newValue-", "newValue-", "newValue-newDefault", "newValue-newDefault"})
41      public void resetByClick() throws Exception {
42          final String html = DOCTYPE_HTML
43              + "<html><head>\n"
44              + "<script>\n"
45              + LOG_TITLE_FUNCTION
46              + "  function test() {\n"
47              + "    var text = document.getElementById('testId');\n"
48              + "    log(text.value + '-' + text.defaultValue);\n"
49  
50              + "    document.getElementById('testReset').click;\n"
51              + "    log(text.value + '-' + text.defaultValue);\n"
52  
53              + "    text.value = 'newValue';\n"
54              + "    log(text.value + '-' + text.defaultValue);\n"
55  
56              + "    document.getElementById('testReset').click;\n"
57              + "    log(text.value + '-' + text.defaultValue);\n"
58  
59              + "    text.defaultValue = 'newDefault';\n"
60              + "    log(text.value + '-' + text.defaultValue);\n"
61  
62              + "    document.forms[0].reset;\n"
63              + "    log(text.value + '-' + text.defaultValue);\n"
64              + "  }\n"
65              + "</script>\n"
66              + "</head><body onload='test()'>\n"
67              + "<form>\n"
68              + "  <textarea id='testId' value='initial'></textarea>\n"
69              + "  <input type='reset' id='testReset'>\n"
70              + "</form>\n"
71              + "</body></html>";
72  
73          loadPageVerifyTitle2(html);
74      }
75  
76      /**
77       * @throws Exception if the test fails
78       */
79      @Test
80      @Alerts({"-", "-", "newValue-", "newValue-", "newValue-newDefault", "newValue-newDefault"})
81      public void resetByJS() throws Exception {
82          final String html = DOCTYPE_HTML
83              + "<html><head>\n"
84              + "<script>\n"
85              + LOG_TITLE_FUNCTION
86              + "  function test() {\n"
87              + "    var text = document.getElementById('testId');\n"
88              + "    log(text.value + '-' + text.defaultValue);\n"
89  
90              + "    document.forms[0].reset;\n"
91              + "    log(text.value + '-' + text.defaultValue);\n"
92  
93              + "    text.value = 'newValue';\n"
94              + "    log(text.value + '-' + text.defaultValue);\n"
95  
96              + "    document.forms[0].reset;\n"
97              + "    log(text.value + '-' + text.defaultValue);\n"
98  
99              + "    text.defaultValue = 'newDefault';\n"
100             + "    log(text.value + '-' + text.defaultValue);\n"
101 
102             + "    document.forms[0].reset;\n"
103             + "    log(text.value + '-' + text.defaultValue);\n"
104             + "  }\n"
105             + "</script>\n"
106             + "</head><body onload='test()'>\n"
107             + "<form>\n"
108             + "  <textarea id='testId' value='initial'></textarea>\n"
109             + "</form>\n"
110             + "</body></html>";
111 
112         loadPageVerifyTitle2(html);
113     }
114 
115     /**
116      * @throws Exception if the test fails
117      */
118     @Test
119     @Alerts({"-", "default-default", "some text-default", "some text-newdefault"})
120     public void defaultValue() throws Exception {
121         final String html = DOCTYPE_HTML
122             + "<html><head>\n"
123             + "<script>\n"
124             + LOG_TITLE_FUNCTION
125             + "  function test() {\n"
126             + "    var text = document.getElementById('testId');\n"
127             + "    log(text.value + '-' + text.defaultValue);\n"
128 
129             + "    text.defaultValue = 'default';\n"
130             + "    log(text.value + '-' + text.defaultValue);\n"
131 
132             + "    text.value = 'some text';\n"
133             + "    log(text.value + '-' + text.defaultValue);\n"
134             + "    text.defaultValue = 'newdefault';\n"
135             + "    log(text.value + '-' + text.defaultValue);\n"
136             + "  }\n"
137             + "</script>\n"
138             + "</head><body onload='test()'>\n"
139             + "<form>\n"
140             + "  <textarea id='testId' value='initial'></textarea>\n"
141             + "</form>\n"
142             + "</body></html>";
143 
144         loadPageVerifyTitle2(html);
145     }
146 
147     /**
148      * @throws Exception if the test fails
149      */
150     @Test
151     @Alerts("\\sfoo\\s\\n\\sbar\\n\\stest\\n\\sa\\s<p>html\\ssnippet</p>\\n")
152     public void defaultValue2() throws Exception {
153         final String html = DOCTYPE_HTML
154             + "<html><head>\n"
155             + "<script>\n"
156             + LOG_TITLE_FUNCTION_NORMALIZE
157             + "  function test() {\n"
158             + "    log(document.getElementById('textArea1').defaultValue);\n"
159             + "  }\n"
160             + "</script>\n"
161             + "</head><body onload='test()'>\n"
162             + "<form id='form1'>\n"
163             + "<textarea id='textArea1'> foo \n bar\r\n test\r a "
164             + "<p>html snippet</p>\n"
165             + "</textarea>\n"
166             + "</form></body></html>";
167 
168         loadPageVerifyTitle2(html);
169     }
170 
171     /**
172      * @throws Exception if the test fails
173      */
174     @Test
175     @Alerts("7")
176     public void textLength() throws Exception {
177         final String html = DOCTYPE_HTML
178             + "<html><head>\n"
179             + "<script>\n"
180             + LOG_TITLE_FUNCTION
181             + "  function test() {\n"
182             + "    var text = document.getElementById('testId');\n"
183             + "    if(text.textLength) {\n"
184             + "      log(text.textLength);\n"
185             + "    } else {\n"
186             + "      log('textLength not available');\n"
187             + "    }\n"
188             + "  }\n"
189             + "</script>\n"
190             + "</head><body onload='test()'>\n"
191             + "<form>\n"
192             + "  <textarea id='testId'>initial</textarea>\n"
193             + "</form>\n"
194             + "</body></html>";
195 
196         loadPageVerifyTitle2(html);
197     }
198 
199     /**
200      * @throws Exception if an error occurs
201      */
202     @Test
203     @Alerts("0")
204     public void selection() throws Exception {
205         final String html = DOCTYPE_HTML
206             + "<html><head><script>\n"
207             + LOG_TITLE_FUNCTION
208             + "  function test() {\n"
209             + "    log(getSelection(document.getElementById('text1')).length);\n"
210             + "  }\n"
211             + "  function getSelection(element) {\n"
212             + "    return element.value.substring(element.selectionStart, element.selectionEnd);\n"
213             + "  }\n"
214             + "</script></head>\n"
215             + "<body onload='test()'>\n"
216             + "  <textarea id='text1'></textarea>\n"
217             + "</body></html>";
218 
219         loadPageVerifyTitle2(html);
220     }
221 
222     /**
223      * @throws Exception if test fails
224      */
225     @Test
226     @Alerts({"0,0", "11,11", "3,11", "3,10"})
227     public void selection2_1() throws Exception {
228         selection2(3, 10);
229     }
230 
231     /**
232      * @throws Exception if test fails
233      */
234     @Test
235     @Alerts({"0,0", "11,11", "11,11", "11,11"})
236     public void selection2_2() throws Exception {
237         selection2(-3, 15);
238     }
239 
240     /**
241      * @throws Exception if test fails
242      */
243     @Test
244     @Alerts({"0,0", "11,11", "10,11", "5,5"})
245     public void selection2_3() throws Exception {
246         selection2(10, 5);
247     }
248 
249     private void selection2(final int selectionStart, final int selectionEnd) throws Exception {
250         final String html = DOCTYPE_HTML
251             + "<html>\n"
252             + "<body>\n"
253             + "<textarea id='myTextInput'>Bonjour</textarea>\n"
254             + "<script>\n"
255             + LOG_TITLE_FUNCTION
256             + "  var input = document.getElementById('myTextInput');\n"
257             + "  log(input.selectionStart + ',' + input.selectionEnd);\n"
258             + "  input.value = 'Hello there';\n"
259             + "  log(input.selectionStart + ',' + input.selectionEnd);\n"
260             + "  input.selectionStart = " + selectionStart + ";\n"
261             + "  log(input.selectionStart + ',' + input.selectionEnd);\n"
262             + "  input.selectionEnd = " + selectionEnd + ";\n"
263             + "  log(input.selectionStart + ',' + input.selectionEnd);\n"
264             + "</script>\n"
265             + "</body>\n"
266             + "</html>";
267 
268         loadPageVerifyTitle2(html);
269     }
270 
271     /**
272      * @throws Exception if test fails
273      */
274     @Test
275     @Alerts({"0,0", "4,5", "10,10", "4,4", "1,1"})
276     public void selectionOnUpdate() throws Exception {
277         final String html = DOCTYPE_HTML
278             + "<html>\n"
279             + "<body>\n"
280             + "<textarea id='myTextInput'>Hello</textarea>\n"
281             + "<script>\n"
282             + LOG_TITLE_FUNCTION
283             + "  var input = document.getElementById('myTextInput');\n"
284             + "  log(input.selectionStart + ',' + input.selectionEnd);\n"
285 
286             + "  input.selectionStart = 4;\n"
287             + "  input.selectionEnd = 5;\n"
288             + "  log(input.selectionStart + ',' + input.selectionEnd);\n"
289             + "  input.value = 'abcdefghif';\n"
290             + "  log(input.selectionStart + ',' + input.selectionEnd);\n"
291 
292             + "  input.value = 'abcd';\n"
293             + "  log(input.selectionStart + ',' + input.selectionEnd);\n"
294 
295             + "  input.selectionStart = 0;\n"
296             + "  input.selectionEnd = 4;\n"
297 
298             + "  input.value = 'a';\n"
299             + "  log(input.selectionStart + ',' + input.selectionEnd);\n"
300             + "</script>\n"
301             + "</body>\n"
302             + "</html>";
303 
304         loadPageVerifyTitle2(html);
305     }
306 
307     /**
308      * @throws Exception if the test fails
309      */
310     @Test
311     @Alerts(" foo \n bar\n test\n a <p>html snippet</p>")
312     public void getVisibleText() throws Exception {
313         final String html = DOCTYPE_HTML
314             + "<html><head><title>foo</title></head><body>\n"
315             + "<form id='form1'>\n"
316             + "<textarea id='tester'> foo \n bar\r\n test\r a "
317             + "<p>html snippet</p>\n"
318             + "</textarea>\n"
319             + "</form></body></html>";
320 
321         final WebDriver driver = loadPage2(html);
322         final String text = driver.findElement(By.id("tester")).getText();
323         assertEquals(getExpectedAlerts()[0], text);
324 
325         if (driver instanceof HtmlUnitDriver) {
326             final HtmlPage page = (HtmlPage) getEnclosedPage();
327             assertEquals(getExpectedAlerts()[0], page.getElementById("tester").getVisibleText());
328         }
329     }
330 
331     /**
332      * @throws Exception if the test fails
333      */
334     @Test
335     @Alerts("Hello World")
336     public void getVisibleTextValueChangedWithTyping() throws Exception {
337         final String html = DOCTYPE_HTML
338             + "<html>"
339             + "<head></head>\n"
340             + "<body>\n"
341             + "<form id='form1'>\n"
342             + "<textarea id='tester'>Hello World</textarea>\n"
343             + "</form>\n"
344             + "</body></html>";
345 
346         final WebDriver driver = loadPage2(html);
347         final WebElement textArea = driver.findElement(By.id("tester"));
348         textArea.sendKeys("HtmlUnit");
349         final String text = textArea.getText();
350         assertEquals(getExpectedAlerts()[0], text);
351 
352         if (driver instanceof HtmlUnitDriver) {
353             final HtmlPage page = (HtmlPage) getEnclosedPage();
354             assertEquals(getExpectedAlerts()[0], page.getElementById("tester").getVisibleText());
355         }
356     }
357 
358     /**
359      * @throws Exception if the test fails
360      */
361     @Test
362     @Alerts("Hello World")
363     public void getVisibleTextValueChangedFromJs() throws Exception {
364         final String html = DOCTYPE_HTML
365             + "<html>"
366             + "<head>\n"
367             + "<script>\n"
368             + "  function test() {\n"
369             + "    document.getElementById('tester').value = 'HtmlUnit';\n"
370             + "  }\n"
371             + "</script>\n"
372             + "</head>\n"
373             + "<body onload='test()'>\n"
374             + "<form id='form1'>\n"
375             + "<textarea id='tester'>Hello World</textarea>\n"
376             + "</form>\n"
377             + "</body></html>";
378 
379         final WebDriver driver = loadPage2(html);
380         final String text = driver.findElement(By.id("tester")).getText();
381         assertEquals(getExpectedAlerts()[0], text);
382 
383         if (driver instanceof HtmlUnitDriver) {
384             final HtmlPage page = (HtmlPage) getEnclosedPage();
385             assertEquals(getExpectedAlerts()[0], page.getElementById("tester").getVisibleText());
386         }
387     }
388 
389     /**
390      * @throws Exception if the test fails
391      */
392     @Test
393     @Alerts("")
394     public void getVisibleTextAndVisibility() throws Exception {
395         final String html = DOCTYPE_HTML
396             + "<html><head></head><body>\n"
397             + "<form id='form1'>\n"
398             + "<textarea id='tester' style='visibility:hidden'> foo \n bar "
399             + "</textarea>\n"
400             + "</form></body></html>";
401         final WebDriver driver = loadPage2(html);
402         final WebElement textArea = driver.findElement(By.id("tester"));
403         assertEquals(getExpectedAlerts()[0], textArea.getText());
404 
405         if (driver instanceof HtmlUnitDriver) {
406             final HtmlPage page = (HtmlPage) getEnclosedPage();
407             assertEquals(getExpectedAlerts()[0], page.getElementById("tester").getVisibleText());
408         }
409     }
410 
411     /**
412      * @throws Exception if the test fails
413      */
414     @Test
415     @Alerts(" foo \n bar <p>html snippet</p>")
416     public void parentAsText() throws Exception {
417         final String html = DOCTYPE_HTML
418             + "<html><head><title>foo</title></head><body>\n"
419             + "<form id='form1'>\n"
420             + "<textarea name='textArea1'> foo \n bar "
421             + "<p>html snippet</p>\n"
422             + "</textarea>\n"
423             + "</form></body></html>";
424 
425         final WebDriver driver = loadPage2(html);
426         final WebElement textArea = driver.findElement(By.id("form1"));
427         assertEquals(getExpectedAlerts()[0], textArea.getText());
428     }
429 
430     /**
431      * @throws Exception if test fails
432      */
433     @Test
434     @Alerts({"1", "a", "", "b", "<!--comment-->2", "c", "<!--comment-->", "d"})
435     public void textUpdate() throws Exception {
436         final String html = DOCTYPE_HTML
437             + "<html>\n"
438             + "<body>\n"
439             + "<textarea id='myText'>1</textarea>\n"
440             + "<textarea id='myTextEmpty'></textarea>\n"
441             + "<textarea id='myTextComment'><!--comment-->2</textarea>\n"
442             + "<textarea id='myTextCommentOnly'><!--comment--></textarea>\n"
443             + "<script>\n"
444             + LOG_TITLE_FUNCTION
445             + "  var text = document.getElementById('myText');\n"
446             + "  log(text.value);\n"
447             + "  text.value = 'a';\n"
448             + "  log(text.value);\n"
449 
450             + "  text = document.getElementById('myTextEmpty');\n"
451             + "  log(text.value);\n"
452             + "  text.value = 'b';\n"
453             + "  log(text.value);\n"
454 
455             + "  text = document.getElementById('myTextComment');\n"
456             + "  log(text.value);\n"
457             + "  text.value = 'c';\n"
458             + "  log(text.value);\n"
459 
460             + "  text = document.getElementById('myTextCommentOnly');\n"
461             + "  log(text.value);\n"
462             + "  text.value = 'd';\n"
463             + "  log(text.value);\n"
464 
465             + "</script>\n"
466             + "</body>\n"
467             + "</html>";
468 
469         loadPageVerifyTitle2(html);
470     }
471 
472     /**
473      * @throws Exception if test fails
474      */
475     @Test
476     @Alerts({"", "xyz", "1", "a", "1"})
477     public void textUpdateFromJSText() throws Exception {
478         final String html = DOCTYPE_HTML
479             + "<html>\n"
480             + "<body>\n"
481             + "<textarea id='myText'></textarea>\n"
482             + "<script>\n"
483             + LOG_TITLE_FUNCTION
484             + "  var text = document.getElementById('myText');\n"
485             + "  log(text.value);\n"
486 
487             + "  var txt = document.createTextNode('xyz');\n"
488             + "  text.appendChild(txt);\n"
489             + "  log(text.value);\n"
490             + "  log(text.childNodes.length);\n"
491 
492             + "  text.value = 'a';\n"
493             + "  log(text.value);\n"
494             + "  log(text.childNodes.length);\n"
495             + "</script>\n"
496             + "</body>\n"
497             + "</html>";
498 
499         loadPageVerifyTitle2(html);
500     }
501 
502     /**
503      * @throws Exception if test fails
504      */
505     @Test
506     @Alerts({"", "", "1", "a", "1"})
507     public void textUpdateFromJSSpan() throws Exception {
508         final String html = DOCTYPE_HTML
509             + "<html>\n"
510             + "<body>\n"
511             + "<textarea id='myText'></textarea>\n"
512             + "<script>\n"
513             + LOG_TITLE_FUNCTION
514             + "  var text = document.getElementById('myText');\n"
515             + "  log(text.value);\n"
516 
517             + "  var span = document.createElement('span');\n"
518             + "  span.innerHTML = '123';\n"
519             + "  text.appendChild(span);\n"
520             + "  log(text.value);\n"
521             + "  log(text.childNodes.length);\n"
522 
523             + "  text.value = 'a';\n"
524             + "  log(text.value);\n"
525             + "  log(text.childNodes.length);\n"
526             + "</script>\n"
527             + "</body>\n"
528             + "</html>";
529 
530         loadPageVerifyTitle2(html);
531     }
532 
533     /**
534      * @throws Exception if test fails
535      */
536     @Test
537     @Alerts({"", "", "1", "xyz", "2", "a", "2"})
538     public void textUpdateFromJSSpanAndText() throws Exception {
539         final String html = DOCTYPE_HTML
540             + "<html>\n"
541             + "<body>\n"
542             + "<textarea id='myText'></textarea>\n"
543             + "<script>\n"
544             + LOG_TITLE_FUNCTION
545             + "  var text = document.getElementById('myText');\n"
546             + "  log(text.value);\n"
547 
548             + "  var span = document.createElement('span');\n"
549             + "  span.innerHTML = '123';\n"
550             + "  text.appendChild(span);\n"
551             + "  log(text.value);\n"
552             + "  log(text.childNodes.length);\n"
553 
554             + "  var txt = document.createTextNode('xyz');\n"
555             + "  text.appendChild(txt);\n"
556             + "  log(text.value);\n"
557             + "  log(text.childNodes.length);\n"
558 
559             + "  text.value = 'a';\n"
560             + "  log(text.value);\n"
561             + "  log(text.childNodes.length);\n"
562             + "</script>\n"
563             + "</body>\n"
564             + "</html>";
565 
566         loadPageVerifyTitle2(html);
567     }
568 
569     /**
570      * @throws Exception if test fails
571      */
572     @Test
573     @Alerts({"", "", "1", "a", "1"})
574     public void textUpdateFromJSComment() throws Exception {
575         final String html = DOCTYPE_HTML
576             + "<html>\n"
577             + "<body>\n"
578             + "<textarea id='myText'></textarea>\n"
579             + "<script>\n"
580             + LOG_TITLE_FUNCTION
581             + "  var text = document.getElementById('myText');\n"
582             + "  log(text.value);\n"
583 
584             + "  var comment = document.createComment('comment');\n"
585             + "  text.appendChild(comment);\n"
586             + "  log(text.value);\n"
587             + "  log(text.childNodes.length);\n"
588 
589             + "  text.value = 'a';\n"
590             + "  log(text.value);\n"
591             + "  log(text.childNodes.length);\n"
592             + "</script>\n"
593             + "</body>\n"
594             + "</html>";
595 
596         loadPageVerifyTitle2(html);
597     }
598 
599     /**
600      * @throws Exception if an error occurs
601      */
602     @Test
603     @Alerts({"0", "2", "1", "2", "1", "1"})
604     public void labels() throws Exception {
605         final String html = DOCTYPE_HTML
606             + "<html><head>\n"
607             + "<script>\n"
608             + LOG_TITLE_FUNCTION
609             + "  function test() {\n"
610             + "    debug(document.getElementById('e1'));\n"
611             + "    debug(document.getElementById('e2'));\n"
612             + "    debug(document.getElementById('e3'));\n"
613             + "    debug(document.getElementById('e4'));\n"
614             + "    var labels = document.getElementById('e4').labels;\n"
615             + "    document.body.removeChild(document.getElementById('l4'));\n"
616             + "    debug(document.getElementById('e4'));\n"
617             + "    log(labels ? labels.length : labels);\n"
618             + "  }\n"
619             + "  function debug(e) {\n"
620             + "    log(e.labels ? e.labels.length : e.labels);\n"
621             + "  }\n"
622             + "</script>\n"
623             + "</head>\n"
624             + "<body onload='test()'>\n"
625             + "  <textarea id='e1'>e 1</textarea><br>\n"
626             + "  <label>something <label> click here <textarea id='e2'>e 2</textarea></label></label><br>\n"
627             + "  <label for='e3'> and here</label>\n"
628             + "  <textarea id='e3'>e 3</textarea><br>\n"
629             + "  <label id='l4' for='e4'> what about</label>\n"
630             + "  <label> this<textarea id='e4'>e 4</textarea></label><br>\n"
631             + "</body></html>";
632 
633         loadPageVerifyTitle2(html);
634     }
635 
636     /**
637      * @throws Exception if an error occurs
638      */
639     @Test
640     @Alerts({"true", "false", "true", "false", "true"})
641     public void willValidate() throws Exception {
642         final String html = DOCTYPE_HTML
643                 + "<html><head>\n"
644                 + "  <script>\n"
645                 + LOG_TITLE_FUNCTION
646                 + "    function test() {\n"
647                 + "      log(document.getElementById('t1').willValidate);\n"
648                 + "      log(document.getElementById('t2').willValidate);\n"
649                 + "      log(document.getElementById('t3').willValidate);\n"
650                 + "      log(document.getElementById('t4').willValidate);\n"
651                 + "      log(document.getElementById('t5').willValidate);\n"
652                 + "    }\n"
653                 + "  </script>\n"
654                 + "</head>\n"
655                 + "<body onload='test()'>\n"
656                 + "  <form>\n"
657                 + "    <textarea id='t1'>t1</textarea>\n"
658                 + "    <textarea id='t2' disabled>t2</textarea>\n"
659                 + "    <textarea id='t3' hidden>t3</textarea>\n"
660                 + "    <textarea id='t4' readonly>t4</textarea>\n"
661                 + "    <textarea id='t5' style='display: none'>t5</textarea>\n"
662                 + "  </form>\n"
663                 + "</body></html>";
664 
665         loadPageVerifyTitle2(html);
666     }
667 
668     /**
669      * @throws Exception if an error occurs
670      */
671     @Test
672     @Alerts({"true",
673              "false-false-false-false-false-false-false-false-false-true-false",
674              "true"})
675     public void validationEmpty() throws Exception {
676         validation("<textarea id='e1'>t1</textarea>\n", "");
677     }
678 
679     /**
680      * @throws Exception if an error occurs
681      */
682     @Test
683     @Alerts({"false",
684              "false-true-false-false-false-false-false-false-false-false-false",
685              "true"})
686     public void validationCustomValidity() throws Exception {
687         validation("<textarea id='e1'>t1</textarea>\n", "elem.setCustomValidity('Invalid');");
688     }
689 
690     /**
691      * @throws Exception if an error occurs
692      */
693     @Test
694     @Alerts({"false",
695              "false-true-false-false-false-false-false-false-false-false-false",
696              "true"})
697     public void validationBlankCustomValidity() throws Exception {
698         validation("<textarea id='e1'>t1</textarea>\n", "elem.setCustomValidity(' ');\n");
699     }
700 
701     /**
702      * @throws Exception if an error occurs
703      */
704     @Test
705     @Alerts({"true",
706              "false-false-false-false-false-false-false-false-false-true-false",
707              "true"})
708     public void validationResetCustomValidity() throws Exception {
709         validation("<textarea id='e1'>t1</textarea>\n",
710                 "elem.setCustomValidity('Invalid');elem.setCustomValidity('');");
711     }
712 
713     /**
714      * @throws Exception if an error occurs
715      */
716     @Test
717     @Alerts({"false",
718              "false-false-false-false-false-false-false-false-false-false-true",
719              "true"})
720     public void validationRequired() throws Exception {
721         validation("<textarea id='e1' required></textarea>\n", "");
722     }
723 
724     /**
725      * @throws Exception if an error occurs
726      */
727     @Test
728     @Alerts({"true",
729              "false-false-false-false-false-false-false-false-false-true-false",
730              "true"})
731     public void validationRequiredWithText() throws Exception {
732         validation("<textarea id='e1' required>HtmlUnit</textarea>\n", "");
733     }
734 
735     /**
736      * @throws Exception if an error occurs
737      */
738     @Test
739     @Alerts({"true",
740              "false-false-false-false-false-false-false-false-false-true-false",
741              "true"})
742     public void validationRequiredValueSet() throws Exception {
743         validation("<textarea id='e1' required></textarea>\n", "elem.value='A';");
744     }
745 
746     /**
747      * @throws Exception if an error occurs
748      */
749     @Test
750     @Alerts({"false",
751              "false-false-false-false-false-false-false-false-false-false-true",
752              "true"})
753     public void validationRequiredValueClear() throws Exception {
754         validation("<textarea id='e1' required>abc</textarea>\n", "elem.value='';");
755     }
756 
757     private void validation(final String htmlPart, final String jsPart) throws Exception {
758         final String html = DOCTYPE_HTML
759                 + "<html><head>\n"
760                 + "  <script>\n"
761                 + LOG_TITLE_FUNCTION
762                 + "    function logValidityState(s) {\n"
763                 + "      log(s.badInput"
764                         + "+ '-' + s.customError"
765                         + "+ '-' + s.patternMismatch"
766                         + "+ '-' + s.rangeOverflow"
767                         + "+ '-' + s.rangeUnderflow"
768                         + "+ '-' + s.stepMismatch"
769                         + "+ '-' + s.tooLong"
770                         + "+ '-' + s.tooShort"
771                         + " + '-' + s.typeMismatch"
772                         + " + '-' + s.valid"
773                         + " + '-' + s.valueMissing);\n"
774                 + "    }\n"
775                 + "    function test() {\n"
776                 + "      var elem = document.getElementById('e1');\n"
777                 + jsPart
778                 + "      log(elem.checkValidity());\n"
779                 + "      logValidityState(elem.validity);\n"
780                 + "      log(elem.willValidate);\n"
781                 + "    }\n"
782                 + "  </script>\n"
783                 + "</head>\n"
784                 + "<body onload='test()'>\n"
785                 + "  <form>\n"
786                 + htmlPart
787                 + "  </form>\n"
788                 + "</body></html>";
789 
790         loadPageVerifyTitle2(html);
791     }
792 }