1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.html;
16
17 import org.htmlunit.WebDriverTestCase;
18 import org.htmlunit.junit.annotation.Alerts;
19 import org.junit.jupiter.api.Test;
20 import org.openqa.selenium.By;
21 import org.openqa.selenium.Keys;
22 import org.openqa.selenium.WebDriver;
23 import org.openqa.selenium.WebElement;
24 import org.openqa.selenium.htmlunit.HtmlUnitDriver;
25
26
27
28
29
30
31
32
33 public class HtmlSearchInputTest extends WebDriverTestCase {
34
35
36
37
38 @Test
39 public void type() throws Exception {
40 final String html = DOCTYPE_HTML + "<html><head></head><body><input id='t' type='search'/></body></html>";
41
42 final WebDriver webDriver = loadPage2(html);
43 final WebElement input = webDriver.findElement(By.id("t"));
44
45 input.sendKeys("abc");
46 assertNull(input.getDomAttribute("value"));
47 assertEquals("abc", input.getDomProperty("value"));
48
49 input.sendKeys(Keys.BACK_SPACE);
50 assertNull(input.getDomAttribute("value"));
51 assertEquals("ab", input.getDomProperty("value"));
52
53 input.sendKeys(Keys.BACK_SPACE);
54 assertNull(input.getDomAttribute("value"));
55 assertEquals("a", input.getDomProperty("value"));
56
57 input.sendKeys(Keys.BACK_SPACE);
58 assertNull(input.getDomAttribute("value"));
59 assertEquals("", input.getDomProperty("value"));
60
61 input.sendKeys(Keys.BACK_SPACE);
62 assertNull(input.getDomAttribute("value"));
63 assertEquals("", input.getDomProperty("value"));
64 }
65
66
67
68
69 @Test
70 @Alerts({"--null", "--null", "--null"})
71 public void defaultValuesAfterClone() throws Exception {
72 final String html = DOCTYPE_HTML
73 + "<html><head>\n"
74 + "<script>\n"
75 + LOG_TITLE_FUNCTION
76 + " function test() {\n"
77 + " var input = document.getElementById('text1');\n"
78 + " input = input.cloneNode(false);\n"
79 + " log(input.value + '-' + input.defaultValue + '-' + input.getAttribute('value'));\n"
80
81 + " try {\n"
82 + " input = document.createElement('input');\n"
83 + " input.type = 'search';\n"
84 + " input = input.cloneNode(false);\n"
85 + " log(input.value + '-' + input.defaultValue + '-' + input.getAttribute('value'));\n"
86 + " } catch(e) { logEx(e); }\n"
87
88 + " var builder = document.createElement('div');\n"
89 + " builder.innerHTML = '<input type=\"search\">';\n"
90 + " input = builder.firstChild;\n"
91 + " input = input.cloneNode(false);\n"
92 + " log(input.value + '-' + input.defaultValue + '-' + input.getAttribute('value'));\n"
93 + " }\n"
94 + "</script>\n"
95 + "</head><body onload='test()'>\n"
96 + "<form>\n"
97 + " <input type='search' id='text1'>\n"
98 + "</form>\n"
99 + "</body></html>";
100
101 loadPageVerifyTitle2(html);
102 }
103
104
105
106
107
108 @Test
109 @Alerts("")
110 public void getVisibleText() throws Exception {
111 final String htmlContent = DOCTYPE_HTML
112 + "<html>\n"
113 + "<head></head>\n"
114 + "<body>\n"
115 + "<form id='form1'>\n"
116 + " <input type='search' name='tester' id='tester' value='1234567' >\n"
117 + "</form>\n"
118 + "</body></html>";
119
120 final WebDriver driver = loadPage2(htmlContent);
121 final String text = driver.findElement(By.id("tester")).getText();
122 assertEquals(getExpectedAlerts()[0], text);
123
124 if (driver instanceof HtmlUnitDriver) {
125 final HtmlPage page = (HtmlPage) getEnclosedPage();
126 assertEquals(getExpectedAlerts()[0], page.getBody().getVisibleText());
127 }
128 }
129
130
131
132
133
134 @Test
135 @Alerts({"1234567", ""})
136 public void clearInput() throws Exception {
137 final String htmlContent = DOCTYPE_HTML
138 + "<html>\n"
139 + "<head></head>\n"
140 + "<body>\n"
141 + "<form id='form1'>\n"
142 + " <input type='search' name='tester' id='tester' value='1234567'>\n"
143 + "</form>\n"
144 + "</body></html>";
145
146 final WebDriver driver = loadPage2(htmlContent);
147 final WebElement element = driver.findElement(By.id("tester"));
148
149 assertEquals(getExpectedAlerts()[0], element.getDomAttribute("value"));
150 assertEquals(getExpectedAlerts()[0], element.getDomProperty("value"));
151
152 element.clear();
153 assertEquals(getExpectedAlerts()[0], element.getDomAttribute("value"));
154 assertEquals(getExpectedAlerts()[1], element.getDomProperty("value"));
155 }
156
157
158
159
160 @Test
161 public void typing() throws Exception {
162 final String htmlContent = DOCTYPE_HTML
163 + "<html><head><title>foo</title></head><body>\n"
164 + "<form id='form1'>\n"
165 + " <input type='search' id='foo'>\n"
166 + "</form></body></html>";
167
168 final WebDriver driver = loadPage2(htmlContent);
169
170 final WebElement input = driver.findElement(By.id("foo"));
171
172 input.sendKeys("hello");
173 assertNull(input.getDomAttribute("value"));
174 assertEquals("hello", input.getDomProperty("value"));
175 }
176
177
178
179
180 @Test
181 @Alerts("--")
182 public void minMaxStep() throws Exception {
183 final String html = DOCTYPE_HTML
184 + "<html>\n"
185 + "<head>\n"
186 + "<script>\n"
187 + LOG_TITLE_FUNCTION
188 + " function test() {\n"
189 + " var input = document.getElementById('tester');\n"
190 + " log(input.min + '-' + input.max + '-' + input.step);\n"
191 + " }\n"
192 + "</script>\n"
193 + "</head>\n"
194 + "<body onload='test()'>\n"
195 + "<form>\n"
196 + " <input type='search' id='tester'>\n"
197 + "</form>\n"
198 + "</body>\n"
199 + "</html>";
200
201 loadPageVerifyTitle2(html);
202 }
203
204
205
206
207 @Test
208 @Alerts({"0987654321!",
209 "0987654321!",
210 "false",
211 "false-false-true-false-false-false-false-false-false-false-false",
212 "true",
213 "§§URL§§", "1"})
214 public void patternValidationInvalid() throws Exception {
215 validation("<input type='search' pattern='[0-9a-zA-Z]{10,40}' id='e1' value='0987654321!' name='k'>\n",
216 "", null);
217 }
218
219
220
221
222 @Test
223 @Alerts({"68746d6c756e69742072756c657a21",
224 "68746d6c756e69742072756c657a21",
225 "true",
226 "false-false-false-false-false-false-false-false-false-true-false",
227 "true",
228 "§§URL§§?k=68746d6c756e69742072756c657a21", "2"})
229 public void patternValidationValid() throws Exception {
230 validation("<input type='search' pattern='[0-9a-zA-Z]{10,40}' "
231 + "id='e1' value='68746d6c756e69742072756c657a21' name='k'>\n", "", null);
232 }
233
234
235
236
237 @Test
238 @Alerts({"",
239 "",
240 "true",
241 "false-false-false-false-false-false-false-false-false-true-false",
242 "true",
243 "§§URL§§?k=", "2"})
244 public void patternValidationEmpty() throws Exception {
245 validation("<input type='search' pattern='[0-9a-zA-Z]{10,40}' id='e1' value='' name='k'>\n", "", null);
246 }
247
248
249
250
251 @Test
252 @Alerts({" ",
253 " ",
254 "false",
255 "false-false-true-false-false-false-false-false-false-false-false",
256 "true",
257 "§§URL§§", "1"})
258 public void patternValidationBlank() throws Exception {
259 validation("<input type='search' pattern='[0-9a-zA-Z]{10,40}' id='e1' value=' ' name='k'>\n", "", null);
260 }
261
262
263
264
265 @Test
266 @Alerts({" \t",
267 " \t",
268 "false",
269 "false-false-true-false-false-false-false-false-false-false-false",
270 "true",
271 "§§URL§§", "1"})
272 public void patternValidationWhitespace() throws Exception {
273 validation("<input type='search' pattern='[0-9a-zA-Z]{10,40}' id='e1' value=' \t' name='k'>\n", "", null);
274 }
275
276
277
278
279 @Test
280 @Alerts({" 210 ",
281 " 210 ",
282 "true",
283 "false-false-false-false-false-false-false-false-false-true-false",
284 "true",
285 "§§URL§§?k=+210+", "2"})
286 public void patternValidationTrimInitial() throws Exception {
287 validation("<input type='search' pattern='[ 012]{3,10}' id='e1' name='k' value=' 210 '>\n", "", null);
288 }
289
290
291
292
293 @Test
294 @Alerts({"null",
295 " 210 ",
296 "true",
297 "false-false-false-false-false-false-false-false-false-true-false",
298 "true",
299 "§§URL§§?k=+210+", "2"})
300 public void patternValidationTrimType() throws Exception {
301 validation("<input type='search' pattern='[ 012]{3,10}' id='e1' name='k'>\n", "", " 210 ");
302 }
303
304
305
306
307 @Test
308 @Alerts({"null",
309 "abcd",
310 "false",
311 "false-false-false-false-false-false-false-true-false-false-false",
312 "true",
313 "§§URL§§", "1"})
314 public void minLengthValidationInvalid() throws Exception {
315 validation("<input type='search' minlength='5' id='e1' name='k'>\n", "", "abcd");
316 }
317
318
319
320
321 @Test
322 @Alerts({"1234",
323 "1234",
324 "true",
325 "false-false-false-false-false-false-false-false-false-true-false",
326 "true",
327 "§§URL§§?k=1234", "2"})
328 public void minLengthValidationInvalidInitial() throws Exception {
329 validation("<input type='search' minlength='20' id='e1' name='k' value='1234'>\n", "", null);
330 }
331
332
333
334
335 @Test
336 @Alerts({"null",
337 "",
338 "true",
339 "false-false-false-false-false-false-false-false-false-true-false",
340 "true",
341 "§§URL§§?k=", "2"})
342 public void minLengthValidationInvalidNoInitial() throws Exception {
343 validation("<input type='search' minlength='5' id='e1' name='k'>\n", "", null);
344 }
345
346
347
348
349 @Test
350 @Alerts({"null",
351 "abcdefghi",
352 "true",
353 "false-false-false-false-false-false-false-false-false-true-false",
354 "true",
355 "§§URL§§?k=abcdefghi", "2"})
356 public void minLengthValidationValid() throws Exception {
357 validation("<input type='search' minlength='5' id='e1' name='k'>\n", "", "abcdefghi");
358 }
359
360
361
362
363 @Test
364 @Alerts({"null",
365 "abcd",
366 "true",
367 "false-false-false-false-false-false-false-false-false-true-false",
368 "true",
369 "§§URL§§?k=abcd", "2"})
370 public void maxLengthValidationValid() throws Exception {
371 validation("<input type='search' maxlength='5' id='e1' name='k'>\n", "", "abcd");
372 }
373
374
375
376
377 @Test
378 @Alerts({"null",
379 "abcde",
380 "true",
381 "false-false-false-false-false-false-false-false-false-true-false",
382 "true",
383 "§§URL§§?k=abcde", "2"})
384 public void maxLengthValidationInvalid() throws Exception {
385 validation("<input type='search' maxlength='5' id='e1' name='k'>\n", "", "abcdefghi");
386 }
387
388
389
390
391 @Test
392 @Alerts({"abcdefghi",
393 "abcdefghi",
394 "true",
395 "false-false-false-false-false-false-false-false-false-true-false",
396 "true",
397 "§§URL§§?k=abcdefghi", "2"})
398 public void maxLengthValidationInvalidInitial() throws Exception {
399 validation("<input type='search' maxlength='5' id='e1' value='abcdefghi' name='k'>\n", "", null);
400 }
401
402
403
404
405 @Test
406 @Alerts({"true", "false", "true", "false", "true"})
407 public void willValidate() throws Exception {
408 final String html = DOCTYPE_HTML
409 + "<html><head>\n"
410 + " <script>\n"
411 + LOG_TITLE_FUNCTION
412 + " function test() {\n"
413 + " log(document.getElementById('o1').willValidate);\n"
414 + " log(document.getElementById('o2').willValidate);\n"
415 + " log(document.getElementById('o3').willValidate);\n"
416 + " log(document.getElementById('o4').willValidate);\n"
417 + " log(document.getElementById('o5').willValidate);\n"
418 + " }\n"
419 + " </script>\n"
420 + "</head>\n"
421 + "<body onload='test()'>\n"
422 + " <form>\n"
423 + " <input type='search' id='o1'>\n"
424 + " <input type='search' id='o2' disabled>\n"
425 + " <input type='search' id='o3' hidden>\n"
426 + " <input type='search' id='o4' readonly>\n"
427 + " <input type='search' id='o5' style='display: none'>\n"
428 + " </form>\n"
429 + "</body></html>";
430
431 loadPageVerifyTitle2(html);
432 }
433
434
435
436
437 @Test
438 @Alerts({"null",
439 "",
440 "true",
441 "false-false-false-false-false-false-false-false-false-true-false",
442 "true",
443 "§§URL§§?k=", "2"})
444 public void validationEmpty() throws Exception {
445 validation("<input type='search' id='e1' name='k'>\n", "", null);
446 }
447
448
449
450
451 @Test
452 @Alerts({"null",
453 "",
454 "false",
455 "false-true-false-false-false-false-false-false-false-false-false",
456 "true",
457 "§§URL§§", "1"})
458 public void validationCustomValidity() throws Exception {
459 validation("<input type='search' id='e1' name='k'>\n", "elem.setCustomValidity('Invalid');", null);
460 }
461
462
463
464
465 @Test
466 @Alerts({"null",
467 "",
468 "false",
469 "false-true-false-false-false-false-false-false-false-false-false",
470 "true",
471 "§§URL§§", "1"})
472 public void validationBlankCustomValidity() throws Exception {
473 validation("<input type='search' id='e1' name='k'>\n", "elem.setCustomValidity(' ');\n", null);
474 }
475
476
477
478
479 @Test
480 @Alerts({"null",
481 "",
482 "true",
483 "false-false-false-false-false-false-false-false-false-true-false",
484 "true",
485 "§§URL§§?k=", "2"})
486 public void validationResetCustomValidity() throws Exception {
487 validation("<input type='search' id='e1' name='k'>\n",
488 "elem.setCustomValidity('Invalid');elem.setCustomValidity('');", null);
489 }
490
491
492
493
494 @Test
495 @Alerts({"null",
496 "",
497 "false",
498 "false-false-false-false-false-false-false-false-false-false-true",
499 "true",
500 "§§URL§§", "1"})
501 public void validationRequired() throws Exception {
502 validation("<input type='search' id='e1' name='k' required>\n", "", null);
503 }
504
505
506
507
508 @Test
509 @Alerts({"null",
510 "",
511 "true",
512 "false-false-false-false-false-false-false-false-false-true-false",
513 "true",
514 "§§URL§§?k=one", "2"})
515 public void validationRequiredValueSet() throws Exception {
516 validation("<input type='search' id='e1' name='k' required>\n", "elem.value='one';", null);
517 }
518
519
520
521
522 @Test
523 @Alerts({"null",
524 "",
525 "false",
526 "false-false-true-false-false-false-false-false-false-false-false",
527 "true",
528 "§§URL§§", "1"})
529 public void validationPattern() throws Exception {
530 validation("<input type='search' id='e1' name='k' pattern='abc'>\n", "elem.value='one';", null);
531 }
532
533 private void validation(final String htmlPart, final String jsPart, final String sendKeys) throws Exception {
534 final String html = DOCTYPE_HTML
535 + "<html><head>\n"
536 + " <script>\n"
537 + LOG_TITLE_FUNCTION
538 + " function logValidityState(s) {\n"
539 + " log(s.badInput"
540 + "+ '-' + s.customError"
541 + "+ '-' + s.patternMismatch"
542 + "+ '-' + s.rangeOverflow"
543 + "+ '-' + s.rangeUnderflow"
544 + "+ '-' + s.stepMismatch"
545 + "+ '-' + s.tooLong"
546 + "+ '-' + s.tooShort"
547 + " + '-' + s.typeMismatch"
548 + " + '-' + s.valid"
549 + " + '-' + s.valueMissing);\n"
550 + " }\n"
551 + " function test() {\n"
552 + " var elem = document.getElementById('e1');\n"
553 + jsPart
554 + " log(elem.checkValidity());\n"
555 + " logValidityState(elem.validity);\n"
556 + " log(elem.willValidate);\n"
557 + " }\n"
558 + " </script>\n"
559 + "</head>\n"
560 + "<body>\n"
561 + " <form>\n"
562 + htmlPart
563 + " <button id='myTest' type='button' onclick='test()'>Test</button>\n"
564 + " <button id='myButton' type='submit'>Submit</button>\n"
565 + " </form>\n"
566 + "</body></html>";
567
568 final String secondContent = DOCTYPE_HTML
569 + "<html><head><title>second</title></head><body>\n"
570 + " <p>hello world</p>\n"
571 + "</body></html>";
572
573 getMockWebConnection().setResponse(URL_SECOND, secondContent);
574 expandExpectedAlertsVariables(URL_FIRST);
575
576 final WebDriver driver = loadPage2(html, URL_FIRST);
577
578 final WebElement foo = driver.findElement(By.id("e1"));
579 if (sendKeys != null) {
580 foo.sendKeys(sendKeys);
581 }
582 assertEquals(getExpectedAlerts()[0], "" + foo.getDomAttribute("value"));
583 assertEquals(getExpectedAlerts()[1], foo.getDomProperty("value"));
584
585 driver.findElement(By.id("myTest")).click();
586 verifyTitle2(driver, getExpectedAlerts()[2], getExpectedAlerts()[3], getExpectedAlerts()[4]);
587
588 driver.findElement(By.id("myButton")).click();
589 if (useRealBrowser()) {
590 Thread.sleep(400);
591 }
592 assertEquals(getExpectedAlerts()[5], getMockWebConnection().getLastWebRequest().getUrl());
593 assertEquals(Integer.parseInt(getExpectedAlerts()[6]), getMockWebConnection().getRequestCount());
594 }
595 }