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