1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.html;
16
17 import java.io.InputStream;
18 import java.net.URL;
19 import java.util.Collections;
20
21 import org.apache.commons.io.IOUtils;
22 import org.htmlunit.WebDriverTestCase;
23 import org.htmlunit.http.HttpStatus;
24 import org.htmlunit.junit.annotation.Alerts;
25 import org.htmlunit.junit.annotation.HtmlUnitNYI;
26 import org.htmlunit.util.MimeType;
27 import org.junit.jupiter.api.Test;
28 import org.openqa.selenium.By;
29 import org.openqa.selenium.WebDriver;
30 import org.openqa.selenium.htmlunit.HtmlUnitDriver;
31 import org.openqa.selenium.interactions.Actions;
32
33
34
35
36
37
38 public class HtmlImage2Test extends WebDriverTestCase {
39
40
41
42
43 @Test
44 @Alerts("1")
45 public void loadImageWithoutSource() throws Exception {
46 loadImage("");
47 loadImageInnerHtml("");
48 loadImageImportNodeHtml("");
49 }
50
51
52
53
54 @Test
55 @Alerts("1")
56 public void loadImageEmptySource() throws Exception {
57 loadImage("src=''");
58 loadImageInnerHtml("src=''");
59 loadImageImportNodeHtml("src=''");
60 }
61
62
63
64
65 @Test
66 @Alerts(DEFAULT = "1",
67 FF = "2",
68 FF_ESR = "2")
69 public void loadImageBlankSource() throws Exception {
70 loadImage("src=' '");
71 loadImageInnerHtml("src=' '");
72 loadImageImportNodeHtml("src=' '");
73 }
74
75
76
77
78 @Test
79 @Alerts("2")
80 public void loadImage() throws Exception {
81 loadImage("src='img.jpg'");
82 loadImageInnerHtml("src='img.jpg'");
83 loadImageImportNodeHtml("src='img.jpg'");
84 }
85
86
87
88
89 @Test
90 @Alerts("2")
91 public void loadImageUnknown() throws Exception {
92 loadImage("src='unknown'");
93 loadImageInnerHtml("src='unknown'");
94 }
95
96
97
98
99 @Test
100 @Alerts(DEFAULT = "2",
101 CHROME = "1",
102 EDGE = "1")
103 @HtmlUnitNYI(CHROME = "2",
104 EDGE = "2")
105 public void loadImageUnknown2() throws Exception {
106 loadImageImportNodeHtml("src='unknown'");
107 }
108
109
110
111
112 @Test
113 @Alerts("1")
114 public void loadImageBrokenUrl() throws Exception {
115 loadImage("src='rbri://nowhere'");
116 loadImageInnerHtml("src='rbri://nowhere'");
117 loadImageImportNodeHtml("src='rbri://nowhere'");
118 }
119
120
121
122
123 @Test
124 @Alerts("1")
125 public void loadImageAboutBlank() throws Exception {
126 loadImage("src='about:blank'");
127 loadImageInnerHtml("src='about:blank'");
128 loadImageImportNodeHtml("src='about:blank'");
129 }
130
131
132
133
134 @Test
135 @Alerts("1")
136 public void loadImageAboutX() throws Exception {
137 loadImage("src='about:x'");
138 loadImageInnerHtml("src='about:x'");
139 loadImageImportNodeHtml("src='about:x'");
140 }
141
142
143
144
145 @Test
146 @Alerts("2")
147 public void loadImageWrongType() throws Exception {
148 loadImage("src='" + URL_FIRST + "'");
149 loadImageInnerHtml("src='" + URL_FIRST + "'");
150 }
151
152
153
154
155 @Test
156 @Alerts(DEFAULT = "2",
157 CHROME = "1",
158 EDGE = "1")
159 @HtmlUnitNYI(CHROME = "2",
160 EDGE = "2")
161 public void loadImageWrongType2() throws Exception {
162 loadImageImportNodeHtml("src='" + URL_FIRST + "'");
163 }
164
165 private void loadImage(final String src) throws Exception {
166 getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
167
168 try (InputStream is = getClass().getClassLoader().getResourceAsStream("testfiles/tiny-jpg.img")) {
169 final byte[] directBytes = IOUtils.toByteArray(is);
170 final URL urlImage = new URL(URL_FIRST, "img.jpg");
171 getMockWebConnection().setResponse(urlImage, directBytes, 200, "ok", "image/jpg", Collections.emptyList());
172 }
173
174 final String html = DOCTYPE_HTML
175 + "<html><head>\n"
176 + "<script>\n"
177 + " function test() {\n"
178 + " var img = document.getElementById('myImage');\n"
179 + " }\n"
180 + "</script>\n"
181 + "</head><body onload='test()'>\n"
182 + " <img id='myImage' " + src + " >\n"
183 + "</body></html>";
184
185 final int count = getMockWebConnection().getRequestCount();
186 final WebDriver driver = getWebDriver();
187 if (driver instanceof HtmlUnitDriver) {
188 ((HtmlUnitDriver) driver).setDownloadImages(true);
189 }
190 loadPage2(html);
191 assertEquals(Integer.parseInt(getExpectedAlerts()[0]), getMockWebConnection().getRequestCount() - count);
192 }
193
194 private void loadImageInnerHtml(final String src) throws Exception {
195 try (InputStream is = getClass().getClassLoader().getResourceAsStream("testfiles/tiny-jpg.img")) {
196 final byte[] directBytes = IOUtils.toByteArray(is);
197 final URL urlImage = new URL(URL_FIRST, "img.jpg");
198 getMockWebConnection().setResponse(urlImage, directBytes, 200, "ok", "image/jpg", Collections.emptyList());
199 }
200
201 final String html = DOCTYPE_HTML
202 + "<html><head>\n"
203 + "<script>\n"
204 + " function test() {\n"
205 + " var tester = document.getElementById('tester');\n"
206 + " tester.innerHTML = \"<img id='myImage' " + src + " >\";\n"
207 + " }\n"
208 + "</script>\n"
209 + "</head><body>\n"
210 + " <button id='test' onclick='test()'>Test</button>\n"
211 + " <div id='tester'></div>\n"
212 + "</body></html>";
213
214 final int count = getMockWebConnection().getRequestCount();
215 final WebDriver driver = getWebDriver();
216 if (driver instanceof HtmlUnitDriver) {
217 ((HtmlUnitDriver) driver).setDownloadImages(true);
218 }
219 loadPage2(html);
220
221 driver.findElement(By.id("test")).click();
222 assertEquals(Integer.parseInt(getExpectedAlerts()[0]), getMockWebConnection().getRequestCount() - count);
223 }
224
225 private void loadImageImportNodeHtml(final String src) throws Exception {
226 getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
227
228 try (InputStream is = getClass().getClassLoader().getResourceAsStream("testfiles/tiny-jpg.img")) {
229 final byte[] directBytes = IOUtils.toByteArray(is);
230 final URL urlImage = new URL(URL_FIRST, "img.jpg");
231 getMockWebConnection().setResponse(urlImage, directBytes, 200, "ok", "image/jpg", Collections.emptyList());
232 }
233
234 final String html = DOCTYPE_HTML
235 + "<html><head>\n"
236 + "<script>\n"
237 + " function test() {\n"
238 + " var tester = document.getElementById('tester');\n"
239
240 + " var doc = document.implementation.createHTMLDocument('test');\n"
241 + " doc.body.innerHTML = \"<img id='myImage' " + src + " >\";\n"
242
243 + " var srcNode = doc.getElementById('myImage');\n"
244 + " var newNode = document.importNode(srcNode, true);\n"
245 + " document.body.replaceChild(newNode, tester);\n"
246 + " alert('before');\n"
247 + " }\n"
248 + "</script>\n"
249 + "</head><body>\n"
250 + " <button id='test' onclick='test()'>Test</button>\n"
251 + " <div id='tester'></div>\n"
252 + "</body></html>";
253
254 final int count = getMockWebConnection().getRequestCount();
255 final WebDriver driver = getWebDriver();
256 if (driver instanceof HtmlUnitDriver) {
257 ((HtmlUnitDriver) driver).setDownloadImages(true);
258 }
259 loadPage2(html);
260
261 driver.findElement(By.id("test")).click();
262 verifyAlerts(driver, "before");
263
264 assertEquals(Integer.parseInt(getExpectedAlerts()[0]), getMockWebConnection().getRequestCount() - count);
265 }
266
267
268
269
270 @Test
271 @Alerts("true")
272 public void isDisplayed() throws Exception {
273 isDisplayed("src='img.jpg'");
274 }
275
276
277
278
279 @Test
280 @Alerts("false")
281 public void isDisplayedNoSource() throws Exception {
282 isDisplayed("");
283 }
284
285
286
287
288 @Test
289 @Alerts("false")
290 public void isDisplayedEmptySource() throws Exception {
291 isDisplayed("src=''");
292 }
293
294
295
296
297 @Test
298 @Alerts(DEFAULT = "true",
299 CHROME = "false",
300 EDGE = "false")
301 public void isDisplayedBlankSource() throws Exception {
302 isDisplayed("src=' '");
303 }
304
305
306
307
308 @Test
309 @Alerts("true")
310 public void isDisplayedInvalidSource() throws Exception {
311 isDisplayed("src='unknown.gif'");
312 }
313
314
315
316
317 @Test
318 @Alerts("true")
319 public void isDisplayedWrongType() throws Exception {
320 isDisplayed("src='" + URL_FIRST + "'");
321 }
322
323
324
325
326 @Test
327 @Alerts("false")
328 public void isDisplayedDisplayNone() throws Exception {
329 isDisplayed("src='img.jpg' style='display: none'");
330 }
331
332 private void isDisplayed(final String src) throws Exception {
333 try (InputStream is = getClass().getClassLoader().getResourceAsStream("testfiles/tiny-jpg.img")) {
334 final byte[] directBytes = IOUtils.toByteArray(is);
335 final URL urlImage = new URL(URL_FIRST, "img.jpg");
336 getMockWebConnection().setResponse(urlImage, directBytes, 200, "ok", "image/jpg", Collections.emptyList());
337
338 getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
339 }
340
341 final String html = DOCTYPE_HTML
342 + "<html><head><title>Page A</title></head>\n"
343 + "<body>\n"
344 + " <img id='myImg' " + src + " >\n"
345 + "</body></html>";
346
347 final WebDriver driver = loadPage2(html);
348
349 final boolean displayed = driver.findElement(By.id("myImg")).isDisplayed();
350 assertEquals(Boolean.parseBoolean(getExpectedAlerts()[0]), displayed);
351 }
352
353
354
355
356 @Test
357 @Alerts("§§URL§§img.gif")
358 public void src() throws Exception {
359 final String html = DOCTYPE_HTML
360 + "<html><head>\n"
361 + "<script>\n"
362 + LOG_TITLE_FUNCTION
363 + " function test() {\n"
364 + " var img = document.getElementById('myImg');\n"
365 + " log(img.src);\n"
366 + " }\n"
367 + "</script>\n"
368 + "</head>\n"
369 + "<body onload='test()'>\n"
370 + " <img id='myImg' src='img.gif'>\n"
371 + "</body>\n"
372 + "</html>";
373
374 expandExpectedAlertsVariables(URL_FIRST);
375 loadPageVerifyTitle2(html);
376 }
377
378
379
380
381 @Test
382 @Alerts({"1", "§§URL§§abcd/img.gif"})
383 public void lineBreaksInUrl() throws Exception {
384 try (InputStream is = getClass().getClassLoader().getResourceAsStream("testfiles/tiny-gif.img")) {
385 final byte[] directBytes = IOUtils.toByteArray(is);
386 final URL urlImage = new URL(URL_SECOND, "abcd/img.gif");
387 getMockWebConnection().setResponse(urlImage, directBytes, 200, "ok",
388 MimeType.IMAGE_GIF, Collections.emptyList());
389 }
390
391 final String html = DOCTYPE_HTML
392 + "<html><head>\n"
393 + "<script>\n"
394 + LOG_TITLE_FUNCTION
395 + " function test() {\n"
396 + " var img = document.getElementById('myImg');\n"
397 + " img.width;\n"
398 + " log(img.width);\n"
399 + " log(img.src);\n"
400 + " }\n"
401 + "</script>\n"
402 + "</head>\n"
403 + "<body onload='test()'>\n"
404 + " <img id='myImg' src='" + URL_SECOND + "a\rb\nc\r\nd/img.gif' onError='log(\"broken\");'>\n"
405 + "</body>\n"
406 + "</html>";
407
408 expandExpectedAlertsVariables(URL_SECOND);
409 loadPageVerifyTitle2(html);
410 }
411
412
413
414
415 @Test
416 @Alerts(DEFAULT = {"58", "29", "58", "29"},
417 FF = {"58", "29", "70", "118"},
418 FF_ESR = {"58", "29", "68", "118"})
419 @HtmlUnitNYI(CHROME = {"18", "18", "18", "18"},
420 EDGE = {"18", "18", "18", "18"},
421 FF = {"18", "18", "18", "18"},
422 FF_ESR = {"18", "18", "18", "18"})
423 public void clickWithCoordinates() throws Exception {
424 try (InputStream is = getClass().getClassLoader().getResourceAsStream("testfiles/tiny-gif.img")) {
425 final byte[] directBytes = IOUtils.toByteArray(is);
426 final URL urlImage = new URL(URL_SECOND, "img.gif");
427 getMockWebConnection().setResponse(urlImage, directBytes, 200, "ok",
428 MimeType.IMAGE_GIF, Collections.emptyList());
429 }
430
431 final String html = DOCTYPE_HTML
432 + "<html><head>\n"
433 + "<script>\n"
434 + LOG_TITLE_FUNCTION
435 + " function clickImage(event) {\n"
436 + " log(event.clientX);\n"
437 + " log(event.clientY);\n"
438 + " log(event.screenX);\n"
439 + " log(event.screenY);\n"
440 + " }\n"
441 + "</script>\n"
442 + "</head>\n"
443 + "<body>\n"
444 + " <img id='myImg' src='" + URL_SECOND + "img.gif' "
445 + "width='100px' height='42px' onclick='clickImage(event)'>\n"
446 + "</body>\n"
447 + "</html>";
448
449 final WebDriver driver = loadPage2(html);
450
451 final Actions actions = new Actions(driver);
452
453 actions.moveToElement(driver.findElement(By.id("myImg")), 0, 0).click().build().perform();
454
455 verifyTitle2(driver, getExpectedAlerts());
456 }
457
458
459
460
461 @Test
462 @Alerts("error [object HTMLImageElement]")
463 public void addEventListener_NoContent() throws Exception {
464 addEventListener(HttpStatus.NO_CONTENT_204);
465 }
466
467
468
469
470 @Test
471 @Alerts("error [object HTMLImageElement]")
472 public void addEventListener_BadRequest() throws Exception {
473 addEventListener(HttpStatus.BAD_REQUEST_400);
474 }
475
476
477
478
479 @Test
480 @Alerts("error [object HTMLImageElement]")
481 public void addEventListener_Forbidden() throws Exception {
482 addEventListener(HttpStatus.FORBIDDEN_403);
483 }
484
485
486
487
488 @Test
489 @Alerts("error [object HTMLImageElement]")
490 public void addEventListener_NotFound() throws Exception {
491 addEventListener(HttpStatus.NOT_FOUND_404);
492 }
493
494
495
496
497 @Test
498 @Alerts("error [object HTMLImageElement]")
499 public void addEventListener_MethodNotAllowed() throws Exception {
500 addEventListener(HttpStatus.METHOD_NOT_ALLOWED_405);
501 }
502
503
504
505
506 @Test
507 @Alerts("error [object HTMLImageElement]")
508 public void addEventListener_NotAcceptable() throws Exception {
509 addEventListener(HttpStatus.NOT_ACCEPTABLE_406);
510 }
511
512
513
514
515 @Test
516 @Alerts("error [object HTMLImageElement]")
517 public void addEventListener_ProxyAuthRequired() throws Exception {
518 addEventListener(HttpStatus.PROXY_AUTHENTICATION_REQUIRED_407);
519 }
520
521
522
523
524 @Test
525 @Alerts("error [object HTMLImageElement]")
526 public void addEventListener_RequestTimeout() throws Exception {
527 addEventListener(HttpStatus.REQUEST_TIMEOUT_408);
528 }
529
530
531
532
533 @Test
534 @Alerts("error [object HTMLImageElement]")
535 public void addEventListener_Conflict() throws Exception {
536 addEventListener(HttpStatus.CONFLICT_409);
537 }
538
539
540
541
542 @Test
543 @Alerts("error [object HTMLImageElement]")
544 public void addEventListener_Gone() throws Exception {
545 addEventListener(HttpStatus.GONE_410);
546 }
547
548
549
550
551 @Test
552 @Alerts("error [object HTMLImageElement]")
553 public void addEventListener_LengthRequired() throws Exception {
554 addEventListener(HttpStatus.LENGTH_REQUIRED_411);
555 }
556
557
558
559
560 @Test
561 @Alerts("error [object HTMLImageElement]")
562 public void addEventListener_PreconditionFailed() throws Exception {
563 addEventListener(HttpStatus.PRECONDITION_FAILED_412);
564 }
565
566
567
568
569 @Test
570 @Alerts("error [object HTMLImageElement]")
571 public void addEventListener_PayloadTooLarge() throws Exception {
572 addEventListener(HttpStatus.PAYLOAD_TOO_LARGE_413);
573 }
574
575
576
577
578 @Test
579 @Alerts("error [object HTMLImageElement]")
580 public void addEventListener_UriTooLong() throws Exception {
581 addEventListener(HttpStatus.URI_TOO_LONG_414);
582 }
583
584
585
586
587 @Test
588 @Alerts("error [object HTMLImageElement]")
589 public void addEventListener_UnsupportedMediaType() throws Exception {
590 addEventListener(HttpStatus.UNSUPPORTED_MEDIA_TYPE_415);
591 }
592
593
594
595
596 @Test
597 @Alerts("error [object HTMLImageElement]")
598 public void addEventListener_RangeNotSatisfiable() throws Exception {
599 addEventListener(HttpStatus.RANGE_NOT_SATISFIABLE_416);
600 }
601
602
603
604
605 @Test
606 @Alerts("error [object HTMLImageElement]")
607 public void addEventListener_ExpectationFailed() throws Exception {
608 addEventListener(HttpStatus.EXPECTATION_FAILED_417);
609 }
610
611
612
613
614 @Test
615 @Alerts("error [object HTMLImageElement]")
616 public void addEventListener_ImaTeapot() throws Exception {
617 addEventListener(HttpStatus.IM_A_TEAPOT_418);
618 }
619
620
621
622
623 @Test
624 @Alerts("error [object HTMLImageElement]")
625 public void addEventListener_EnhanceYourCalm() throws Exception {
626 addEventListener(HttpStatus.ENHANCE_YOUR_CALM_420);
627 }
628
629
630
631
632 @Test
633 @Alerts("error [object HTMLImageElement]")
634 public void addEventListener_MisdirectedRequest() throws Exception {
635 addEventListener(HttpStatus.MISDIRECTED_REQUEST_421);
636 }
637
638
639
640
641 @Test
642 @Alerts("error [object HTMLImageElement]")
643 public void addEventListener_UnprocessableEntity() throws Exception {
644 addEventListener(HttpStatus.UNPROCESSABLE_ENTITY_422);
645 }
646
647
648
649
650 @Test
651 @Alerts("error [object HTMLImageElement]")
652 public void addEventListener_Locked() throws Exception {
653 addEventListener(HttpStatus.LOCKED_423);
654 }
655
656
657
658
659 @Test
660 @Alerts("error [object HTMLImageElement]")
661 public void addEventListener_FailedDependency() throws Exception {
662 addEventListener(HttpStatus.FAILED_DEPENDENCY_424);
663 }
664
665
666
667
668 @Test
669 @Alerts("error [object HTMLImageElement]")
670 public void addEventListener_UpgradeRequired() throws Exception {
671 addEventListener(HttpStatus.UPGRADE_REQUIRED_426);
672 }
673
674
675
676
677 @Test
678 @Alerts("error [object HTMLImageElement]")
679 public void addEventListener_PreconditionRequired() throws Exception {
680 addEventListener(HttpStatus.PRECONDITION_REQUIRED_428);
681 }
682
683
684
685
686 @Test
687 @Alerts("error [object HTMLImageElement]")
688 public void addEventListener_TooManyRedirects() throws Exception {
689 addEventListener(HttpStatus.TOO_MANY_REQUESTS_429);
690 }
691
692
693
694
695 @Test
696 @Alerts("error [object HTMLImageElement]")
697 public void addEventListener_RequestHeaderFieldsTooLarge() throws Exception {
698 addEventListener(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE_431);
699 }
700
701
702
703
704 @Test
705 @Alerts("error [object HTMLImageElement]")
706 public void addEventListener_UnavailableForLegalReasons() throws Exception {
707 addEventListener(HttpStatus.UNAVAILABLE_FOR_LEGAL_REASONS_451);
708 }
709
710
711
712
713 @Test
714 @Alerts("error [object HTMLImageElement]")
715 public void addEventListener_InternalServerError() throws Exception {
716 addEventListener(HttpStatus.INTERNAL_SERVER_ERROR_500);
717 }
718
719
720
721
722 @Test
723 @Alerts("error [object HTMLImageElement]")
724 public void addEventListener_NotImplemented() throws Exception {
725 addEventListener(HttpStatus.NOT_IMPLEMENTED_501);
726 }
727
728
729
730
731 @Test
732 @Alerts("error [object HTMLImageElement]")
733 public void addEventListener_BadGateway() throws Exception {
734 addEventListener(HttpStatus.BAD_GATEWAY_502);
735 }
736
737
738
739
740 @Test
741 @Alerts("error [object HTMLImageElement]")
742 public void addEventListener_ServiceUnavailable() throws Exception {
743 addEventListener(HttpStatus.SERVICE_UNAVAILABLE_503);
744 }
745
746
747
748
749 @Test
750 @Alerts("error [object HTMLImageElement]")
751 public void addEventListener_GatewayTimeout() throws Exception {
752 addEventListener(HttpStatus.GATEWAY_TIMEOUT_504);
753 }
754
755
756
757
758 @Test
759 @Alerts("error [object HTMLImageElement]")
760 public void addEventListener_HttpVersionNotSupported() throws Exception {
761 addEventListener(HttpStatus.HTTP_VERSION_NOT_SUPPORTED_505);
762 }
763
764
765
766
767 @Test
768 @Alerts("error [object HTMLImageElement]")
769 public void addEventListener_InsufficientStrorage() throws Exception {
770 addEventListener(HttpStatus.INSUFFICIENT_STORAGE_507);
771 }
772
773
774
775
776 @Test
777 @Alerts("error [object HTMLImageElement]")
778 public void addEventListener_LoopDetected() throws Exception {
779 addEventListener(HttpStatus.LOOP_DETECTED_508);
780 }
781
782
783
784
785 @Test
786 @Alerts("error [object HTMLImageElement]")
787 public void addEventListener_NotExtended() throws Exception {
788 addEventListener(HttpStatus.NOT_EXTENDED_510);
789 }
790
791
792
793
794 @Test
795 @Alerts("error [object HTMLImageElement]")
796 public void addEventListener_NetworkAuthenticationRequired() throws Exception {
797 addEventListener(HttpStatus.NETWORK_AUTHENTICATION_REQUIRED_511);
798 }
799
800 private void addEventListener(final int statusCode) throws Exception {
801
802 final URL scriptUrl = new URL(URL_SECOND, "" + System.currentTimeMillis() + ".png");
803
804 final String html = DOCTYPE_HTML
805 + "<html><head>\n"
806 + "<script>\n"
807 + LOG_TITLE_FUNCTION
808 + " function test() {\n"
809 + " var s1 = document.createElement('img');\n"
810 + " s1.src = '" + scriptUrl + "';\n"
811 + " s1.addEventListener('load', function() { log('load'); }, false);\n"
812 + " s1.addEventListener('error', function(event) { log(event.type + ' ' + event.target); }, false);\n"
813 + " document.body.insertBefore(s1, document.body.firstChild);\n"
814 + " }\n"
815 + "</script>\n"
816 + "</head>\n"
817 + "<body onload='test()'></body>\n"
818 + "</html>";
819
820 getMockWebConnection().setResponse(scriptUrl, (String) null,
821 statusCode, "test", MimeType.TEXT_JAVASCRIPT, null);
822 loadPageVerifyTitle2(html);
823 }
824 }