1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host;
16
17 import java.io.InputStream;
18 import java.net.URL;
19 import java.util.Arrays;
20 import java.util.Collections;
21 import java.util.Comparator;
22 import java.util.Map;
23 import java.util.regex.Pattern;
24 import java.util.stream.Collectors;
25
26 import org.apache.commons.io.IOUtils;
27 import org.apache.commons.lang3.StringUtils;
28 import org.htmlunit.HttpHeader;
29 import org.htmlunit.WebDriverTestCase;
30 import org.htmlunit.junit.annotation.Alerts;
31 import org.htmlunit.junit.annotation.HtmlUnitNYI;
32 import org.junit.jupiter.api.Test;
33 import org.openqa.selenium.By;
34 import org.openqa.selenium.WebDriver;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public class Window3Test extends WebDriverTestCase {
54
55
56
57
58 @Test
59 @Alerts("about:blank")
60 public void openWindow_emptyUrl() throws Exception {
61 final String html = DOCTYPE_HTML
62 + "<html><head>\n"
63 + "<script>\n"
64 + LOG_TITLE_FUNCTION
65 + "var w = window.open('');\n"
66 + "log(w ? w.document.location : w);\n"
67 + "</script></head>\n"
68 + "<body></body></html>";
69
70 loadPageVerifyTitle2(html);
71 }
72
73
74
75
76 @Test
77 @Alerts({"null", "one", "two", "three"})
78 public void opener() throws Exception {
79 final URL urlThird = new URL(URL_FIRST, "third/");
80
81 final String firstContent = DOCTYPE_HTML
82 + "<html><head>\n"
83 + "<title>First</title>\n"
84 + "<script>\n"
85 + LOG_WINDOW_NAME_FUNCTION
86 + "function test() {\n"
87 + " log(window.opener);\n"
88 + " log('one');\n"
89 + " open('" + URL_SECOND + "', 'foo');\n"
90 + "}\n"
91 + "function calllog(text) {\n"
92 + " log(text);\n"
93 + "}\n"
94 + "</script></head><body onload='test()'>\n"
95 + "</body></html>";
96 final String secondContent = DOCTYPE_HTML
97 + "<html><head>\n"
98 + "<title>Second</title>\n"
99 + "<script>\n"
100 + "function test() {\n"
101 + " opener.calllog('two');\n"
102 + " document.form1.submit();\n"
103 + "}\n"
104 + "</script></head>\n"
105 + "<body onload='test()'>\n"
106 + "<form name='form1' action='" + urlThird + "' method='post'><input type='submit'></form>\n"
107 + "</body></html>";
108 final String thirdContent = DOCTYPE_HTML
109 + "<html><head>\n"
110 + "<title>Third</title>\n"
111 + "<script>\n"
112 + "function test() {\n"
113 + " opener.calllog('three');\n"
114 + "}\n"
115 + "</script></head><body onload='test()'>\n"
116 + "</body></html>";
117
118 getMockWebConnection().setResponse(URL_SECOND, secondContent);
119 getMockWebConnection().setResponse(urlThird, thirdContent);
120
121 final WebDriver driver = loadPage2(firstContent);
122 assertTitle(driver, "First");
123 verifyWindowName2(DEFAULT_WAIT_TIME, driver, getExpectedAlerts());
124 }
125
126
127
128
129 @Test
130 @Alerts("one")
131 public void windowFrames() throws Exception {
132 final String html = DOCTYPE_HTML
133 + "<html><body>\n"
134 + "<script language='JavaScript'>\n"
135 + LOG_TITLE_FUNCTION
136 + "if (typeof top.frames['anyXXXname'] == 'undefined') {\n"
137 + " log('one');\n"
138 + "}\n"
139 + "</script></body></html>";
140
141 loadPageVerifyTitle2(html);
142 }
143
144
145
146
147
148
149 @Test
150 @Alerts("foo")
151 public void javascriptVariableFromWindow() throws Exception {
152 final String html = DOCTYPE_HTML
153 + "<html><head></head>\n"
154 + "<body>\n"
155 + "<script>\n"
156 + LOG_TITLE_FUNCTION
157 + "myVariable = 'foo';\n"
158 + "log(window.myVariable);\n"
159 + "</script></body></head>";
160
161 loadPageVerifyTitle2(html);
162 }
163
164
165
166
167
168
169 @Test
170 @Alerts({"parent.myVariable = second", "top.myVariable = first"})
171 public void javascriptVariableFromTopAndParentFrame() throws Exception {
172 final URL urlThird = new URL(URL_FIRST, "third/");
173
174 final String firstContent = DOCTYPE_HTML
175 + "<html><head>\n"
176 + "<title>First</title>\n"
177 + "</head><body>\n"
178 + "<script>myVariable = 'first'</script>\n"
179 + "<iframe name='left' src='" + URL_SECOND + "'></iframe>\n"
180 + "</body></html>";
181
182 final String secondContent = DOCTYPE_HTML
183 + "<html><head>\n"
184 + "<title>Second</title>\n"
185 + "</head>\n"
186 + "<body>\n"
187 + "<script>myVariable = 'second'</script>\n"
188 + "<iframe name='innermost' src='" + urlThird + "'></iframe>\n"
189 + "</body></html>";
190 getMockWebConnection().setResponse(URL_SECOND, secondContent);
191
192 final String thirdContent = DOCTYPE_HTML
193 + "<html><head>\n"
194 + "<title>Third</title>\n"
195 + "<script>\n"
196 + "myVariable = 'third';\n"
197
198 + LOG_WINDOW_NAME_FUNCTION
199 + "function doTest() {\n"
200 + " log('parent.myVariable = ' + parent.myVariable);\n"
201 + " log('top.myVariable = ' + top.myVariable);\n"
202 + "}\n"
203 + "</script></head>\n"
204 + "<body onload='doTest()'></body></html>";
205 getMockWebConnection().setResponse(urlThird, thirdContent);
206
207 final WebDriver driver = loadPage2(firstContent);
208 assertTitle(driver, "First");
209 verifyWindowName2(driver, getExpectedAlerts());
210 }
211
212
213
214
215
216
217 @Test
218 @Alerts({"parent.second.myVariable = second", "parent.third.myVariable = third"})
219 public void javascriptVariableFromNamedFrame() throws Exception {
220 final URL urlThird = new URL(URL_FIRST, "third/");
221 final URL urlFourth = new URL(URL_FIRST, "fourth/");
222
223 final String firstContent = DOCTYPE_HTML
224 + "<html><head><title>first</title></head>\n"
225 + "<frameset cols='20%,80%'>\n"
226 + " <frameset rows='30%,70%'>\n"
227 + " <frame src='" + URL_SECOND + "' name='second'>\n"
228 + " <frame src='" + urlThird + "' name='third'>\n"
229 + " </frameset>\n"
230 + " <frame src='" + urlFourth + "' name='fourth'>\n"
231 + "</frameset></html>";
232
233 final String secondContent = DOCTYPE_HTML
234 + "<html><head>\n"
235 + "<title>second</title>\n"
236 + "</head><body>\n"
237 + "<script>myVariable = 'second';</script>\n"
238 + "<p>second</p></body></html>";
239 getMockWebConnection().setResponse(URL_SECOND, secondContent);
240
241 final String thirdContent = DOCTYPE_HTML
242 + "<html><head>\n"
243 + "<title>third</title>\n"
244 + "</head>\n"
245 + "<body>\n"
246 + "<script>myVariable = 'third';</script>\n"
247 + "<p>third</p></body></html>";
248 getMockWebConnection().setResponse(urlThird, thirdContent);
249
250 final String fourthContent = DOCTYPE_HTML
251 + "<html><head>\n"
252 + "<title>fourth</title>\n"
253 + "</head>\n"
254 + "<body onload='doTest()'>\n"
255 + "<script>\n"
256 + " myVariable = 'fourth';\n"
257 + LOG_WINDOW_NAME_FUNCTION
258 + " function doTest() {\n"
259 + " log('parent.second.myVariable = ' + parent.second.myVariable);\n"
260 + " log('parent.third.myVariable = ' + parent.third.myVariable);\n"
261 + "}\n"
262 + "</script></body></html>";
263 getMockWebConnection().setResponse(urlFourth, fourthContent);
264
265 final WebDriver driver = loadPage2(firstContent);
266 assertTitle(driver, "first");
267 verifyWindowName2(driver, getExpectedAlerts());
268 }
269
270
271
272
273
274 @Test
275 @Alerts("true")
276 public void javascriptVariableFromWindow_NotFound() throws Exception {
277 final String html = DOCTYPE_HTML
278 + "<html><head></head>\n"
279 + "<body>\n"
280 + "<script>\n"
281 + LOG_TITLE_FUNCTION
282 + "myVariable = 'foo';\n"
283 + "log(window.myOtherVariable == null);\n"
284 + "</script></body></head>";
285
286 loadPageVerifyTitle2(html);
287 }
288
289
290
291
292 @Test
293 @Alerts({"fourth-second=§§URL2§§", "fourth-third=§§URL3§§"})
294 public void getFrameByName() throws Exception {
295 final URL urlThird = new URL(URL_FIRST, "third/");
296 final URL urlFourth = new URL(URL_FIRST, "fourth/");
297
298 final String firstContent = DOCTYPE_HTML
299 + "<html><head><title>first</title></head>\n"
300 + "<frameset cols='20%,80%'>\n"
301 + " <frameset rows='30%,70%'>\n"
302 + " <frame src='" + URL_SECOND + "' name='second'>\n"
303 + " <frame src='" + urlThird + "' name='third'>\n"
304 + " </frameset>\n"
305 + " <frame src='" + urlFourth + "' name='fourth'>\n"
306 + "</frameset></html>";
307
308 final String secondContent = DOCTYPE_HTML
309 + "<html><head><title>second</title></head><body><p>second</p></body></html>";
310 getMockWebConnection().setResponse(URL_SECOND, secondContent);
311
312 final String thirdContent = DOCTYPE_HTML
313 + "<html><head><title>third</title></head><body><p>third</p></body></html>";
314 getMockWebConnection().setResponse(urlThird, thirdContent);
315
316 final String fourthContent = DOCTYPE_HTML
317 + "<html><head>\n"
318 + "<title>fourth</title>\n"
319 + "</head>\n"
320 + "<body onload='doTest()'><script>\n"
321 + LOG_WINDOW_NAME_FUNCTION
322 + " function doTest() {\n"
323 + " log('fourth-second='+parent.second.document.location);\n"
324 + " log('fourth-third='+parent.third.document.location);\n"
325 + "}\n"
326 + "</script></body></html>";
327 getMockWebConnection().setResponse(urlFourth, fourthContent);
328
329 final String[] expectedAlerts = getExpectedAlerts();
330 for (int i = 0; i < expectedAlerts.length; i++) {
331 expectedAlerts[i] = expectedAlerts[i].replaceAll("§§URL2§§", URL_SECOND.toExternalForm())
332 .replaceAll("§§URL3§§", urlThird.toExternalForm());
333 }
334 setExpectedAlerts(expectedAlerts);
335
336 final WebDriver driver = loadPage2(firstContent);
337 assertTitle(driver, "first");
338 verifyWindowName2(driver, expectedAlerts);
339 }
340
341
342
343
344
345 @Test
346 @Alerts({"false", "false", "true"})
347 public void closed() throws Exception {
348 final String html = DOCTYPE_HTML
349 + "<html><head>\n"
350 + "<script>\n"
351 + LOG_TITLE_FUNCTION
352 + "function test() {\n"
353 + " log(window.closed);\n"
354 + " var newWindow = window.open('about:blank', 'foo');\n"
355 + " log(newWindow.closed);\n"
356 + " newWindow.close();\n"
357 + " log(newWindow.closed);\n"
358 + "}\n"
359 + "</script></head><body onload='test()'>\n"
360 + "</body></html>";
361
362 loadPageVerifyTitle2(html);
363 }
364
365
366
367
368
369 @Test
370 public void moveTo() throws Exception {
371 final String html = DOCTYPE_HTML
372 + "<html><head>\n"
373 + "<script>\n"
374 + LOG_TITLE_FUNCTION
375 + " window.moveTo(10, 20);\n"
376 + "</script></head><body>\n"
377 + "</body></html>";
378 loadPageVerifyTitle2(html);
379 }
380
381
382
383
384
385 @Test
386 public void moveBy() throws Exception {
387 final String html = DOCTYPE_HTML
388 + "<html><head>\n"
389 + "<script>\n"
390 + LOG_TITLE_FUNCTION
391 + " window.moveBy(10, 20);\n"
392 + "</script></head><body>\n"
393 + "</body></html>";
394 loadPageVerifyTitle2(html);
395 }
396
397
398
399
400
401 @Test
402 public void resizeTo() throws Exception {
403 final String html = DOCTYPE_HTML
404 + "<html><head>\n"
405 + "<script>\n"
406 + LOG_TITLE_FUNCTION
407 + "window.resizeTo(10, 20);\n"
408 + "window.resizeTo(-10, 20);\n"
409 + "</script></head><body></body></html>";
410 loadPageVerifyTitle2(html);
411 }
412
413
414
415
416
417 @Test
418 public void resizeBy() throws Exception {
419 final String html = DOCTYPE_HTML
420 + "<html><head>\n"
421 + "<script>\n"
422 + LOG_TITLE_FUNCTION
423 + "window.resizeBy(10, 20);\n"
424 + "window.resizeBy(-10, 20);\n"
425 + "</script></head><body></body></html>";
426 loadPageVerifyTitle2(html);
427 }
428
429
430
431
432
433 @Test
434 public void scroll() throws Exception {
435 final String html = DOCTYPE_HTML
436 + "<html><head>\n"
437 + "<script>\n"
438 + LOG_TITLE_FUNCTION
439 + "window.scroll(10, 20);\n"
440 + "</script></head><body>\n"
441 + "</body></html>";
442 loadPageVerifyTitle2(html);
443 }
444
445
446
447
448 @Test
449 @Alerts({"document", "body"})
450 public void scrollEvents() throws Exception {
451 final String html = DOCTYPE_HTML
452 + "<html>\n"
453 + "<head>\n"
454 + "<script>\n"
455 + LOG_TEXTAREA_FUNCTION
456 + " function test() {\n"
457 + " document.addEventListener('scroll', function(e) { log(\"document\") });\n"
458 + " window.scroll(10, 20);\n"
459 + " }\n"
460 + "</script>\n"
461 + "</head>\n"
462 + "<body onload='test()' onscroll='log(\"body\")'>\n"
463 + " <div onscroll='log(\"div\")' style='height: 1000px;'></div>\n"
464 + LOG_TEXTAREA
465 + "</body>\n"
466 + "</html>";
467
468 loadPageVerifyTextArea2(html);
469 }
470
471
472
473
474
475 @Test
476 public void scrollBy() throws Exception {
477 final String html = DOCTYPE_HTML
478 + "<html><head>\n"
479 + "<script>\n"
480 + LOG_TITLE_FUNCTION
481 + "window.scrollBy(10, 20);\n"
482 + "</script></head>\n"
483 + "<body>\n"
484 + "</body></html>";
485 loadPageVerifyTitle2(html);
486 }
487
488
489
490
491 @Test
492 @Alerts({"document [object HTMLDocument]", "body", "window [object HTMLDocument]"})
493 public void scrollByEvents() throws Exception {
494 final String html = DOCTYPE_HTML
495 + "<html>\n"
496 + "<head>\n"
497 + "<script>\n"
498 + LOG_TEXTAREA_FUNCTION
499 + " function test() {\n"
500 + " window.addEventListener('scroll', function(e) { log(\"window \" + e.target) });\n"
501 + " document.addEventListener('scroll', function(e) { log(\"document \" + e.target) });\n"
502
503 + " window.scrollBy(10, 20);\n"
504 + " }\n"
505 + "</script>\n"
506 + "</head>\n"
507 + "<body onload='test()' onscroll='log(\"body\")'>\n"
508 + " <div onscroll='log(\"div\")' style='height: 1000px;'></div>\n"
509 + LOG_TEXTAREA
510 + "</body>\n"
511 + "</html>";
512
513 loadPageVerifyTextArea2(html);
514 }
515
516
517
518
519
520 @Test
521 @Alerts(DEFAULT = "TypeError",
522 FF = {},
523 FF_ESR = {})
524 public void scrollByLines() throws Exception {
525 final String html = DOCTYPE_HTML
526 + "<html><head>\n"
527 + "<script>\n"
528 + LOG_TITLE_FUNCTION
529 + "try {\n"
530 + " window.scrollByLines(2);\n"
531 + "} catch(e) { logEx(e); }\n"
532 + "</script></head><body>\n"
533 + "</body></html>";
534 loadPageVerifyTitle2(html);
535 }
536
537
538
539
540
541 @Test
542 @Alerts(DEFAULT = "TypeError",
543 FF = {},
544 FF_ESR = {})
545 public void scrollByPages() throws Exception {
546 final String html = DOCTYPE_HTML
547 + "<html><head>\n"
548 + "<script>\n"
549 + LOG_TITLE_FUNCTION
550 + "try {\n"
551 + " window.scrollByPages(2);\n"
552 + "} catch(e) { logEx(e); }\n"
553 + "</script></head><body>\n"
554 + "</body></html>";
555 loadPageVerifyTitle2(html);
556 }
557
558
559
560
561
562 @Test
563 public void scrollTo() throws Exception {
564 final String html = DOCTYPE_HTML
565 + "<html><head>\n"
566 + "<script>\n"
567 + LOG_TITLE_FUNCTION
568 + "window.scrollTo(10, 20);\n"
569 + "</script></head><body>\n"
570 + "</body></html>";
571 loadPageVerifyTitle2(html);
572 }
573
574
575
576
577 @Test
578 @Alerts({"document[object HTMLDocument]", "body", "document[object HTMLDocument]"})
579 public void scrollToEvents() throws Exception {
580 final String html = DOCTYPE_HTML
581 + "<html>\n"
582 + "<head>\n"
583 + "<script>\n"
584 + LOG_TEXTAREA_FUNCTION
585 + " function test() {\n"
586 + " window.addEventListener('scroll', function(e) { log(\"document\" + e.target) });\n"
587 + " document.addEventListener('scroll', function(e) { log(\"document\" + e.target) });\n"
588 + " window.scrollTo(10, 20);\n"
589 + " }\n"
590 + "</script>\n"
591 + "</head>\n"
592 + "<body onload='test()' onscroll='log(\"body\")'>\n"
593 + " <div onscroll='log(\"div\")' style='height: 1000px;'></div>\n"
594 + LOG_TEXTAREA
595 + "</body>\n"
596 + "</html>";
597
598 loadPageVerifyTextArea2(html);
599 }
600
601
602
603
604 @Test
605 @Alerts({"form1", "form1", "2", "2"})
606 public void formByName() throws Exception {
607 final String html = DOCTYPE_HTML
608 + "<html><head>\n"
609 + "<script>\n"
610 + LOG_TITLE_FUNCTION
611 + " function test() {\n"
612 + " log(window.form1.name);\n"
613 + " log(form1.name);\n"
614 + " log(window.form2.length);\n"
615 + " log(form2.length);\n"
616 + " }\n"
617 + "</script></head><body onload='test()'>\n"
618 + " <form name='form1'></form>\n"
619 + " <form name='form2'></form>\n"
620 + " <form name='form2'></form>\n"
621 + "</body></html>";
622
623 loadPageVerifyTitle2(html);
624 }
625
626
627
628
629 @Test
630 @Alerts({"frame1", "frame1", "0", "0"})
631 public void frameByName() throws Exception {
632 final String html = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\""
633 + "\"http://www.w3.org/TR/html4/frameset.dtd\">\n"
634 + "<html><head>\n"
635 + "<script>\n"
636 + LOG_TITLE_FUNCTION
637 + " function test() {\n"
638 + " log(window.frame1.name);\n"
639 + " log(frame1.name);\n"
640 + " log(window.frame2.length);\n"
641 + " log(frame2.length);\n"
642 + " }\n"
643 + "</script></head>\n"
644 + "<frameset onload='test()'>\n"
645 + " <frame src='" + URL_SECOND + "' name='frame1'>\n"
646 + " <frame src='" + URL_SECOND + "' name='frame2'>\n"
647 + " <frame src='" + URL_SECOND + "' name='frame2'>\n"
648 + "</frameset>\n"
649 + "</html>";
650
651 final String frame = DOCTYPE_HTML
652 + "<html><head><title>frame</title></head><body></body></html>";
653 getMockWebConnection().setDefaultResponse(frame);
654
655 loadPageVerifyTitle2(html);
656 }
657
658
659
660
661 @Test
662 @Alerts({"frame1", "frame1", "0", "0"})
663 public void iframeByName() throws Exception {
664 final String html = DOCTYPE_HTML
665 + "<html><head>\n"
666 + "<script>\n"
667 + LOG_TITLE_FUNCTION
668 + " function test() {\n"
669 + " log(window.frame1.name);\n"
670 + " log(frame1.name);\n"
671 + " log(window.frame2.length);\n"
672 + " log(frame2.length);\n"
673 + " }\n"
674 + "</script></head><body onload='test()'>\n"
675 + " <iframe name='frame1'></iframe>\n"
676 + " <iframe name='frame2'></iframe>\n"
677 + " <iframe name='frame2'></iframe>\n"
678
679 + " <form name='frame2'></form>\n"
680 + "</body></html>";
681
682 loadPageVerifyTitle2(html);
683 }
684
685
686
687
688 @Test
689 @Alerts({"5", "EMBED", "FORM", "IMG", "IMG", "OBJECT", "5", "EMBED", "FORM", "IMG", "IMG", "OBJECT"})
690
691
692
693
694 public void elementsByName() throws Exception {
695 final String html = DOCTYPE_HTML
696 + "<html><head>\n"
697 + "<script>\n"
698 + LOG_TITLE_FUNCTION
699 + " function test() {\n"
700 + " dump(window.element1);\n"
701 + " dump(element1);\n"
702 + " }\n"
703 + " function dump(c) {\n"
704 + " log(c.length);\n"
705 + " for (i = 0; i < c.length; i++) {\n"
706 + " log(c.item(i).nodeName);\n"
707 + " }\n"
708 + " }\n"
709 + "</script></head>\n"
710 + "<body onload='test()'>\n"
711 + " <abbr name='element1'></abbr>\n"
712 + " <acronym name='element1'></acronym>\n"
713 + " <a name='element1'></a>\n"
714 + " <address name='element1'></address>\n"
715 + " <article name='element1'></article>\n"
716 + " <audio name='element1'></audio>\n"
717 + " <bgsound name='element1'>\n"
718 + " <base name='element1'>\n"
719 + " <basefont name='element1'>\n"
720 + " <bdo name='element1'></bdo>\n"
721 + " <big name='element1'></big>\n"
722 + " <blink name='element1'></blink>\n"
723 + " <blockquote name='element1'></blockquote>\n"
724
725 + " <b name='element1'></b>\n"
726 + " <br name='element1'>\n"
727 + " <button name='element1'></button>\n"
728 + " <canvas name='element1'></canvas>\n"
729 + " <caption name='element1'></caption>\n"
730 + " <center name='element1'></center>\n"
731 + " <cite name='element1'></cite>\n"
732 + " <code name='element1'></code>\n"
733 + " <datalist name='element1'></datalist>\n"
734 + " <dfn name='element1'></dfn>\n"
735 + " <del name='element1'></del>\n"
736 + " <dir name='element1'></dir>\n"
737 + " <div name='element1'></div>\n"
738 + " <dl name='element1'>\n"
739 + " <dt name='element1'></dt>\n"
740 + " <dd name='element1'></dd>\n"
741 + " </dl>\n"
742 + " <embed name='element1'>\n"
743 + " <em name='element1'></em>\n"
744 + " <fieldset name='element1'></fieldset>\n"
745 + " <figcaption name='element1'></figcaption>\n"
746 + " <figure name='element1'></figure>\n"
747 + " <font name='element1'></font>\n"
748 + " <form name='element1'></form>\n"
749 + " <footer name='element1'></footer>\n"
750
751
752 + " <h1 name='element1'></h1>\n"
753 + " <h2 name='element1'></h2>\n"
754 + " <h3 name='element1'></h3>\n"
755 + " <h4 name='element1'></h4>\n"
756 + " <h5 name='element1'></h5>\n"
757 + " <h6 name='element1'></h6>\n"
758
759 + " <header name='element1'></header>\n"
760 + " <hr name='element1'>\n"
761
762
763 + " <q name='element1'></q>\n"
764 + " <ruby name='element1'>\n"
765 + " <rt name='element1'></rt>\n"
766 + " <rp name='element1'></rp>\n"
767 + " </ruby>\n"
768 + " <image name='element1'></image>\n"
769 + " <img name='element1'>\n"
770 + " <input name='element1'>\n"
771 + " <ins name='element1'></ins>\n"
772
773 + " <i name='element1'></i>\n"
774 + " <kbd name='element1'></kbd>\n"
775 + " <keygen name='element1'>\n"
776 + " <label name='element1'></label>\n"
777 + " <legend name='element1'></legend>\n"
778 + " <listing name='element1'></listing>\n"
779 + " <link name='element1'>\n"
780 + " <map name='element1'>\n"
781 + " <area name='element1'>\n"
782 + " </map>\n"
783 + " <marquee name='element1'></marquee>\n"
784 + " <mark name='element1'></mark>\n"
785 + " <menu name='element1'></menu>\n"
786
787 + " <meter name='element1'></meter>\n"
788 + " <multicol name='element1'></multicol>\n"
789 + " <nav name='element1'></nav>\n"
790 + " <nextid name='element1'></nextid>\n"
791 + " <nobr name='element1'></nobr>\n"
792 + " <noembed name='element1'></noembed>\n"
793 + " <noframes name='element1'></noframes>\n"
794 + " <noscript name='element1'></noscript>\n"
795 + " <object name='element1'>\n"
796 + " <param name='element1'>\n"
797 + " </object>\n"
798 + " <ol name='element1'>\n"
799 + " <li name='element1'></li>\n"
800 + " </ol>\n"
801 + " <output name='element1'></output>\n"
802 + " <p name='element1'></p>\n"
803
804 + " <pre name='element1'></pre>\n"
805 + " <progress name='element1'></progress>\n"
806 + " <s name='element1'></s>\n"
807 + " <samp name='element1'></samp>\n"
808 + " <script name='element1'></script>\n"
809 + " <section name='element1'></section>\n"
810 + " <select name='element1'>\n"
811 + " <optgroup name='element1'>\n"
812 + " <option name='element1'></option>\n"
813 + " </optgroup>\n"
814 + " </select>\n"
815 + " <small name='element1'></small>\n"
816 + " <source name='element1'>\n"
817 + " <spacer name='element1'></spacer>\n"
818 + " <span name='element1'></span>\n"
819 + " <strike name='element1'></strike>\n"
820 + " <strong name='element1'></strong>\n"
821 + " <style name='element1'></style>\n"
822 + " <sub name='element1'></sub>\n"
823 + " <sup name='element1'></sup>\n"
824 + " <table name='element1'>\n"
825 + " <colgroup name='element1'>\n"
826 + " <col name='element1'></col>\n"
827 + " </colgroup>\n"
828 + " <thead name='element1'>\n"
829 + " <tr name='element1'>\n"
830 + " <th name='element1'></th>\n"
831 + " </tr>\n"
832 + " </thead>\n"
833 + " <tbody name='element1'>\n"
834 + " <tr name='element1'>\n"
835 + " <td name='element1'></td>\n"
836 + " </tr>\n"
837 + " </tbody>\n"
838 + " <tfoot name='element1'></tfoot>\n"
839 + " </table>\n"
840 + " <textarea name='element1'></textarea>\n"
841 + " <tt name='element1'></tt>\n"
842 + " <time name='element1'></time>\n"
843
844 + " <u name='element1'></u>\n"
845 + " <ul name='element1'></ul>\n"
846 + " <var name='element1'></var>\n"
847 + " <video name='element1'></video>\n"
848 + " <wbr name='element1'>\n"
849 + " <xmp name='element1'></xmp>\n"
850 + "</body></html>";
851
852 loadPageVerifyTitle2(html);
853 }
854
855
856
857
858 @Test
859 @Alerts({"2-2", "3-3", "4-4", "5-5", "6-6", "7-7", "8-8", "9-9", "10-10", "11-11", "10-10"})
860 public void elementsByName_changedAfterGet() throws Exception {
861 final String html = DOCTYPE_HTML
862 + "<html><head>\n"
863 + "<script>\n"
864 + LOG_TITLE_FUNCTION
865 + " function test() {\n"
866
867 + " var collection1 = window.image1;\n"
868 + " var collection2 = image1;\n"
869 + " if (!collection1) {\n"
870 + " collection1 = [];\n"
871 + " }\n"
872 + " if (!collection2) {\n"
873 + " collection2 = [];\n"
874 + " }\n"
875 + " log(collection1.length + '-' + collection2.length);\n"
876
877
878 + " var newImage1 = document.createElement('img');\n"
879 + " newImage1.name = 'image1';\n"
880 + " document.getElementById('outer1').appendChild(newImage1);\n"
881 + " log(collection1.length + '-' + collection2.length);\n"
882
883
884 + " var newImage2 = document.createElement('img');\n"
885 + " newImage2.name = 'image1';\n"
886 + " document.getElementById('outer2').insertBefore(newImage2, null);\n"
887 + " log(collection1.length + '-' + collection2.length);\n"
888
889
890 + " var newImage3 = document.createElement('img');\n"
891 + " newImage3.name = 'image1';\n"
892 + " document.getElementById('outer3').replaceChild(newImage3, document.getElementById('inner3'));\n"
893 + " log(collection1.length + '-' + collection2.length);\n"
894
895
896 + " document.getElementById('outer4').outerHTML = '<img name=\"image1\">';\n"
897 + " log(collection1.length + '-' + collection2.length);\n"
898
899
900 + " document.getElementById('outer5').innerHTML = '<img name=\"image1\">';\n"
901 + " log(collection1.length + '-' + collection2.length);\n"
902
903
904 + " document.getElementById('outer6').insertAdjacentHTML('beforeend', '<img name=\"image1\">');\n"
905 + " log(collection1.length + '-' + collection2.length);\n"
906
907
908 + " document.getElementById('image3').setAttribute('name', 'image1');\n"
909 + " log(collection1.length + '-' + collection2.length);\n"
910
911
912 + " var newAttr = document.createAttribute('name');\n"
913 + " newAttr.nodeValue = 'image1';\n"
914 + " document.getElementById('image4').setAttributeNode(newAttr);\n"
915 + " log(collection1.length + '-' + collection2.length);\n"
916
917
918 + " document.getElementById('image5').setAttributeNS(null, 'name', 'image1');\n"
919 + " log(collection1.length + '-' + collection2.length);\n"
920
921
922 + " document.getElementById('outer1').removeChild(newImage1);\n"
923 + " log(collection1.length + '-' + collection2.length);\n"
924 + " }\n"
925 + "</script></head><body onload='test()'>\n"
926 + " <img name='image1'>\n"
927 + " <img name='image1'>\n"
928 + " <div id='outer1'></div>\n"
929 + " <div id='outer2'></div>\n"
930 + " <div id='outer3'><div id='inner3'></div></div>\n"
931 + " <div id='outer4'></div>\n"
932 + " <div id='outer5'></div>\n"
933 + " <div id='outer6'></div>\n"
934 + " <img id='image2'>\n"
935 + " <img id='image3'>\n"
936 + " <img id='image4'>\n"
937 + " <img id='image5'>\n"
938 + "</body></html>";
939
940 loadPageVerifyTitle2(html);
941 }
942
943
944
945
946 @Test
947 @Alerts({"2-2", "3-3"})
948 public void elementsByName_changedAfterGet2() throws Exception {
949 final String html = DOCTYPE_HTML
950 + "<html><head>\n"
951 + "<script>\n"
952 + LOG_TITLE_FUNCTION
953 + " function test() {\n"
954
955 + " var collection1 = window.image1;\n"
956 + " var collection2 = image1;\n"
957 + " if (!collection1) {\n"
958 + " collection1 = [];\n"
959 + " }\n"
960 + " if (!collection2) {\n"
961 + " collection2 = [];\n"
962 + " }\n"
963 + " log(collection1.length + '-' + collection2.length);\n"
964
965
966 + " document.getElementById('image2').name = 'image1';\n"
967 + " log(collection1.length + '-' + collection2.length);\n"
968 + " }\n"
969 + "</script></head><body onload='test()'>\n"
970 + " <img name='image1'>\n"
971 + " <img name='image1'>\n"
972 + " <img id='image2'>\n"
973 + "</body></html>";
974
975 loadPageVerifyTitle2(html);
976 }
977
978
979
980
981 @Test
982 @Alerts({"form1", "form1", "f1", "f1", "input1", "input1", "anchor1", "anchor1", "image1",
983 "image1", "element1", "element1"})
984 public void elementsById() throws Exception {
985 final String html = DOCTYPE_HTML
986 + "<html><head>\n"
987 + "<script>\n"
988 + LOG_TITLE_FUNCTION
989 + " function test() {\n"
990 + " log(window.form1.id);\n"
991 + " log(form1.id);\n"
992 + " log(window.frame1.name);\n"
993 + " log(frame1.name);\n"
994 + " log(window.input1.id);\n"
995 + " log(input1.id);\n"
996 + " log(window.anchor1.id);\n"
997 + " log(anchor1.id);\n"
998 + " log(window.image1.id);\n"
999 + " log(image1.id);\n"
1000 + " log(window.element1.id);\n"
1001 + " log(element1.id);\n"
1002 + " }\n"
1003 + "</script></head><body onload='test()'>\n"
1004 + " <form id='form1'></form>\n"
1005 + " <iframe id='frame1' name='f1'></iframe>\n"
1006 + " <input type='text' id='input1' value='1'/>\n"
1007 + " <a id='anchor1'></a>\n"
1008 + " <img id='image1'>\n"
1009 + " <div id='element1'></table>\n"
1010 + "</body></html>";
1011
1012 loadPageVerifyTitle2(html);
1013 }
1014
1015
1016
1017
1018 @Test
1019 @Alerts({"f1", "f1"})
1020 public void frameById() throws Exception {
1021 final String html = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\""
1022 + "\"http://www.w3.org/TR/html4/frameset.dtd\">\n"
1023 + "<html><head>\n"
1024 + "<script>\n"
1025 + LOG_TITLE_FUNCTION
1026 + " function test() {\n"
1027 + " log(window.frame1.name);\n"
1028 + " log(frame1.name);\n"
1029 + " }\n"
1030 + "</script></head>\n"
1031 + "<frameset onload='test()'>\n"
1032 + " <frame src='" + URL_SECOND + "' id='frame1' name='f1'>\n"
1033 + "</frameset>\n"
1034 + "</html>";
1035
1036 final String frame = DOCTYPE_HTML
1037 + "<html><head><title>frame</title></head><body></body></html>";
1038 getMockWebConnection().setDefaultResponse(frame);
1039
1040 loadPageVerifyTitle2(html);
1041 }
1042
1043
1044
1045
1046
1047 @Test
1048 @Alerts("TypeError")
1049 public void execScript() throws Exception {
1050 final String html = DOCTYPE_HTML
1051 + "<html>\n"
1052 + "<head>\n"
1053 + "<script>\n"
1054 + LOG_TITLE_FUNCTION
1055 + " function test() {\n"
1056 + " try {\n"
1057 + " window.execScript('log(\"JavaScript\")', 'JavaScript');\n"
1058 + " window.execScript('log(\"JScript\")', 'JScript');\n"
1059 + " try {\n"
1060 + " window.execScript('log(\"VBScript\")', 'VBScript');\n"
1061 + " } catch(e) { log('exception1'); }\n"
1062 + " try {\n"
1063 + " window.execScript('log(\"BadLanguage\")', 'BadLanguage');\n"
1064 + " } catch(e) {\n"
1065 + " log('exception2: ' + e.message.substr(0, 20)); // msg now contains info on error location\n"
1066 + " }\n"
1067 + " } catch(e) { logEx(e); }\n"
1068 + " }\n"
1069 + "</script>\n"
1070 + "</head>\n"
1071 + "<body onload='test()'>\n"
1072 + " <div id='div1'>blah</div>\n"
1073 + "</body>\n"
1074 + "</html>";
1075
1076 loadPageVerifyTitle2(html);
1077 }
1078
1079
1080
1081
1082 @Test
1083 @Alerts({"test2", "test"})
1084 public void onLoadFunction() throws Exception {
1085 final String html = DOCTYPE_HTML
1086 + "<html>\n"
1087 + "<head>\n"
1088 + "<script>\n"
1089 + LOG_TITLE_FUNCTION
1090 + " function test() {\n"
1091 + " log('test');\n"
1092 + " }\n"
1093 + "</script>\n"
1094 + "</head>\n"
1095 + "<body onload='test()'>\n"
1096 + "<script>\n"
1097 + " var oldOnLoad = window.onload;\n"
1098 + " window.onload = test2;\n"
1099 + " function test2() {\n"
1100 + " log('test2');\n"
1101 + " oldOnLoad();\n"
1102 + " }\n"
1103 + "</script>\n"
1104 + "</body>\n"
1105 + "</html>";
1106
1107 loadPageVerifyTitle2(html);
1108 }
1109
1110
1111
1112
1113
1114
1115 @Test
1116 @Alerts({"a", "null"})
1117 public void onloadNotAFunction() throws Exception {
1118 final String html = DOCTYPE_HTML
1119 + "<html><body>\n"
1120 + "<script>\n"
1121 + LOG_TITLE_FUNCTION
1122 + "window.onload = new function() {log('a')};\n"
1123 + "window.onload = undefined;\n"
1124 + "log(window.onload);\n"
1125 + "</script></body></html>";
1126
1127 loadPageVerifyTitle2(html);
1128 }
1129
1130
1131
1132
1133 @Test
1134 @Alerts({"false", "false", "test1", "test2", "onload"})
1135 public void addOnLoadEventListener() throws Exception {
1136 final String html = DOCTYPE_HTML
1137 + "<html>\n"
1138 + "<head>\n"
1139 + "<script>\n"
1140 + LOG_TITLE_FUNCTION
1141 + " function test1() {log('test1');}\n"
1142 + " function test2() {log('test2');}\n"
1143 + " function test3() {log('test3');}\n"
1144 + " log(window.addEventListener == null);\n"
1145 + " log(window.removeEventListener == null);\n"
1146 + " window.addEventListener('load', test1, true);\n"
1147 + " window.addEventListener('load', test1, true);\n"
1148 + " window.addEventListener('load', test2, true);\n"
1149 + " window.addEventListener('load', test3, true);\n"
1150 + " window.removeEventListener('load', test3, true);\n"
1151 + "</script></head>\n"
1152 + "<body onload='log(\"onload\")'></body></html>";
1153
1154 loadPageVerifyTitle2(html);
1155 }
1156
1157
1158
1159
1160 @Test
1161 @Alerts({"true", "true", "TypeError", "onload"})
1162 public void attachOnLoadEvent() throws Exception {
1163 final String html = DOCTYPE_HTML
1164 + "<html>\n"
1165 + "<head>\n"
1166 + "<script>\n"
1167 + LOG_TITLE_FUNCTION
1168 + " function test1(_e) {log('test1, param null: ' + (_e == null));}\n"
1169 + " function test2() {log('test2');}\n"
1170 + " function test3() {log('test3');}\n"
1171 + " log(window.attachEvent == null);\n"
1172 + " log(window.detachEvent == null);\n"
1173 + " try {\n"
1174 + " window.attachEvent('onload', test1);\n"
1175 + " window.attachEvent('onload', test1);\n"
1176 + " window.attachEvent('onload', test2);\n"
1177 + " window.attachEvent('onload', test3);\n"
1178 + " window.detachEvent('onload', test3);\n"
1179 + " } catch(e) { logEx(e); }\n"
1180 + "</script></head>\n"
1181 + "<body onload='log(\"onload\")'></body></html>";
1182
1183 loadPageVerifyTitle2(html);
1184 }
1185
1186
1187
1188
1189 @Test
1190 @Alerts("TypeError")
1191 public void detachEventInAttachEvent() throws Exception {
1192 final String html = DOCTYPE_HTML
1193 + "<html>\n"
1194 + "<head>\n"
1195 + "<script>\n"
1196 + LOG_TITLE_FUNCTION
1197 + "function test() {\n"
1198 + " window.detachEvent('onload', test);\n"
1199 + " log('detached');\n"
1200 + "}\n"
1201 + "try {\n"
1202 + " window.attachEvent('onload', test);\n"
1203 + "} catch(e) { logEx(e); }\n"
1204 + "</script></head>\n"
1205 + "<body></body></html>";
1206
1207 loadPageVerifyTitle2(html);
1208 }
1209
1210
1211
1212
1213
1214
1215 @Test
1216 @Alerts({"window.name before: ", "window.name after: main"})
1217 public void windowName() throws Exception {
1218 shutDownAll();
1219
1220 final String html = DOCTYPE_HTML
1221 + "<html>\n"
1222 + "<head></head>\n"
1223 + "<body>\n"
1224 + "<script>\n"
1225 + LOG_TITLE_FUNCTION
1226 + " log('window.name before: ' + window.name);\n"
1227 + " window.name = 'main';\n"
1228 + " log('window.name after: ' + window.name);\n"
1229 + "</script>\n"
1230 + "</body>\n"
1231 + "</html>";
1232
1233 loadPageVerifyTitle2(html);
1234 }
1235
1236
1237
1238
1239
1240 @Test
1241 @Alerts({"number", "number", "number", "number"})
1242 public void viewport() throws Exception {
1243 final String html = DOCTYPE_HTML
1244 + "<html>\n"
1245 + "<head></head>\n"
1246 + "<body>\n"
1247 + "<script>\n"
1248 + LOG_TITLE_FUNCTION
1249 + " log(typeof window.innerWidth);\n"
1250 + " log(typeof window.innerHeight);\n"
1251 + " log(typeof window.outerWidth);\n"
1252 + " log(typeof window.outerHeight);\n"
1253 + "</script>\n"
1254 + "</body>\n"
1255 + "</html>";
1256
1257 loadPageVerifyTitle2(html);
1258 }
1259
1260
1261
1262
1263
1264 @Test
1265 @Alerts("§§URL§§")
1266 public void openWindow_refererHeader() throws Exception {
1267 final String firstContent = DOCTYPE_HTML
1268 + "<html><head></head>\n"
1269 + "<body>\n"
1270 + "<button id='clickme' onClick='window.open(\"" + URL_SECOND + "\");'>Click me</a>\n"
1271 + "</body></html>";
1272
1273 final String secondContent = DOCTYPE_HTML
1274 + "<html><head><title>Second</title></head><body></body></html>";
1275
1276 getMockWebConnection().setResponse(URL_SECOND, secondContent);
1277
1278 expandExpectedAlertsVariables(URL_FIRST);
1279 final String[] expectedAlerts = getExpectedAlerts();
1280 setExpectedAlerts();
1281
1282 final WebDriver driver = loadPageVerifyTitle2(firstContent);
1283
1284 driver.findElement(By.id("clickme")).click();
1285
1286 final Map<String, String> lastAdditionalHeaders = getMockWebConnection().getLastAdditionalHeaders();
1287 if (expectedAlerts.length == 0) {
1288 assertNull(lastAdditionalHeaders.get(HttpHeader.REFERER));
1289 }
1290 else {
1291 assertEquals(expectedAlerts[0], lastAdditionalHeaders.get(HttpHeader.REFERER));
1292 }
1293 }
1294
1295
1296
1297
1298 @Test
1299 @Alerts("1")
1300 public void evalScopeOtherWindow() throws Exception {
1301 final String html = DOCTYPE_HTML
1302 + "<html><body>\n"
1303 + " <iframe src='iframe.html'></iframe>\n"
1304 + "</body></html>";
1305 final String iframe = DOCTYPE_HTML
1306 + "<html><body>\n"
1307 + "<script>\n"
1308 + LOG_WINDOW_NAME_FUNCTION
1309 + " window.parent.eval('var foo = 1');\n"
1310 + " log(window.parent.foo);\n"
1311 + "</script>\n"
1312 + "</body></html>";
1313
1314 getMockWebConnection().setDefaultResponse(iframe);
1315 loadPage2(html);
1316 verifyWindowName2(getWebDriver(), getExpectedAlerts());
1317 }
1318
1319
1320
1321
1322
1323
1324 @Test
1325 @Alerts({"elementValue", "elementValue", "elementValue"})
1326 public void evalScopeLocal() throws Exception {
1327 final String html = DOCTYPE_HTML
1328 + "<html><body><form id='formtest'><input id='element' value='elementValue'/></form>\n"
1329 + "<script>\n"
1330 + LOG_TITLE_FUNCTION
1331 + "var docPatate = 'patate';\n"
1332 + "function test() {\n"
1333 + " var f = document.forms['formtest'];\n"
1334 + " log(eval(\"document.forms['formtest'].element.value\"));\n"
1335 + " log(f.element.value);\n"
1336 + " log(eval('f.element.value'));\n"
1337 + "}\n"
1338 + "test();\n"
1339 + "</script>\n"
1340 + "</body></html>";
1341
1342 loadPageVerifyTitle2(html);
1343 }
1344
1345
1346
1347
1348
1349
1350
1351 @Test
1352 @Alerts("string")
1353 public void evalScopeEvent() throws Exception {
1354 final String html = DOCTYPE_HTML
1355 + "<html><body onload='test()'><script>\n"
1356 + LOG_TITLE_FUNCTION
1357 + " function test() {\n"
1358 + " var s = 'string';\n"
1359 + " var f = 'initial';\n"
1360 + " eval('f = function() {log(s);}');\n"
1361 + " invoke(f);\n"
1362 + " }\n"
1363 + " function invoke(fn) {\n"
1364 + " fn();\n"
1365 + " }\n"
1366 + "</script></body></html>";
1367
1368 loadPageVerifyTitle2(html);
1369 }
1370
1371
1372
1373
1374 @Test
1375 @Alerts("true")
1376 public void functionEquality() throws Exception {
1377 final String html = DOCTYPE_HTML
1378 + "<html><body>\n"
1379 + "<script>\n"
1380 + LOG_TITLE_FUNCTION
1381 + " log(window.focus == window.focus);\n"
1382 + "</script>\n"
1383 + "</body></html>";
1384
1385 loadPageVerifyTitle2(html);
1386 }
1387
1388
1389
1390
1391
1392
1393 @Test
1394 @Alerts({"123", "captured"})
1395 public void captureEvents() throws Exception {
1396 final String content = DOCTYPE_HTML
1397 + "<html><head>\n"
1398 + "<script>\n"
1399 + LOG_TITLE_FUNCTION
1400 + " function t() { log('captured'); }\n"
1401 + " window.captureEvents(Event.CLICK);\n"
1402 + " window.onclick = t;\n"
1403 + "</script></head><body>\n"
1404 + "<div id='theDiv' onclick='log(123)'>foo</div>\n"
1405 + "</body></html>";
1406
1407 final WebDriver driver = loadPage2(content);
1408
1409 driver.findElement(By.id("theDiv")).click();
1410
1411 verifyTitle2(driver, getExpectedAlerts());
1412 }
1413
1414
1415
1416
1417
1418
1419 @Test
1420 @Alerts("true")
1421 public void onLoadContext() throws Exception {
1422 final String html = DOCTYPE_HTML
1423 + "<html><body>\n"
1424 + "<script>\n"
1425 + LOG_TITLE_FUNCTION
1426 + "var x = function() { log(this==window) };\n"
1427 + "window.onload = x;\n"
1428 + "</script></body></html>";
1429
1430 loadPageVerifyTitle2(html);
1431 }
1432
1433
1434
1435
1436
1437 @Test
1438 @Alerts("INPUT")
1439 public void eval() throws Exception {
1440 final String content = DOCTYPE_HTML
1441 + "<html><body>\n"
1442 + "<input type='button' id='myButton' value='Click Me' onclick='test(this)'>\n"
1443 + "<script>\n"
1444 + LOG_TITLE_FUNCTION
1445 + "function test(f) {\n"
1446 + " log(eval('f.tagName'));\n"
1447 + "}\n"
1448 + "</script>\n"
1449 + "</body></html>";
1450
1451 final WebDriver driver = loadPage2(content);
1452
1453 driver.findElement(By.id("myButton")).click();
1454 verifyTitle2(driver, getExpectedAlerts());
1455 }
1456
1457
1458
1459
1460 @Test
1461 @Alerts({"undefined", "undefined", "true"})
1462 public void undefinedProperty() throws Exception {
1463 final String html = DOCTYPE_HTML
1464 + "<html><head>\n"
1465 + "<script>\n"
1466 + LOG_TITLE_FUNCTION
1467 + " function test() {\n"
1468 + " log(window['something']);\n"
1469 + " log(typeof window['something']);\n"
1470 + " log(typeof window['something']=='undefined');\n"
1471 + " }\n"
1472 + "</script></head><body onload='test()'>\n"
1473 + "</body></html>";
1474
1475 loadPageVerifyTitle2(html);
1476 }
1477
1478
1479
1480
1481 @Test
1482 @Alerts("First")
1483 public void frames() throws Exception {
1484 final String html = DOCTYPE_HTML
1485 + "<html><head><title>First§</title></head>\n"
1486 + "<frameset id='fs' rows='20%,*'>\n"
1487 + " <frame name='top' src='" + URL_SECOND + "' />\n"
1488 + " <frame name='bottom' src='about:blank' />\n"
1489 + "</frameset>\n"
1490 + "</html>";
1491
1492 final String frameContent = DOCTYPE_HTML
1493 + "<html><head><title>TopFrame</title>\n"
1494 + "<script>\n"
1495 + "function doTest() {\n"
1496 + " var bottomFrame = window.top.frames['bottom'];\n"
1497 + " bottomFrame.location = 'about:blank';\n"
1498 + "}</script>\n"
1499 + "</head>\n"
1500 + "<body onload='doTest()'></body></html>";
1501
1502 getMockWebConnection().setResponse(URL_SECOND, frameContent);
1503
1504 loadPageVerifyTitle2(html);
1505 }
1506
1507
1508
1509
1510 @Test
1511 @Alerts("true")
1512 public void openWindow_numericName() throws Exception {
1513 final String html = DOCTYPE_HTML
1514 + "<html><head>\n"
1515 + "<script>\n"
1516 + LOG_TITLE_FUNCTION
1517 + "function test() {\n"
1518 + " var w1 = window.open('about:blank', 1);\n"
1519 + " log(w1 != null);\n"
1520 + "}\n"
1521 + "</script></head><body onload='test()'>\n"
1522 + "<iframe name='myFrame' id='myFrame'></iframe>\n"
1523 + "</body></html>";
1524
1525 loadPageVerifyTitle2(html);
1526 }
1527
1528
1529
1530
1531 @Test
1532 @Alerts("about:blank")
1533 public void openWindow_aboutblank_location() throws Exception {
1534 final String html = DOCTYPE_HTML
1535 + "<html><head><script>\n"
1536 + LOG_TITLE_FUNCTION
1537 + "function test() {\n"
1538 + " var win = window.open('about:blank', 'test');\n"
1539 + " log(win.location);\n"
1540 + "}\n"
1541 + "</script></head>\n"
1542 + "<body onload='test()'>\n"
1543 + "</body></html>";
1544
1545 loadPageVerifyTitle2(html);
1546 }
1547
1548
1549
1550
1551 @Test
1552 @Alerts("about:blank")
1553 public void openWindow_empty_location() throws Exception {
1554 final String html = DOCTYPE_HTML
1555 + "<html><head>\n"
1556 + "<script>\n"
1557 + LOG_TITLE_FUNCTION
1558 + "function test() {\n"
1559 + " var win = window.open('', 'test');\n"
1560 + " log(win.location);\n"
1561 + "}\n"
1562 + "</script></head>\n"
1563 + "<body onload='test()'>\n"
1564 + "</body></html>";
1565
1566 loadPageVerifyTitle2(html);
1567 }
1568
1569
1570
1571
1572 @Test
1573 @Alerts("§§URL§§img.gif")
1574 public void openWindow_aboutblank_img() throws Exception {
1575 final String html = DOCTYPE_HTML
1576 + "<html><head><script>\n"
1577 + LOG_TITLE_FUNCTION
1578 + "function test() {\n"
1579 + " var win = window.open('about:blank', 'test', '');\n"
1580 + " win.document.open();\n"
1581 + " win.document.writeln('<img id=\"myImg\" src=\"img.gif\" />');\n"
1582 + " win.document.close();\n"
1583 + " log(win.document.getElementById('myImg').src);\n"
1584 + "}\n"
1585 + "</script></head>\n"
1586 + "<body onload='test()'>\n"
1587 + "</body></html>";
1588 getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found",
1589 org.htmlunit.util.MimeType.TEXT_HTML);
1590
1591 expandExpectedAlertsVariables(URL_FIRST);
1592 loadPageVerifyTitle2(html);
1593 }
1594
1595
1596
1597
1598 @Test
1599 @Alerts("§§URL§§img.gif")
1600 public void openWindow_aboutblank_document_img() throws Exception {
1601 final String html = DOCTYPE_HTML
1602 + "<html><head><script>\n"
1603 + LOG_TITLE_FUNCTION
1604 + "function test() {\n"
1605 + " var win = window.open('about:blank', 'test');\n"
1606 + " win.document.open();\n"
1607 + " win.document.writeln('<html><head></head><body><img id=\"myImg\" src=\"img.gif\" /></body></html>');\n"
1608 + " win.document.close();\n"
1609 + " win.focus();\n"
1610 + " log(win.document.getElementById('myImg').src);\n"
1611 + "}\n"
1612 + "</script></head>\n"
1613 + "<body onload='test()'>\n"
1614 + "</body></html>";
1615 getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found",
1616 org.htmlunit.util.MimeType.TEXT_HTML);
1617
1618 expandExpectedAlertsVariables(URL_FIRST);
1619 loadPageVerifyTitle2(html);
1620 }
1621
1622
1623
1624
1625 @Test
1626 @Alerts("§§URL§§img.gif")
1627 public void openWindow_empty_img() throws Exception {
1628 final String html = DOCTYPE_HTML
1629 + "<html><head>\n"
1630 + "<script>\n"
1631 + LOG_TITLE_FUNCTION
1632 + "function test() {\n"
1633 + " var win = window.open('', 'test');\n"
1634 + " win.document.open();\n"
1635 + " win.document.writeln('<img id=\"myImg\" src=\"img.gif\" />');\n"
1636 + " win.document.close();\n"
1637 + " log(win.document.getElementById('myImg').src);\n"
1638 + "}\n"
1639 + "</script></head>\n"
1640 + "<body onload='test()'>\n"
1641 + "</body></html>";
1642 getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found",
1643 org.htmlunit.util.MimeType.TEXT_HTML);
1644
1645 expandExpectedAlertsVariables(URL_FIRST);
1646 loadPageVerifyTitle2(html);
1647 }
1648
1649
1650
1651
1652 @Test
1653 @Alerts("true")
1654 public void stop() throws Exception {
1655 final String html = DOCTYPE_HTML
1656 + "<html><head>\n"
1657 + "<script>\n"
1658 + LOG_TITLE_FUNCTION
1659 + "function test() {\n"
1660 + " try {\n"
1661 + " window.stop();\n"
1662 + " log(true);\n"
1663 + " } catch(e) { logEx(e); }\n"
1664 + "}\n"
1665 + "</script></head><body onload='test()'>\n"
1666 + "</body></html>";
1667
1668 loadPageVerifyTitle2(html);
1669 }
1670
1671
1672
1673
1674 @Test
1675 public void open() throws Exception {
1676 final String firstHtml = DOCTYPE_HTML
1677 + "<html><head></head>\n"
1678 + "<body>\n"
1679 + "<button id='clickme' onClick='window.open(new String(\"" + URL_SECOND + "\"));'>Click me</a>\n"
1680 + "</body></html>";
1681
1682 final String secondHtml = DOCTYPE_HTML
1683 + "<html><head><title>Second</title></head><body></body></html>";
1684
1685 getMockWebConnection().setResponse(URL_SECOND, secondHtml);
1686
1687 final WebDriver driver = loadPageVerifyTitle2(firstHtml);
1688
1689 driver.findElement(By.id("clickme")).click();
1690 }
1691
1692
1693
1694
1695 @Test
1696 @Alerts("First")
1697 public void navigate() throws Exception {
1698 final String firstContent = DOCTYPE_HTML
1699 + "<html><head><title>First</title><script>\n"
1700 + " function test() {\n"
1701 + " if (window.navigate) {\n"
1702 + " window.navigate('" + URL_SECOND + "');\n"
1703 + " }\n"
1704 + " }\n"
1705 + "</script></head><body onload='test()'>\n"
1706 + "</body></html>";
1707
1708 final String secondContent = DOCTYPE_HTML
1709 + "<html><head><title>Second</title></head><body></body></html>";
1710
1711 getMockWebConnection().setResponse(URL_SECOND, secondContent);
1712
1713 final WebDriver driver = loadPage2(firstContent, URL_FIRST);
1714 assertTitle(driver, getExpectedAlerts()[0]);
1715 }
1716
1717
1718
1719
1720 @Test
1721 @Alerts("1")
1722 public void devicePixelRatio() throws Exception {
1723 final String html = DOCTYPE_HTML
1724 + "<html><head><script>\n"
1725 + LOG_TITLE_FUNCTION
1726 + " function test() {\n"
1727 + " log(window.devicePixelRatio);\n"
1728 + " }\n"
1729 + "</script></head><body onload='test()'>\n"
1730 + "</body></html>";
1731
1732 loadPageVerifyTitle2(html);
1733 }
1734
1735
1736
1737
1738 @Test
1739 @Alerts(DEFAULT = "undefined",
1740 CHROME = "true",
1741 EDGE = "true")
1742 public void offscreenBuffering() throws Exception {
1743 final String html = DOCTYPE_HTML
1744 + "<html><head>\n"
1745 + "<script>\n"
1746 + LOG_TITLE_FUNCTION
1747 + " function test() {\n"
1748 + " log(window.offscreenBuffering);\n"
1749 + " }\n"
1750 + "</script></head><body onload='test()'>\n"
1751 + "</body></html>";
1752
1753 loadPageVerifyTitle2(html);
1754 }
1755
1756
1757
1758
1759 @Test
1760 @Alerts("TypeError")
1761 public void getComputedStyle() throws Exception {
1762 final String html = DOCTYPE_HTML
1763 + "<html><head><script>\n"
1764 + LOG_TITLE_FUNCTION
1765 + " function test() {\n"
1766 + " try {\n"
1767 + " getComputedStyle(void 0);\n"
1768 + " log('no exception');\n"
1769 + " } catch(e) { logEx(e) }\n"
1770 + " }\n"
1771 + "</script></head><body onload='test()'>\n"
1772 + "</body></html>";
1773
1774 loadPageVerifyTitle2(html);
1775 }
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787 @Test
1788 @Alerts({"window DOMContentLoaded 1 capture",
1789 "window DOMContentLoaded 2 capture",
1790 "document DOMContentLoaded 1",
1791 "document DOMContentLoaded 1 capture",
1792 "document DOMContentLoaded 2",
1793 "document DOMContentLoaded 2 capture",
1794 "window DOMContentLoaded 1",
1795 "window DOMContentLoaded 2",
1796 "window at load 1",
1797 "window at load 1 capture",
1798 "window at load 2",
1799 "onload 2",
1800 "window at load 2 capture",
1801 "after"})
1802 public void onload() throws Exception {
1803 final String html = DOCTYPE_HTML
1804 + "<html><head>\n"
1805 + "<script>\n"
1806 + " function log(msg) {\n"
1807 + " window.parent.document.title += msg + ';';\n"
1808 + " }\n"
1809
1810
1811
1812
1813
1814
1815
1816 + " window.addEventListener('load', function () { log('window at load 1') })\n"
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828 + " window.addEventListener('load', function () { log('window at load 1 capture') }, true)\n"
1829
1830 + " window.addEventListener('DOMContentLoaded', function () { log('window DOMContentLoaded 1') })\n"
1831 + " window.addEventListener('DOMContentLoaded', "
1832 + "function () { log('window DOMContentLoaded 1 capture') }, true)\n"
1833
1834 + " document.addEventListener('load', function () { log('document at load 1') })\n"
1835 + " document.addEventListener('load', function () { log('document at load 1 capture') }, true)\n"
1836 + " document.addEventListener('DOMContentLoaded', function () { log('document DOMContentLoaded 1') })\n"
1837 + " document.addEventListener('DOMContentLoaded', "
1838 + "function () { log('document DOMContentLoaded 1 capture') }, true)\n"
1839 + "</script>\n"
1840 + "</head>\n"
1841 + "<body>\n"
1842 + "<script>\n"
1843 + " window.addEventListener('load', function () { log('window at load 2') })\n"
1844
1845
1846 + " window.onload = function () { log('onload 2') }\n"
1847 + " window.addEventListener('load', function () { log('window at load 2 capture') }, true)\n"
1848 + " window.addEventListener('DOMContentLoaded', function () { log('window DOMContentLoaded 2') })\n"
1849 + " window.addEventListener('DOMContentLoaded', "
1850 + "function () { log('window DOMContentLoaded 2 capture') }, true)\n"
1851
1852 + " document.addEventListener('load', function () { log('document at load 2 capture') }, true)\n"
1853 + " document.addEventListener('DOMContentLoaded', function () { log('document DOMContentLoaded 2') })\n"
1854 + " document.addEventListener('DOMContentLoaded', "
1855 + "function () { log('document DOMContentLoaded 2 capture') }, true)\n"
1856
1857
1858 + " window.addEventListener('load', "
1859 + "function (event) { var x = event; "
1860 + "window.setTimeout(function () { log('after', x.eventPhase) }, 100) }, true)\n"
1861 + "</script>\n"
1862 + "</body></html>";
1863
1864 final WebDriver driver = loadPage2(html);
1865 Thread.sleep(200);
1866 final String text = driver.getTitle().trim().replaceAll(";", "\n").trim();
1867 assertEquals(String.join("\n", getExpectedAlerts()), text);
1868 }
1869
1870
1871
1872
1873
1874
1875
1876
1877 @Test
1878 @Alerts({"document at load capture",
1879 "element 1 onload",
1880 "window at error capture",
1881 "document at error capture",
1882 "element 2 onerror",
1883 "document DOMContentLoaded",
1884 "window DOMContentLoaded",
1885 "window at load",
1886 "window at load capture",
1887 "body onload"})
1888 @HtmlUnitNYI(CHROME = {"element 1 onload",
1889 "element 2 onerror",
1890 "document DOMContentLoaded",
1891 "window DOMContentLoaded",
1892 "window at load",
1893 "window at load capture",
1894 "body onload"},
1895 EDGE = {"element 1 onload",
1896 "element 2 onerror",
1897 "document DOMContentLoaded",
1898 "window DOMContentLoaded",
1899 "window at load",
1900 "window at load capture",
1901 "body onload"},
1902 FF = {"element 1 onload",
1903 "element 2 onerror",
1904 "document DOMContentLoaded",
1905 "window DOMContentLoaded",
1906 "window at load",
1907 "window at load capture",
1908 "body onload"},
1909 FF_ESR = {"element 1 onload",
1910 "element 2 onerror",
1911 "document DOMContentLoaded",
1912 "window DOMContentLoaded",
1913 "window at load",
1914 "window at load capture",
1915 "body onload"})
1916 public void onloadScript() throws Exception {
1917 getMockWebConnection().setResponse(URL_SECOND, "");
1918
1919 final String html = DOCTYPE_HTML
1920 + "<html><head>\n"
1921 + "<script>\n"
1922 + " function log(msg) {\n"
1923 + " window.parent.document.title += msg + ';';\n"
1924 + " }\n"
1925
1926 + " window.addEventListener('load', function () { log('window at load') })\n"
1927 + " window.addEventListener('load', function () { log('window at load capture') }, true)\n"
1928 + " window.addEventListener('error', function () { log('window at error') })\n"
1929 + " window.addEventListener('error', function () { log('window at error capture') }, true)\n"
1930 + " window.addEventListener('DOMContentLoaded', function () { log('window DOMContentLoaded') })\n"
1931
1932 + " document.addEventListener('load', function () { log('document at load') })\n"
1933 + " document.addEventListener('load', function () { log('document at load capture') }, true)\n"
1934 + " document.addEventListener('error', function () { log('document at error') })\n"
1935 + " document.addEventListener('error', function () { log('document at error capture') }, true)\n"
1936 + " document.addEventListener('DOMContentLoaded', function () { log('document DOMContentLoaded') })\n"
1937
1938 + "</script>\n"
1939 + "</head>\n"
1940 + "<body onload='log(\"body onload\")'>\n"
1941 + " <script src='" + URL_SECOND + "' onload='log(\"element 1 onload\")' "
1942 + "onerror='log(\"element 1 onerror\")'></script>\n"
1943 + " <script src='missing.txt' onload='log(\"element 2 onload\")' "
1944 + "onerror='log(\"element 2 onerror\")'></script>\n"
1945 + "</body></html>";
1946 getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found",
1947 org.htmlunit.util.MimeType.TEXT_HTML);
1948
1949 final WebDriver driver = loadPage2(html);
1950 Thread.sleep(200);
1951 final String text = driver.getTitle().trim().replaceAll(";", "\n").trim();
1952 assertEquals(String.join("\n", getExpectedAlerts()), text);
1953 }
1954
1955
1956
1957
1958
1959
1960
1961
1962 @Test
1963 @Alerts(DEFAULT = {"img2: window at error capture",
1964 "img2: document at error capture",
1965 "img2: element 2 onerror",
1966 "#document: document DOMContentLoaded",
1967 "#document: window DOMContentLoaded",
1968 "img1: document at load capture",
1969 "img1: element 1 onload",
1970 "#document: window at load",
1971 "#document: window at load capture",
1972 "#document: body onload"},
1973 CHROME = {"#document: document DOMContentLoaded",
1974 "#document: window DOMContentLoaded",
1975 "img2: window at error capture",
1976 "img2: document at error capture",
1977 "img2: element 2 onerror",
1978 "img1: document at load capture",
1979 "img1: element 1 onload",
1980 "#document: window at load",
1981 "#document: window at load capture",
1982 "#document: body onload"})
1983 public void onloadImg() throws Exception {
1984 final URL urlImage = new URL(URL_FIRST, "img.jpg");
1985 try (InputStream is = getClass().getClassLoader().getResourceAsStream("testfiles/tiny-jpg.img")) {
1986 final byte[] directBytes = IOUtils.toByteArray(is);
1987 getMockWebConnection().setResponse(urlImage, directBytes, 200, "ok", "image/jpg", Collections.emptyList());
1988 }
1989
1990 final String html = DOCTYPE_HTML
1991 + "<html><head>\n"
1992 + "<script>\n"
1993 + " function log(msg, target) {\n"
1994 + " if (target) msg = (target.id ? target.id : target.nodeName) + ': ' + msg\n"
1995 + " window.parent.document.title += msg + ';';\n"
1996 + " }\n"
1997
1998 + " window.addEventListener('load', function (event) { log('window at load', event.target) })\n"
1999 + " window.addEventListener('load', function (event) { "
2000 + "log('window at load capture', event.target) }, true)\n"
2001 + " window.addEventListener('error', function (event) { log('window at error', event.target) })\n"
2002 + " window.addEventListener('error', function (event) { "
2003 + "log('window at error capture', event.target) }, true)\n"
2004 + " window.addEventListener('DOMContentLoaded', function (event) { "
2005 + "log('window DOMContentLoaded', event.target) })\n"
2006
2007 + " document.addEventListener('load', function (event) { log('document at load', event.target) })\n"
2008 + " document.addEventListener('load', function (event) { "
2009 + "log('document at load capture', event.target) }, true)\n"
2010 + " document.addEventListener('error', function (event) { log('document at error', event.target) })\n"
2011 + " document.addEventListener('error', function (event) { "
2012 + "log('document at error capture', event.target) }, true)\n"
2013 + " document.addEventListener('DOMContentLoaded', function (event) { "
2014 + "log('document DOMContentLoaded', event.target) })\n"
2015
2016 + "</script>\n"
2017 + "</head>\n"
2018 + "<body onload='log(\"body onload\", document)'>\n"
2019 + " <img id='img1' src='" + urlImage + "' onload='log(\"element 1 onload\", this)' "
2020 + "onerror='log(\"element 1 onerror\", this)'>\n"
2021 + " <img id='img2' src='' onload='log(\"element 2 onload\", this)' "
2022 + "onerror='log(\"element 2 onerror\", this)'>\n"
2023
2024 + "</body></html>";
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035 final Comparator<String> sorter = Comparator.comparing(s -> StringUtils.substringBefore(s, ":"));
2036
2037 final WebDriver driver = loadPage2(html);
2038 Thread.sleep(200);
2039 final String text = Pattern.compile(";").splitAsStream(driver.getTitle())
2040 .map(String::trim).sorted(sorter).collect(Collectors.joining("\n"));
2041 final String expected = Arrays.stream(getExpectedAlerts()).sorted(sorter).collect(Collectors.joining("\n"));
2042 assertEquals(expected, text);
2043 }
2044
2045
2046
2047
2048
2049
2050 @Test
2051 @Alerts({"framing window DOMContentLoaded 1 capture",
2052 "framing document DOMContentLoaded 1",
2053 "framing document DOMContentLoaded 1 capture",
2054 "framing window DOMContentLoaded 1",
2055 "window DOMContentLoaded 1 capture",
2056 "window DOMContentLoaded 2 capture",
2057 "document DOMContentLoaded 1",
2058 "document DOMContentLoaded 1 capture",
2059 "document DOMContentLoaded 2",
2060 "document DOMContentLoaded 2 capture",
2061 "window DOMContentLoaded 1",
2062 "window DOMContentLoaded 2",
2063 "window at load 1",
2064 "window at load 1 capture",
2065 "window at load 2",
2066 "onload 2",
2067 "window at load 2 capture",
2068 "framing document at load 1 capture",
2069 "frame onload",
2070 "framing window at load 1",
2071 "framing window at load 1 capture",
2072 "frameset onload",
2073 "after"})
2074 public void onloadFrame() throws Exception {
2075 final String content = DOCTYPE_HTML
2076 + "<html><head>\n"
2077 + "<script>\n"
2078 + " function log(msg) {\n"
2079 + " window.parent.document.title += msg + ';';\n"
2080 + " }\n"
2081
2082 + " window.addEventListener('load', function () { log('window at load 1') })\n"
2083
2084 + " window.addEventListener('load', function () { log('window at load 1 capture') }, true)\n"
2085 + " window.addEventListener('DOMContentLoaded', function () { log('window DOMContentLoaded 1') })\n"
2086 + " window.addEventListener('DOMContentLoaded', "
2087 + "function () { log('window DOMContentLoaded 1 capture') }, true)\n"
2088
2089 + " document.addEventListener('load', function () { log('document at load 1') })\n"
2090 + " document.addEventListener('load', function () { log('document at load 1 capture') }, true)\n"
2091 + " document.addEventListener('DOMContentLoaded', function () { log('document DOMContentLoaded 1') })\n"
2092 + " document.addEventListener('DOMContentLoaded', "
2093 + "function () { log('document DOMContentLoaded 1 capture') }, true)\n"
2094 + "</script>\n"
2095 + "</head>\n"
2096 + "<body >\n"
2097 + "<script>\n"
2098 + " window.addEventListener('load', function () { log('window at load 2') })\n"
2099 + " window.onload = function () { log('onload 2') }\n"
2100 + " window.addEventListener('load', function () { log('window at load 2 capture') }, true)\n"
2101 + " window.addEventListener('DOMContentLoaded', function () { log('window DOMContentLoaded 2') })\n"
2102 + " window.addEventListener('DOMContentLoaded', "
2103 + "function () { log('window DOMContentLoaded 2 capture') }, true)\n"
2104
2105 + " document.addEventListener('load', function () { log('document at load 2 capture') }, true)\n"
2106 + " document.addEventListener('DOMContentLoaded', function () { log('document DOMContentLoaded 2') })\n"
2107 + " document.addEventListener('DOMContentLoaded', "
2108 + "function () { log('document DOMContentLoaded 2 capture') }, true)\n"
2109
2110 + " window.addEventListener('load', "
2111 + "function (event) { var x = event; "
2112 + "window.setTimeout(function () { log('after', x.eventPhase) }, 100) }, true)\n"
2113 + "</script>\n"
2114 + "</body></html>";
2115
2116 getMockWebConnection().setDefaultResponse(content);
2117
2118 final String html = DOCTYPE_HTML
2119 + "<html><head>\n"
2120 + "<script>\n"
2121 + " function log(msg) {\n"
2122 + " window.document.title += msg + ';';\n"
2123 + " }\n"
2124
2125 + " window.addEventListener('load', function () { log('framing window at load 1') })\n"
2126 + " window.addEventListener('load', function () { log('framing window at load 1 capture') }, true)\n"
2127 + " window.addEventListener('DOMContentLoaded', "
2128 + "function () { log('framing window DOMContentLoaded 1') })\n"
2129 + " window.addEventListener('DOMContentLoaded', "
2130 + "function () { log('framing window DOMContentLoaded 1 capture') }, true)\n"
2131
2132
2133 + " document.addEventListener('load', "
2134 + "function () { log('framing document at load 1') })\n"
2135 + " document.addEventListener('load', "
2136 + "function () { log('framing document at load 1 capture') }, true)\n"
2137 + " document.addEventListener('DOMContentLoaded', "
2138 + "function () { log('framing document DOMContentLoaded 1') })\n"
2139 + " document.addEventListener('DOMContentLoaded', "
2140 + "function () { log('framing document DOMContentLoaded 1 capture') }, true)\n"
2141 + "</script>\n"
2142 + "</head>\n"
2143 + "<frameset onload='log(\"frameset onload\")'>\n"
2144 + "<frame src='test_onload.html' onload='log(\"frame onload\")'>\n"
2145 + "</frameset>\n"
2146 + "</html>";
2147
2148 final WebDriver driver = loadPage2(html);
2149 Thread.sleep(200);
2150 final String text = driver.getTitle().trim().replaceAll(";", "\n").trim();
2151 assertEquals(String.join("\n", getExpectedAlerts()), text);
2152 }
2153
2154
2155
2156
2157 @Test
2158 @Alerts({"function () { log(\"onload from body\") }",
2159 "function () { log(\"onload from body\") }",
2160 "function () { log(\"onload from window\") }",
2161 "function () { log(\"onload from window\") }",
2162 "null",
2163 "null",
2164 "function () { log(\"onload from body\") }",
2165 "function () { log(\"onload from body\") }",
2166 "onload from body"})
2167 public void onloadFromBody() throws Exception {
2168 final String html = DOCTYPE_HTML
2169 + "<html><head>\n"
2170 + "</head>\n"
2171 + "<body>\n"
2172 + "<script>\n"
2173 + " function log(msg) {\n"
2174 + " window.parent.document.title += ('' + msg).replace(';', '') + ';';\n"
2175 + " }\n"
2176
2177 + " document.body.onload = function () { log(\"onload from body\") };\n"
2178 + " log(document.body.onload);\n"
2179 + " log(window.onload);\n"
2180
2181 + " window.onload = function () { log(\"onload from window\") };\n"
2182 + " log(document.body.onload);\n"
2183 + " log(window.onload);\n"
2184
2185 + " window.onload = undefined;\n"
2186 + " log(document.body.onload);\n"
2187 + " log(window.onload);\n"
2188
2189 + " document.body.onload = function () { log(\"onload from body\") };\n"
2190 + " log(document.body.onload);\n"
2191 + " log(window.onload);\n"
2192
2193 + "</script>\n"
2194 + "</body></html>";
2195
2196 final WebDriver driver = loadPage2(html);
2197 final String text = driver.getTitle().trim().replaceAll(";", "\n").trim();
2198 assertEquals(String.join("\n", getExpectedAlerts()), text);
2199 }
2200
2201
2202
2203
2204 @Test
2205 @Alerts({})
2206 public void onloadListenerFromBody() throws Exception {
2207 final String html = DOCTYPE_HTML
2208 + "<html><head>\n"
2209 + "</head>\n"
2210 + "<body>\n"
2211 + "<script>\n"
2212 + " function log(msg) {\n"
2213 + " window.parent.document.title += msg + ';';\n"
2214 + " }\n"
2215
2216 + " document.body.addEventListener(\"load\", function () { log(\"onload from body\") });\n"
2217 + "</script>\n"
2218 + "</body></html>";
2219
2220 final WebDriver driver = loadPage2(html);
2221 final String text = driver.getTitle().trim().replaceAll(";", "\n").trim();
2222 assertEquals(String.join("\n", getExpectedAlerts()), text);
2223 }
2224
2225
2226
2227
2228 @Test
2229 @Alerts("onload from window")
2230 public void onloadListenerFromBodyAndWindow() throws Exception {
2231 final String html = DOCTYPE_HTML
2232 + "<html><head>\n"
2233 + "</head>\n"
2234 + "<body>\n"
2235 + "<script>\n"
2236 + " function log(msg) {\n"
2237 + " window.parent.document.title += msg + ';';\n"
2238 + " }\n"
2239
2240 + " document.body.addEventListener(\"load\", function () { log(\"onload from body\") });\n"
2241 + " window.addEventListener(\"load\", function () { log(\"onload from window\") });\n"
2242
2243 + "</script>\n"
2244 + "</body></html>";
2245
2246 final WebDriver driver = loadPage2(html);
2247 final String text = driver.getTitle().trim().replaceAll(";", "\n").trim();
2248 assertEquals(String.join("\n", getExpectedAlerts()), text);
2249 }
2250
2251
2252
2253
2254 @Test
2255 @Alerts({})
2256 public void onloadListenerFromBodyAndWindowRemoved() throws Exception {
2257 final String html = DOCTYPE_HTML
2258 + "<html><head>\n"
2259 + "</head>\n"
2260 + "<body>\n"
2261 + "<script>\n"
2262 + " function log(msg) {\n"
2263 + " window.parent.document.title += msg + ';';\n"
2264 + " }\n"
2265
2266 + " document.body.addEventListener(\"load\", function () { log(\"onload from body\") });\n"
2267 + " function evt() { log(\"onload from window\") }"
2268 + " window.addEventListener(\"load\", evt);\n"
2269 + " window.removeEventListener(\"load\", evt);\n"
2270
2271 + "</script>\n"
2272 + "</body></html>";
2273
2274 final WebDriver driver = loadPage2(html);
2275 final String text = driver.getTitle().trim().replaceAll(";", "\n").trim();
2276 assertEquals(String.join("\n", getExpectedAlerts()), text);
2277 }
2278
2279
2280
2281
2282
2283
2284
2285
2286 @Test
2287 @Alerts({"window at click 1 capture",
2288 "window at click 2 capture",
2289 "onclick 2",
2290 "i1 at click 1",
2291 "i1 at click 1 capture",
2292 "i1 at click 2",
2293 "i1 at click 2 capture",
2294 "window at click 1",
2295 "window at click 2"})
2296 public void propagation() throws Exception {
2297 final String html = DOCTYPE_HTML
2298 + "<html><head>\n"
2299 + "<script>\n"
2300 + " function log(msg) {\n"
2301 + " window.parent.document.title += msg + ';';\n"
2302 + " }\n"
2303 + "</script>\n"
2304 + "</head>\n"
2305 + "<body>\n"
2306 + " <input id='tester' type='button' value='test' onclick='log(\"onclick\")'>\n"
2307
2308 + "<script>\n"
2309 + " window.addEventListener('click', function () { log('window at click 1') })\n"
2310 + " window.addEventListener('click', function () { log('window at click 1 capture') }, true)\n"
2311 + " window.addEventListener('click', function () { log('window at click 2') })\n"
2312 + " window.addEventListener('click', function () { log('window at click 2 capture') }, true)\n"
2313
2314 + " tester.addEventListener('click', function () { log('i1 at click 1') })\n"
2315 + " tester.addEventListener('click', function () { log('i1 at click 1 capture') }, true)\n"
2316 + " tester.addEventListener('click', function () { log('i1 at click 2') })\n"
2317 + " tester.onclick = function () { log('onclick 2') }\n"
2318 + " tester.addEventListener('click', function () { log('i1 at click 2 capture') }, true)\n"
2319 + "</script>\n"
2320 + "</body></html>";
2321
2322 final WebDriver driver = loadPage2(html);
2323 driver.findElement(By.id("tester")).click();
2324
2325 final String text = driver.getTitle().trim().replaceAll(";", "\n").trim();
2326 assertEquals(String.join("\n", getExpectedAlerts()), text);
2327 }
2328
2329
2330
2331
2332
2333
2334
2335 @Test
2336 @Alerts({"window at click 1 capture",
2337 "window at click 2 capture",
2338 "d1 at click 1 capture",
2339 "d1 at click 2 capture",
2340 "d2 at click 1 capture",
2341 "d2 at click 2 capture",
2342 "d3 at click 1",
2343 "d3 onclick",
2344 "d3 at click 1 capture",
2345 "d3 at click 2",
2346 "d3 at click 2 capture",
2347 "d2 at click 1",
2348 "d2 onclick",
2349 "d2 at click 2",
2350 "d1 at click 1",
2351 "d1 onclick",
2352 "d1 at click 2",
2353 "window at click 1",
2354 "window at click 2"})
2355 public void propagationNested() throws Exception {
2356 final String html = DOCTYPE_HTML
2357 + "<html><head>\n"
2358 + "<script>\n"
2359 + " function log(msg) {\n"
2360 + " window.parent.document.title += msg + ';';\n"
2361 + " }\n"
2362 + "</script>\n"
2363 + "</head>\n"
2364 + "<body>\n"
2365 + " <div id='d1' style='width: 150px; height: 150px; background-color: blue'>\n"
2366 + " <div id='d2' style='width: 100px; height: 100px; background-color: green'>\n"
2367 + " <div id='d3' style='width: 50px; height: 50px; background-color: red'>\n"
2368 + " </div>\n"
2369 + " </div>\n"
2370 + " </div>\n"
2371
2372 + "<script>\n"
2373 + " window.addEventListener('click', function () { log('window at click 1') })\n"
2374 + " window.addEventListener('click', function () { log('window at click 1 capture') }, true)\n"
2375 + " window.addEventListener('click', function () { log('window at click 2') })\n"
2376 + " window.addEventListener('click', function () { log('window at click 2 capture') }, true)\n"
2377
2378 + " d1.addEventListener('click', function () { log('d1 at click 1') })\n"
2379 + " d1.onclick = function () { log('d1 onclick') }\n"
2380 + " d1.addEventListener('click', function () { log('d1 at click 1 capture') }, true)\n"
2381 + " d1.addEventListener('click', function () { log('d1 at click 2') })\n"
2382 + " d1.addEventListener('click', function () { log('d1 at click 2 capture') }, true)\n"
2383
2384 + " d2.addEventListener('click', function () { log('d2 at click 1') })\n"
2385 + " d2.onclick = function () { log('d2 onclick'); d2.parentNode.removeChild(d2) }\n"
2386 + " d2.addEventListener('click', function () { log('d2 at click 1 capture') }, true)\n"
2387 + " d2.addEventListener('click', function () { log('d2 at click 2') })\n"
2388 + " d2.addEventListener('click', function () { log('d2 at click 2 capture') }, true)\n"
2389
2390 + " d3.addEventListener('click', function () { log('d3 at click 1') })\n"
2391 + " d3.onclick = function () { log('d3 onclick') }\n"
2392 + " d3.addEventListener('click', function () { log('d3 at click 1 capture') }, true)\n"
2393 + " d3.addEventListener('click', function () { log('d3 at click 2') })\n"
2394 + " d3.addEventListener('click', function () { log('d3 at click 2 capture') }, true)\n"
2395 + "</script>\n"
2396 + "</body></html>";
2397
2398 final WebDriver driver = loadPage2(html);
2399 driver.findElement(By.id("d3")).click();
2400
2401 final String text = driver.getTitle().trim().replaceAll(";", "\n").trim();
2402 assertEquals(String.join("\n", getExpectedAlerts()), text);
2403 }
2404
2405
2406
2407
2408
2409
2410
2411 @Test
2412 @Alerts({"window at click 1 capture",
2413 "window at click 2 capture",
2414 "begin detach click",
2415 "d2 at click 1 capture",
2416 "d2 at click 2 capture",
2417 "d3 at click 1",
2418 "d3 onclick",
2419 "d3 at click 1 capture",
2420 "d3 at click 2",
2421 "d3 at click 2 capture",
2422 "d2 at click 1",
2423 "d2 onclick",
2424 "d2 at click 2",
2425 "end detach click",
2426 "window at click 1",
2427 "window at click 2"})
2428 public void propagationNestedDetached() throws Exception {
2429 final String html = DOCTYPE_HTML
2430 + "<html><head>\n"
2431 + "<script>\n"
2432 + " function log(msg) {\n"
2433 + " window.parent.document.title += msg + ';';\n"
2434 + " }\n"
2435
2436 + " function detachAndClick() {\n"
2437 + " log('begin detach click')\n"
2438 + " var d2 = window.d2, d3 = window.d3\n"
2439 + " d2.parentNode.removeChild(d2);\n"
2440 + " d3.click();\n"
2441 + " log('end detach click')\n"
2442 + " }\n"
2443 + "</script>\n"
2444 + "</head>\n"
2445 + "<body>\n"
2446 + " <div id='d1' style='width: 150px; height: 150px; background-color: blue'>\n"
2447 + " <div id='d2' style='width: 100px; height: 100px; background-color: green'>\n"
2448 + " <div id='d3' style='width: 50px; height: 50px; background-color: red'>\n"
2449 + " </div>\n"
2450 + " </div>\n"
2451 + " </div>\n"
2452 + " <input id='detach_click' type='button' value='Detach & click' onclick='detachAndClick()'>\n"
2453
2454 + "<script>\n"
2455 + " d2 = window.d2, d3 = window.d3\n"
2456 + " window.addEventListener('click', function () { log('window at click 1') })\n"
2457 + " window.addEventListener('click', function () { log('window at click 1 capture') }, true)\n"
2458 + " window.addEventListener('click', function () { log('window at click 2') })\n"
2459 + " window.addEventListener('click', function () { log('window at click 2 capture') }, true)\n"
2460
2461 + " d1.addEventListener('click', function () { log('d1 at click 1') })\n"
2462 + " d1.onclick = function () { log('d1 onclick') }\n"
2463 + " d1.addEventListener('click', function () { log('d1 at click 1 capture') }, true)\n"
2464 + " d1.addEventListener('click', function () { log('d1 at click 2') })\n"
2465 + " d1.addEventListener('click', function () { log('d1 at click 2 capture') }, true)\n"
2466
2467 + " d2.addEventListener('click', function () { log('d2 at click 1') })\n"
2468 + " d2.onclick = function () { log('d2 onclick'); if (d2.parentNode) d2.parentNode.removeChild(d2) }\n"
2469 + " d2.addEventListener('click', function () { log('d2 at click 1 capture') }, true)\n"
2470 + " d2.addEventListener('click', function () { log('d2 at click 2') })\n"
2471 + " d2.addEventListener('click', function () { log('d2 at click 2 capture') }, true)\n"
2472
2473 + " d3.addEventListener('click', function () { log('d3 at click 1') })\n"
2474 + " d3.onclick = function () { log('d3 onclick') }\n"
2475 + " d3.addEventListener('click', function () { log('d3 at click 1 capture') }, true)\n"
2476 + " d3.addEventListener('click', function () { log('d3 at click 2') })\n"
2477 + " d3.addEventListener('click', function () { log('d3 at click 2 capture') }, true)\n"
2478 + "</script>\n"
2479 + "</body></html>";
2480
2481 final WebDriver driver = loadPage2(html);
2482 driver.findElement(By.id("detach_click")).click();
2483
2484 final String text = driver.getTitle().trim().replaceAll(";", "\n").trim();
2485 assertEquals(String.join("\n", getExpectedAlerts()), text);
2486 }
2487
2488
2489
2490
2491
2492
2493
2494 @Test
2495 @Alerts({"listener: stop propagation & return false",
2496 "FIRED a1",
2497 "listener: return true",
2498 "property: return false",
2499 "listener: return true",
2500 "listener: prevented=false returnValue: true -> false (false)",
2501 "listener: prevented=true returnValue: false -> true (false)",
2502 "listener: prevented=true returnValue: false -> preventDefault() (false)",
2503 "property: prevented=true returnValue: false -> return true",
2504 "listener: prevented=true returnValue: false -> x (false)",
2505 "listener: prevented=true returnValue: false -> null (false)"})
2506 public void stopPropagation() throws Exception {
2507 final String html = DOCTYPE_HTML
2508 + "<html><head>\n"
2509 + "<script>\n"
2510 + " function log(msg) {\n"
2511 + " window.parent.document.title += msg + ';';\n"
2512 + " }\n"
2513 + "</script>\n"
2514 + "</head>\n"
2515 + "<body>\n"
2516 + " <div><a id='a1' href='javascript:log(\"FIRED a1\")'>test: listener return false</a></div>\n"
2517 + " <div><a id='a2' href='javascript:log(\"FIRED a2\")'>test: property return false</a></div>\n"
2518 + " <div><a id='a3' href='javascript:log(\"FIRED a3\")'>test: listener returnValue = false</a></div>\n"
2519
2520 + " <textarea id='log' rows=40 cols=80></textarea>\n"
2521
2522 + "<script>\n"
2523
2524
2525 + " a1.addEventListener('click', function (event) { "
2526 + "log('listener: stop propagation & return false');"
2527 + "event.stopPropagation(); return false })\n"
2528
2529
2530
2531 + " a2.addEventListener('click',"
2532 + " function (event) { log('listener: return true'); event.stopPropagation(); return true })\n"
2533 + " a2.onclick = function () { log('property: return false'); return false }\n"
2534 + " a2.addEventListener('click', function (event) { log('listener: return true'); return true })\n"
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547 + " a3.addEventListener('click', function (event) {"
2548 + " var a = event.returnValue, p = event.defaultPrevented, b = false; event.returnValue = b;"
2549 + " log('listener: prevented=' + p + ' returnValue: ' + a "
2550 + "+ ' -> ' + b + ' (' + event.returnValue + ')') })\n"
2551
2552 + " a3.addEventListener('click', function (event) {"
2553 + " var a = event.returnValue, p = event.defaultPrevented, b = true; event.returnValue = b;"
2554 + " log('listener: prevented=' + p + ' returnValue: ' + a "
2555 + "+ ' -> ' + b + ' (' + event.returnValue + ')') })\n"
2556
2557 + " a3.addEventListener('click', function (event) {"
2558 + " var a = event.returnValue, p = event.defaultPrevented, "
2559 + "b = 'preventDefault()'; event.preventDefault();"
2560 + " log('listener: prevented=' + p + ' returnValue: ' + a "
2561 + "+ ' -> ' + b + ' (' + event.returnValue + ')') })\n"
2562
2563 + " a3.onclick = function (event) {"
2564 + " var a = event.returnValue, p = event.defaultPrevented; b = true;"
2565 + " log('property: prevented=' + p + ' returnValue: ' + a + ' -> return ' + b); return b }\n"
2566
2567
2568
2569
2570
2571
2572
2573 + " a3.addEventListener('click', function (event) {"
2574 + " var a = event.returnValue, p = event.defaultPrevented, b = 'x'; event.returnValue = b;"
2575 + " log('listener: prevented=' + p + ' returnValue: ' + a "
2576 + "+ ' -> ' + b + ' (' + event.returnValue + ')') })\n"
2577 + " a3.addEventListener('click', function (event) {"
2578 + " var a = event.returnValue, p = event.defaultPrevented, b = null; event.returnValue = b;"
2579 + " log('listener: prevented=' + p + ' returnValue: ' + a "
2580 + "+ ' -> ' + b + ' (' + event.returnValue + ')') })\n"
2581 + "</script>\n"
2582 + "</body></html>";
2583
2584 final WebDriver driver = loadPage2(html);
2585 driver.findElement(By.id("a1")).click();
2586 driver.findElement(By.id("a2")).click();
2587 driver.findElement(By.id("a3")).click();
2588
2589 final String text = driver.getTitle().trim().replaceAll(";", "\n").trim();
2590 assertEquals(String.join("\n", getExpectedAlerts()), text);
2591 }
2592 }