1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.html;
16
17 import static java.nio.charset.StandardCharsets.ISO_8859_1;
18
19 import java.net.URL;
20 import java.util.List;
21 import java.util.Map;
22
23 import org.htmlunit.HttpHeader;
24 import org.htmlunit.WebDriverTestCase;
25 import org.htmlunit.junit.annotation.Alerts;
26 import org.htmlunit.junit.annotation.HtmlUnitNYI;
27 import org.htmlunit.util.MimeType;
28 import org.junit.jupiter.api.Test;
29 import org.openqa.selenium.By;
30 import org.openqa.selenium.InvalidSelectorException;
31 import org.openqa.selenium.NoSuchElementException;
32 import org.openqa.selenium.WebDriver;
33 import org.openqa.selenium.WebElement;
34
35
36
37
38
39
40
41
42
43
44 public class HtmlPage3Test extends WebDriverTestCase {
45
46
47
48
49 @Test
50 public void emptyJavaScript() throws Exception {
51 final String html = "<body>\n"
52 + "<a id='myAnchor' href='javascript:'>Hello</a>\n"
53 + "</body>";
54
55 final WebDriver driver = loadPage2(html);
56 driver.findElement(By.id("myAnchor")).click();
57 }
58
59
60
61
62
63 @Test
64 public void formElementCreatedFromJavascript() throws Exception {
65 final String html = DOCTYPE_HTML
66 + "<html>\n"
67 + "<head>\n"
68 + "<script type='text/javascript'>\n"
69 + " function modifyForm() {\n"
70 + " var myForm = document.forms['test_form'];\n"
71 + " var el = document.createElement('input');\n"
72 + " el.setAttribute('addedBy','js');\n"
73 + " el.name = 'myHiddenField';\n"
74 + " el.value = 'myValue';\n"
75 + " el.type = 'hidden';\n"
76 + " myForm.appendChild(el);\n"
77 + "}\n"
78 + "</script>\n"
79 + "</head>\n"
80 + "<body onLoad='modifyForm()'>\n"
81 + " <form id='test_form' action='http://www.sourceforge.com/' method='post'>\n"
82 + " <input type='submit' value='click'/>\n"
83 + " </form>\n"
84 + "</body>\n"
85 + "</html>";
86
87 final WebDriver driver = loadPage2(html);
88 final List<WebElement> elements = driver.findElements(By.xpath("//*"));
89 assertEquals(7, elements.size());
90
91 assertEquals("html", elements.get(0).getTagName());
92 assertEquals("head", elements.get(1).getTagName());
93 assertEquals("script", elements.get(2).getTagName());
94 assertEquals("body", elements.get(3).getTagName());
95 assertEquals("form", elements.get(4).getTagName());
96 assertEquals("input", elements.get(5).getTagName());
97
98 final WebElement input = elements.get(6);
99 assertEquals("input", input.getTagName());
100 assertEquals("myHiddenField", input.getAttribute("name"));
101 assertEquals("js", input.getAttribute("addedBy"));
102 assertEquals("js", input.getAttribute("addedby"));
103 }
104
105
106
107
108 @Test
109 @Alerts({"windows-1252", "windows-1252", "windows-1252", "undefined"})
110 public void getPageEncoding() throws Exception {
111 final String htmlContent = DOCTYPE_HTML
112 + "<html><head>\n"
113 + " <meta http-equiv='Content-Type' content='text/html; charset=Shift_JIS'>\n"
114 + " <script>\n"
115 + LOG_TITLE_FUNCTION
116 + " function test() {\n"
117 + " log(document.inputEncoding);\n"
118 + " log(document.characterSet);\n"
119 + " log(document.charset);\n"
120 + " log(document.defaultCharset);\n"
121 + " }\n"
122 + " </script>\n"
123 + "</head><body onload='test()'>\n"
124 + "<table><tr><td>\n"
125 + "<meta name=vs_targetSchema content=\"http://schemas.microsoft.com/intellisense/ie5\">\n"
126 + "<form name='form1'>\n"
127 + " <input type='text' name='textfield1' id='textfield1' value='foo' />\n"
128 + " <input type='text' name='textfield2' id='textfield2'/>\n"
129 + "</form>\n"
130 + "</td></tr></table>\n"
131 + "</body></html>";
132 loadPageVerifyTitle2(htmlContent);
133 }
134
135
136
137
138
139 @Test
140 public void onLoadHandler_ScriptNameRead() throws Exception {
141 final String html = DOCTYPE_HTML
142 + "<html><head><title>foo</title>\n"
143 + "<script type='text/javascript'>\n"
144 + " load = function() {};\n"
145 + " onload = load;\n"
146 + " alert(onload);\n"
147 + "</script></head><body></body></html>";
148
149 final WebDriver driver = loadPage2(html);
150 final List<String> alerts = getCollectedAlerts(driver, 1);
151 assertEquals(1, alerts.size());
152 assertTrue(alerts.get(0).startsWith("function"));
153 }
154
155
156
157
158 @Test
159 public void constructor() throws Exception {
160 final String html = DOCTYPE_HTML
161 + "<html>\n"
162 + "<head><title>foo</title></head>\n"
163 + "<body>\n"
164 + "<p>hello world</p>\n"
165 + "<form id='form1' action='/formSubmit' method='post'>\n"
166 + " <input type='text' NAME='textInput1' value='textInput1'/>\n"
167 + " <input type='text' name='textInput2' value='textInput2'/>\n"
168 + " <input type='hidden' name='hidden1' value='hidden1'/>\n"
169 + " <input type='submit' name='submitInput1' value='push me'/>\n"
170 + "</form>\n"
171 + "</body></html>";
172
173 final WebDriver driver = loadPage2(html);
174 assertTitle(driver, "foo");
175 }
176
177
178
179
180 @Test
181 public void getInputByName() throws Exception {
182 final String html = DOCTYPE_HTML
183 + "<html>\n"
184 + "<head><title>foo</title></head>\n"
185 + "<body>\n"
186 + "<p>hello world</p>\n"
187 + "<form id='form1' action='/formSubmit' method='post'>\n"
188 + " <input type='text' NAME='textInput1' value='textInput1'/>\n"
189 + " <input type='text' name='textInput2' value='textInput2'/>\n"
190 + " <input type='hidden' name='hidden1' value='hidden1'/>\n"
191 + " <input type='submit' name='submitInput1' value='push me'/>\n"
192 + "</form>\n"
193 + "</body></html>";
194
195 final WebDriver driver = loadPage2(html);
196
197 final WebElement form = driver.findElement(By.id("form1"));
198 final WebElement input = form.findElement(By.name("textInput1"));
199 assertEquals("name", "textInput1", input.getDomAttribute("name"));
200
201 assertEquals("value", "textInput1", input.getDomAttribute("value"));
202 assertEquals("type", "text", input.getDomAttribute("type"));
203 }
204
205
206
207
208 @Test
209 @Alerts({"[object HTMLInputElement]", "1"})
210 public void write_getElementById_afterParsing() throws Exception {
211 final String html = DOCTYPE_HTML
212 + "<html>\n"
213 + "<head>\n"
214 + "<script>\n"
215 + LOG_WINDOW_NAME_FUNCTION
216 + " function test() {\n"
217 + " document.write(\"<input id='sendemail'>\");\n"
218 + " log(document.getElementById('sendemail'));\n"
219 + " document.write(\"<input name='sendemail2'>\");\n"
220 + " log(document.getElementsByName('sendemail2').length);\n"
221 + " }\n"
222 + "</script></head>\n"
223 + "<body onload='test()'>\n"
224 + "</body></html>";
225
226 loadPage2(html);
227 verifyWindowName2(getWebDriver(), getExpectedAlerts());
228 }
229
230
231
232
233 @Test
234 @Alerts({"[object HTMLInputElement]", "1"})
235 public void write_getElementById_duringParsing() throws Exception {
236 final String html = DOCTYPE_HTML
237 + "<html>\n"
238 + "<head></head>\n"
239 + "<body><script>\n"
240 + LOG_TITLE_FUNCTION
241 + " document.write(\"<input id='sendemail'>\");\n"
242 + " log(document.getElementById('sendemail'));\n"
243 + " document.write(\"<input name='sendemail2'>\");\n"
244 + " log(document.getElementsByName('sendemail2').length);\n"
245 + "</script></body></html>";
246 loadPageVerifyTitle2(html);
247 }
248
249
250
251
252 @Test
253 @Alerts("Hello")
254 public void application_javascript_type() throws Exception {
255 final String html = DOCTYPE_HTML
256 + "<html>\n"
257 + "<body>\n"
258 + " <script type='application/javascript'>\n"
259 + LOG_TITLE_FUNCTION
260 + " log('Hello');\n"
261 + " </script>\n"
262 + "</body></html>";
263
264 loadPageVerifyTitle2(html);
265 }
266
267
268
269
270 @Test
271 @Alerts("Hello")
272 public void application_x_javascript_type() throws Exception {
273 final String html = DOCTYPE_HTML
274 + "<html>\n"
275 + "<body>\n"
276 + " <script type='application/x-javascript'>\n"
277 + LOG_TITLE_FUNCTION
278 + " log('Hello');\n"
279 + " </script>\n"
280 + "</body></html>";
281
282 loadPageVerifyTitle2(html);
283 }
284
285
286
287
288 @Test
289 public void basePath() throws Exception {
290 basePath("base_path", URL_SECOND + "path");
291 }
292
293 private void basePath(final String baseUrl, final String expected) throws Exception {
294 final String html = DOCTYPE_HTML
295 + "<html>\n"
296 + "<head>\n"
297 + " <base href='" + baseUrl + "'>\n"
298 + "</head>\n"
299 + "<body>\n"
300 + " <a id='testLink' href='path'>click me</a>\n"
301 + "</body></html>";
302 getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
303 final WebDriver webDriver = loadPage2(html, URL_SECOND);
304 webDriver.findElement(By.id("testLink")).click();
305 assertEquals(expected, webDriver.getCurrentUrl());
306 }
307
308
309
310
311 @Test
312 public void basePathAndSlash() throws Exception {
313 basePath("base_path/", URL_SECOND + "base_path/path");
314 }
315
316
317
318
319 @Test
320 public void basePathAfterSlash() throws Exception {
321 basePath("/base_path", "http://localhost:" + PORT + "/path");
322 }
323
324
325
326
327 @Test
328 public void basePathSlashes() throws Exception {
329 basePath("/base_path/", URL_FIRST + "base_path/path");
330 }
331
332
333
334
335 @Test
336 public void basePathFullyQualified() throws Exception {
337 basePath("http://localhost:" + PORT + "/base_path", "http://localhost:" + PORT + "/path");
338 }
339
340
341
342
343 @Test
344 public void basePathFullyQualifiedSlash() throws Exception {
345 basePath("http://localhost:" + PORT + "/base_path/", "http://localhost:" + PORT + "/base_path/path");
346 }
347
348
349
350
351 @Test
352
353 public void basePathNoProtocol() throws Exception {
354 basePath("//localhost:" + PORT + "/base_path", "http://localhost:" + PORT + "/path");
355 }
356
357
358
359
360 @Test
361 public void basePathNoProtocolSlash() throws Exception {
362 basePath("//localhost:" + PORT + "/base_path/", "http://localhost:" + PORT + "/base_path/path");
363 }
364
365
366
367
368 @Test
369 public void basePathInvalid() throws Exception {
370 basePath("---****://==", URL_SECOND + "---****://path");
371 }
372
373
374
375
376 @Test
377 public void basePathLeadingAndTrailingWhitespace() throws Exception {
378 basePath(" \t\n" + "http://localhost:" + PORT + "/base_path/" + "\n\t ",
379 "http://localhost:" + PORT + "/base_path/path");
380 }
381
382
383
384
385 @Test
386 public void basePathEmpty() throws Exception {
387 basePath("", "http://localhost:" + PORT + "/second/path");
388 }
389
390
391
392
393 @Test
394 public void basePathWhitespaceOnly() throws Exception {
395 basePath(" \t\n ", "http://localhost:" + PORT + "/second/path");
396 }
397
398
399
400
401 @Test
402 @Alerts({"[object SVGSVGElement]", "http://www.w3.org/2000/svg",
403 "[object SVGRectElement]", "http://www.w3.org/2000/svg"})
404 public void htmlPageEmbeddedSvgWithoutNamespace() throws Exception {
405 final String content
406 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
407 + "<head>\n"
408 + "<script>\n"
409 + LOG_TITLE_FUNCTION
410 + " function test() {\n"
411 + " log(document.getElementById('mySvg'));\n"
412 + " log(document.getElementById('mySvg').namespaceURI);\n"
413 + " log(document.getElementById('myRect'));\n"
414 + " log(document.getElementById('myRect').namespaceURI);\n"
415 + " }\n"
416 + "</script>\n"
417 + "</head>\n"
418 + "<body onload='test()'>\n"
419 + " <svg id='mySvg'>\n"
420 + " <rect id='myRect' />\n"
421 + " </svg>\n"
422 + "</body>\n"
423 + "</html>";
424
425 loadPageVerifyTitle2(content);
426 }
427
428
429
430
431 @Test
432 @Alerts("HTML")
433 public void htmlPage() throws Exception {
434 final String content
435 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
436 + "<svg xmlns=\"http://www.w3.org/2000/svg\">\n"
437 + " <rect id='rect' width='50' height='50' fill='green' />\n"
438 + "<head>\n"
439 + "<script>\n"
440 + LOG_TITLE_FUNCTION
441 + " function test() {\n"
442 + " log(document.documentElement.tagName);\n"
443 + " }\n"
444 + "</script>\n"
445 + "</head>\n"
446 + "<body onload='test()'>\n"
447 + "</body>\n"
448 + "</svg>";
449
450 loadPageVerifyTitle2(content);
451 }
452
453
454
455
456 @Test
457 @Alerts("[object HTMLHtmlElement]")
458 public void htmlSvgPage() throws Exception {
459 final String content
460 = "<html xmlns=\"http://www.w3.org/2000/svg\">\n"
461 + " <rect id='rect' width='50' height='50' fill='green' />\n"
462 + "<body>\n"
463 + "<script>\n"
464 + LOG_TITLE_FUNCTION
465 + " log(document.documentElement);\n"
466 + "</script>\n"
467 + "</body>\n"
468 + "</html>";
469
470 loadPageVerifyTitle2(content);
471 }
472
473
474
475
476 @Test
477 @Alerts(DEFAULT = "error",
478 CHROME = "Something",
479 EDGE = "Something")
480 @HtmlUnitNYI(FF = "Something",
481 FF_ESR = "Something")
482 public void shouldBeAbleToFindElementByXPathInXmlDocument() throws Exception {
483 final String html = "<?xml version='1.0' encoding='UTF-8'?>\n"
484 + "<html xmlns='http://www.w3.org/1999/xhtml'\n"
485 + " xmlns:svg='http://www.w3.org/2000/svg'\n"
486 + " xmlns:xlink='http://www.w3.org/1999/xlink'>\n"
487 + "<body>\n"
488 + " <svg:svg id='chart_container' height='220' width='400'>\n"
489 + " <svg:text y='16' x='200' text-anchor='middle'>Something</svg:text>\n"
490 + " </svg:svg>\n"
491 + "</body>\n"
492 + "</html>\n";
493
494 final WebDriver driver = loadPage2(html, URL_FIRST, "application/xhtml+xml", ISO_8859_1, null);
495 String actual;
496 try {
497 final WebElement element = driver.findElement(By.xpath("//svg:svg//svg:text"));
498 actual = element.getText();
499 }
500 catch (final NoSuchElementException e) {
501 actual = "error";
502 }
503 catch (final InvalidSelectorException e) {
504 actual = "error";
505 }
506 assertEquals(getExpectedAlerts()[0], actual);
507 }
508
509
510
511
512 @Test
513 @Alerts("interactive")
514 public void readyStateInDOMContentLoaded() throws Exception {
515 final String html = DOCTYPE_HTML
516 + "<html>\n"
517 + " <head>\n"
518 + " <script>\n"
519 + LOG_TITLE_FUNCTION
520 + " document.addEventListener('DOMContentLoaded', function () {\n"
521 + " log(document.readyState);\n"
522 + " });\n"
523 + " </script>\n"
524 + " </head>\n"
525 + " <body>test</body>\n"
526 + "</html>";
527
528 loadPageVerifyTitle2(html);
529 }
530
531
532
533
534 @Test
535 @Alerts("25")
536 public void loadExternalJavaScript() throws Exception {
537 final String html = DOCTYPE_HTML
538 + "<html><head>\n"
539 + "<script>\n"
540 + "function makeIframe() {\n"
541 + " var iframesrc = '<html><head>';\n"
542 + " iframesrc += '<script src=\"" + "js.js" + "\"></' + 'script>';\n"
543 + " iframesrc += '<script>';\n"
544 + " iframesrc += 'function doSquared() {';\n"
545 + " iframesrc += ' try {';\n"
546 + " iframesrc += ' var y = squared(5);';\n"
547 + " iframesrc += ' alert(y);';\n"
548 + " iframesrc += ' } catch(e) {';\n"
549 + " iframesrc += ' alert(\"error\");';\n"
550 + " iframesrc += ' }';\n"
551 + " iframesrc += '}';\n"
552 + " iframesrc += '</' + 'script>';\n"
553 + " iframesrc += '</head>';\n"
554 + " iframesrc += '<body onLoad=\"doSquared()\" >';\n"
555 + " iframesrc += '</body>';\n"
556 + " iframesrc += '</html>';\n"
557 + " var iframe = document.createElement('IFRAME');\n"
558 + " iframe.id = 'iMessage';\n"
559 + " iframe.name = 'iMessage';\n"
560 + " iframe.src = \"javascript:'\" + iframesrc + \"'\";\n"
561 + " document.body.appendChild(iframe);\n"
562 + "}\n"
563 + "</script></head>\n"
564 + "<body onload='makeIframe()'>\n"
565 + "</body></html>";
566
567 final String js = "function squared(n) {return n * n}";
568
569 getMockWebConnection().setResponse(URL_FIRST, html);
570 getMockWebConnection().setResponse(new URL(URL_FIRST, "js.js"), js);
571
572 loadPageWithAlerts2(URL_FIRST);
573
574 assertEquals(2, getMockWebConnection().getRequestCount());
575
576 final Map<String, String> lastAdditionalHeaders = getMockWebConnection().getLastAdditionalHeaders();
577 assertNull(lastAdditionalHeaders.get(HttpHeader.REFERER));
578 }
579
580
581
582
583
584 @Test
585 @Alerts("25")
586 public void loadExternalJavaScript_absolute() throws Exception {
587 final String html = DOCTYPE_HTML
588 + "<html><head>\n"
589 + "<script>\n"
590 + "function makeIframe() {\n"
591 + " var iframesrc = '<html><head>';\n"
592 + " iframesrc += '<script src=\"" + URL_SECOND + "\"></' + 'script>';\n"
593 + " iframesrc += '<script>';\n"
594 + " iframesrc += 'function doSquared() {';\n"
595 + " iframesrc += ' try {';\n"
596 + " iframesrc += ' var y = squared(5);';\n"
597 + " iframesrc += ' alert(y);';\n"
598 + " iframesrc += ' } catch(e) {';\n"
599 + " iframesrc += ' log(\"error\");';\n"
600 + " iframesrc += ' }';\n"
601 + " iframesrc += '}';\n"
602 + " iframesrc += '</' + 'script>';\n"
603 + " iframesrc += '</head>';\n"
604 + " iframesrc += '<body onLoad=\"doSquared()\" >';\n"
605 + " iframesrc += '</body>';\n"
606 + " iframesrc += '</html>';\n"
607 + " var iframe = document.createElement('IFRAME');\n"
608 + " iframe.id = 'iMessage';\n"
609 + " iframe.name = 'iMessage';\n"
610 + " iframe.src = \"javascript:'\" + iframesrc + \"'\";\n"
611 + " document.body.appendChild(iframe);\n"
612 + "}\n"
613 + "</script></head>\n"
614 + "<body onload='makeIframe()'>\n"
615 + "</body></html>";
616
617 final String js = "function squared(n) {return n * n}";
618
619 getMockWebConnection().setResponse(URL_FIRST, html);
620 getMockWebConnection().setResponse(URL_SECOND, js);
621
622 loadPageWithAlerts2(URL_FIRST);
623
624 assertEquals(2, getMockWebConnection().getRequestCount());
625
626 final Map<String, String> lastAdditionalHeaders = getMockWebConnection().getLastAdditionalHeaders();
627 assertNull(lastAdditionalHeaders.get(HttpHeader.REFERER));
628 }
629
630
631
632
633
634 @Test
635 @Alerts({"cl2", "cl1"})
636 public void onLoadHandler_idChange() throws Exception {
637 final String html = DOCTYPE_HTML
638 + "<html>\n"
639 + "<head>\n"
640 + "<div id='id1' class='cl1'><div id='id2' class='cl2'></div></div>'"
641 + "<script type='text/javascript'>\n"
642 + LOG_TITLE_FUNCTION
643 + "document.getElementById('id1').id = 'id3';\n"
644 + "log(document.getElementById('id2').className);\n"
645 + "log(document.getElementById('id3').className);\n"
646 + "</script>\n"
647 + "</head><body></body></html>";
648
649 loadPageVerifyTitle2(html);
650 }
651
652
653
654
655
656
657
658 @Test
659 @Alerts("[object HTMLTableRowElement]")
660 public void getElementById_AfterAppendRemoveAppendChild() throws Exception {
661 final String content = DOCTYPE_HTML
662 + "<html><head>\n"
663 + "<script>\n"
664 + LOG_TITLE_FUNCTION
665 + " function test() {\n"
666 + " var table = document.createElement('table');\n"
667 + " var tr = document.createElement('tr');\n"
668 + " tr.id = 'myTR';\n"
669 + " table.appendChild(tr);\n"
670 + " document.body.appendChild(table);\n"
671 + " document.body.removeChild(table);\n"
672 + " document.body.appendChild(table);\n"
673 + " log(document.getElementById('myTR'));\n"
674 + " }\n"
675 + "</script></head>\n"
676 + "<body onload='test()'>\n"
677 + "</body></html>";
678 loadPageVerifyTitle2(content);
679 }
680
681
682
683
684 @Test
685 @Alerts("null")
686 public void getElementById_AfterAppendingToNewlyCreatedElement() throws Exception {
687 final String content = DOCTYPE_HTML
688 + "<html><head>\n"
689 + "<script>\n"
690 + LOG_TITLE_FUNCTION
691 + " function test() {\n"
692 + " var table = document.createElement('table');\n"
693 + " var tr = document.createElement('tr');\n"
694 + " tr.id = 'myTR';\n"
695 + " table.appendChild(tr);\n"
696 + " log(document.getElementById('myTR'));\n"
697 + " }\n"
698 + "</script></head>\n"
699 + "<body onload='test()'>\n"
700 + "</body></html>";
701 loadPageVerifyTitle2(content);
702 }
703
704
705
706
707
708 @Test
709 @Alerts("works")
710 public void metaWithNamespace() throws Exception {
711 final String content = DOCTYPE_HTML
712 + "<html>\n"
713 + "<head>\n"
714 + " <title>works\u00a7</title>\n"
715 + "</head>\n"
716 + "<body>\n"
717 + " <overheidrg:meta xmlns:overheidrg='http://standaarden.overheid.nl/cvdr/terms/'>\n"
718 + "</body>\n"
719 + "</html>";
720
721 loadPageVerifyTitle2(content);
722 }
723 }