1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.html;
16
17 import static java.nio.charset.StandardCharsets.ISO_8859_1;
18 import static java.nio.charset.StandardCharsets.UTF_8;
19
20 import java.io.IOException;
21 import java.net.MalformedURLException;
22 import java.net.URL;
23 import java.nio.charset.StandardCharsets;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.Iterator;
28 import java.util.LinkedList;
29 import java.util.List;
30 import java.util.Set;
31
32 import javax.xml.parsers.DocumentBuilder;
33 import javax.xml.parsers.DocumentBuilderFactory;
34
35 import org.apache.commons.io.IOUtils;
36 import org.apache.commons.lang3.SerializationUtils;
37 import org.htmlunit.CollectingAlertHandler;
38 import org.htmlunit.ElementNotFoundException;
39 import org.htmlunit.HttpMethod;
40 import org.htmlunit.ImmediateRefreshHandler;
41 import org.htmlunit.IncorrectnessListener;
42 import org.htmlunit.MockWebConnection;
43 import org.htmlunit.OnbeforeunloadHandler;
44 import org.htmlunit.Page;
45 import org.htmlunit.SimpleWebTestCase;
46 import org.htmlunit.StringWebResponse;
47 import org.htmlunit.WebClient;
48 import org.htmlunit.WebRequest;
49 import org.htmlunit.WebResponse;
50 import org.htmlunit.html.HtmlElementTest.HtmlAttributeChangeListenerTestImpl;
51 import org.htmlunit.junit.annotation.Alerts;
52 import org.htmlunit.util.Cookie;
53 import org.htmlunit.util.MimeType;
54 import org.htmlunit.util.NameValuePair;
55 import org.htmlunit.util.StringUtils;
56 import org.junit.jupiter.api.Assertions;
57 import org.junit.jupiter.api.Test;
58 import org.w3c.dom.NodeList;
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public class HtmlPageTest extends SimpleWebTestCase {
74
75
76 public static final String STANDARDS_MODE_PREFIX_
77 = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n";
78
79
80
81
82 @Test
83 public void formSubmit() throws Exception {
84 final String htmlContent = DOCTYPE_HTML
85 + "<html>\n"
86 + "<head><title>foo</title></head>\n"
87 + "<body>\n"
88 + "<p>hello world</p>\n"
89 + "<form id='form1' action='/formSubmit' method='PoSt'>\n"
90 + "<input type='text' NAME='textInput1' value='textInput1'/>\n"
91 + "<input type='text' name='textInput2' value='textInput2'/>\n"
92 + "<input type='hidden' name='hidden1' value='hidden1'/>\n"
93 + "<input type='submit' name='submitInput1' value='push me'/>\n"
94 + "</form>\n"
95 + "</body></html>";
96 final HtmlPage page = loadPage(htmlContent);
97 final MockWebConnection webConnection = getMockConnection(page);
98
99 final HtmlForm form = page.getHtmlElementById("form1");
100 final HtmlInput textInput = form.getInputByName("textInput1");
101 textInput.setValue("foo");
102
103 final HtmlSubmitInput button = form.getInputByName("submitInput1");
104 final HtmlPage secondPage = button.click();
105
106 final List<NameValuePair> expectedParameters = new ArrayList<>();
107 expectedParameters.add(new NameValuePair("textInput1", "foo"));
108 expectedParameters.add(new NameValuePair("textInput2", "textInput2"));
109 expectedParameters.add(new NameValuePair("hidden1", "hidden1"));
110 expectedParameters.add(new NameValuePair("submitInput1", "push me"));
111
112 final URL expectedUrl = new URL(URL_FIRST, "formSubmit");
113 final URL actualUrl = secondPage.getUrl();
114 assertEquals("url", expectedUrl, actualUrl);
115 assertSame("method", HttpMethod.POST, webConnection.getLastMethod());
116 assertEquals("parameters", expectedParameters, webConnection.getLastParameters());
117 assertNotNull(secondPage);
118 }
119
120
121
122
123 @Test
124 public void getElementByIdNull() throws Exception {
125 final String htmlContent = DOCTYPE_HTML
126 + "<html>\n"
127 + "<head><title>foo</title></head>\n"
128 + "<body>\n"
129 + "<p>hello world</p>\n"
130 + "</body></html>";
131
132 final HtmlPage page = loadPage(htmlContent);
133
134 assertNull(page.getElementById(null));
135 }
136
137
138
139
140 @Test
141 public void getElementsByIdNull() throws Exception {
142 final String htmlContent = DOCTYPE_HTML
143 + "<html>\n"
144 + "<head><title>foo</title></head>\n"
145 + "<body>\n"
146 + "<p>hello world</p>\n"
147 + "</body></html>";
148
149 final HtmlPage page = loadPage(htmlContent);
150
151 final List<DomElement> elements = page.getElementsById(null);
152 assertNotNull(elements);
153 assertEquals(0, elements.size());
154 }
155
156
157
158
159 @Test
160 public void getElementsByIdOrNameNull() throws Exception {
161 final String htmlContent = DOCTYPE_HTML
162 + "<html>\n"
163 + "<head><title>foo</title></head>\n"
164 + "<body>\n"
165 + "<p>hello world</p>\n"
166 + "</body></html>";
167
168 final HtmlPage page = loadPage(htmlContent);
169
170 final List<DomElement> elements = page.getElementsByIdAndOrName(null);
171 assertNotNull(elements);
172 assertEquals(0, elements.size());
173 }
174
175
176
177
178 @Test
179 public void getElementByNameNull() throws Exception {
180 final String htmlContent = DOCTYPE_HTML
181 + "<html>\n"
182 + "<head><title>foo</title></head>\n"
183 + "<body>\n"
184 + "<p>hello world</p>\n"
185 + "</body></html>";
186
187 final HtmlPage page = loadPage(htmlContent);
188
189 Assertions.assertThrows(ElementNotFoundException.class, () -> page.getElementByName(null));
190 }
191
192
193
194
195 @Test
196 public void getElementsByNameNull() throws Exception {
197 final String htmlContent = DOCTYPE_HTML
198 + "<html>\n"
199 + "<head><title>foo</title></head>\n"
200 + "<body>\n"
201 + "<p>hello world</p>\n"
202 + "</body></html>";
203
204 final HtmlPage page = loadPage(htmlContent);
205
206 final List<DomElement> elements = page.getElementsByName(null);
207 assertNotNull(elements);
208 assertEquals(0, elements.size());
209 }
210
211
212
213
214
215 @Test
216 public void getHtmlElement() throws Exception {
217 final String htmlContent = DOCTYPE_HTML
218 + "<html>\n"
219 + "<head><title>foo</title></head>\n"
220 + "<body>\n"
221 + " <p>hello world</p>\n"
222 + " <form id='form1' id='form1' action='/formSubmit' method='post'>\n"
223 + " <input type='text' NAME='textInput1' value='textInput1'/>\n"
224 + " <button type='submit' name='button1'>foobar</button>\n"
225 + " <select name='select1'>\n"
226 + " <option value='option1'>Option1</option>\n"
227 + " </select>\n"
228 + " <textarea name='textArea1'>foobar</textarea>\n"
229 + " </form>\n"
230 + " <a href='http://www.foo.com' name='anchor1'>foo.com</a>\n"
231 + " <table id='table1'>\n"
232 + " <tr>\n"
233 + " <th id='header1'>Header</th>\n"
234 + " <td id='data1'>Data</td>\n"
235 + " </tr>\n"
236 + " </table>\n"
237 + "</body></html>";
238 final HtmlPage page = loadPage(htmlContent);
239
240 final HtmlForm form = page.getHtmlElementById("form1");
241 assertSame("form1", form, page.getHtmlElementById("form1"));
242
243 final HtmlInput input = form.getInputByName("textInput1");
244 assertSame("input1", input, form.getInputByName("textInput1"));
245
246 final HtmlButton button = form.getButtonByName("button1");
247 assertSame("button1", button, form.getButtonByName("button1"));
248
249 final HtmlSelect select = form.getSelectsByName("select1").get(0);
250 assertSame("select1", select, form.getSelectsByName("select1").get(0));
251
252 final HtmlOption option = select.getOptionByValue("option1");
253 assertSame("option1", option, select.getOptionByValue("option1"));
254
255 final HtmlTable table = page.getHtmlElementById("table1");
256 assertSame("table1", table, page.getHtmlElementById("table1"));
257
258 final HtmlAnchor anchor = page.getAnchorByName("anchor1");
259 assertSame("anchor1", anchor, page.getAnchorByName("anchor1"));
260 assertSame("anchor3", anchor, page.getAnchorByHref("http://www.foo.com"));
261 assertSame("anchor4", anchor, page.getAnchorByText("foo.com"));
262
263 final HtmlTableRow tableRow = table.getRow(0);
264 assertSame("tableRow1", tableRow, table.getRow(0));
265
266 final HtmlTableHeaderCell tableHeaderCell = (HtmlTableHeaderCell) tableRow.getCell(0);
267 assertSame("tableHeaderCell1", tableHeaderCell, tableRow.getCell(0));
268 assertSame("tableHeaderCell2", tableHeaderCell, page.getHtmlElementById("header1"));
269
270 final HtmlTableDataCell tableDataCell = (HtmlTableDataCell) tableRow.getCell(1);
271 assertSame("tableDataCell1", tableDataCell, tableRow.getCell(1));
272 assertSame("tableDataCell2", tableDataCell, page.getHtmlElementById("data1"));
273
274 final HtmlTextArea textArea = form.getTextAreaByName("textArea1");
275 assertSame("textArea1", textArea, form.getTextAreaByName("textArea1"));
276 }
277
278
279
280
281
282 @Test
283 public void getAnchorByText() throws Exception {
284 final String htmlContent = DOCTYPE_HTML
285 + "<html>\n"
286 + "<head></head>\n"
287 + "<body>\n"
288 + " <a href='http://www.foo.com' id='anchor1'>anchor text</a>\n"
289 + " <a href='http://www.foo.com' id='anchor2'><span>anchor text inside span</span></a>\n"
290 + " <a href='http://www.foo.com' id='anchor3'>"
291 + "<svg><rect x='1' y='11' width='8' height='8'/></svg>"
292 + "<span>complex</span>"
293 + "</a>\n"
294 + "</body></html>";
295 final HtmlPage page = loadPage(htmlContent);
296
297 assertSame("anchor1", page.getElementById("anchor1"), page.getAnchorByText("anchor text"));
298 assertSame("anchor2", page.getElementById("anchor2"), page.getAnchorByText("anchor text inside span"));
299 assertSame("anchor3", page.getElementById("anchor3"), page.getAnchorByText("complex"));
300 }
301
302
303
304
305 @Test
306 public void getTabbableElements_None() throws Exception {
307 final String htmlContent = DOCTYPE_HTML
308 + "<html>\n"
309 + "<head><title>foo</title></head>\n"
310 + "<body>\n"
311 + "<p>hello world</p>\n"
312 + "<table><tr><td>foo</td></tr></table>\n"
313 + "</body></html>";
314
315 final HtmlPage page = loadPage(htmlContent);
316
317 assertEquals(Collections.EMPTY_LIST, page.getTabbableElements());
318 }
319
320
321
322
323 @Test
324 public void getTabbableElements_OneEnabled_OneDisabled() throws Exception {
325 final String htmlContent = DOCTYPE_HTML
326 + "<html>\n"
327 + "<head><title>foo</title></head>\n"
328 + "<body>\n"
329 + "<form><p>hello world</p>\n"
330 + "<input name='foo' type='submit' disabled='disabled' id='foo'/>\n"
331 + "<input name='bar' type='submit' id='bar'/>\n"
332 + "</form></body></html>";
333 final HtmlPage page = loadPage(htmlContent);
334
335 final List<HtmlElement> expectedElements = new ArrayList<>();
336 expectedElements.add(page.getHtmlElementById("bar"));
337
338 assertEquals(expectedElements, page.getTabbableElements());
339 }
340
341
342
343
344 @Test
345 public void getTabbableElements() throws Exception {
346 final String htmlContent = DOCTYPE_HTML
347 + "<html>\n"
348 + "<head><title>foo</title></head>\n"
349 + "<body>\n"
350 + "<a id='a' tabindex='1'>foo</a>\n"
351 + "<a id='b'>foo</a>\n"
352 + "<form>\n"
353 + "<a id='c' tabindex='3'>foo</a>\n"
354 + "<a id='d' tabindex='2'>foo</a>\n"
355 + "<a id='e' tabindex='0'>foo</a>\n"
356 + "</form>\n"
357 + "<a id='f' tabindex='3'>foo</a>\n"
358 + "<a id='g' tabindex='1'>foo</a>\n"
359 + "<a id='q' tabindex='-1'>foo</a>\n"
360 + "<form><p>hello world</p>\n"
361 + "<input name='foo' type='submit' disabled='disabled' id='foo'/>\n"
362 + "<input name='bar' type='submit' id='bar'/>\n"
363 + "</form></body></html>";
364 final HtmlPage page = loadPage(htmlContent);
365
366 final List<HtmlElement> expectedElements = Arrays.asList(new HtmlElement[] {page.getHtmlElementById("a"),
367 page.getHtmlElementById("g"), page.getHtmlElementById("d"),
368 page.getHtmlElementById("c"), page.getHtmlElementById("f"),
369 page.getHtmlElementById("e"), page.getHtmlElementById("b"),
370 page.getHtmlElementById("bar")});
371
372 assertEquals(expectedElements, page.getTabbableElements());
373
374 final String[] expectedIds = {"a", "g", "d", "c", "f", "e", "b", "bar"};
375 assertEquals(expectedIds, page.getTabbableElementIds());
376 }
377
378
379
380
381 @Test
382 public void getHtmlElementByAccessKey() throws Exception {
383 final String htmlContent = DOCTYPE_HTML
384 + "<html>\n"
385 + "<head><title>foo</title></head>\n"
386 + "<body>\n"
387 + "<a id='a' accesskey='a'>foo</a>\n"
388 + "<a id='b'>foo</a>\n"
389 + "<form>\n"
390 + "<a id='c' accesskey='c'>foo</a>\n"
391 + "</form>\n"
392 + "<form><p>hello world</p>\n"
393 + "<input name='foo' type='submit' disabled='disabled' id='foo' accesskey='f'/>\n"
394 + "<input name='bar' type='submit' id='bar'/>\n"
395 + "</form></body></html>";
396 final HtmlPage page = loadPage(htmlContent);
397
398 assertEquals(page.getHtmlElementById("a"), page.getHtmlElementByAccessKey('A'));
399 assertEquals(page.getHtmlElementById("c"), page.getHtmlElementByAccessKey('c'));
400 assertNull(page.getHtmlElementByAccessKey('z'));
401 }
402
403
404
405
406 @Test
407 public void getHtmlElementsByAccessKey() throws Exception {
408 final String htmlContent = DOCTYPE_HTML
409 + "<html>\n"
410 + "<head><title>foo</title></head><body>\n"
411 + "<a id='a' accesskey='a'>foo</a>\n"
412 + "<a id='b' accesskey='a'>foo</a>\n"
413 + "<form>\n"
414 + "<a id='c' accesskey='c'>foo</a>\n"
415 + "</form></body></html>";
416 final HtmlPage page = loadPage(htmlContent);
417
418 final List<HtmlElement> expectedElements = Arrays.asList(new HtmlElement[] {page.getHtmlElementById("a"),
419 page.getHtmlElementById("b")});
420 final List<HtmlElement> collectedElements = page.getHtmlElementsByAccessKey('a');
421 assertEquals(expectedElements, collectedElements);
422 }
423
424
425
426
427 @Test
428 public void getFullQualifiedUrl_NoBaseSpecified() throws Exception {
429 final String htmlContent = DOCTYPE_HTML
430 + "<html><head><title>foo</title></head><body>\n"
431 + "<form id='form1'>\n"
432 + "<table><tr><td><input type='text' id='foo'/></td></tr></table>\n"
433 + "</form></body></html>";
434 final WebClient client = getWebClient();
435
436 final MockWebConnection webConnection = new MockWebConnection();
437 webConnection.setDefaultResponse(htmlContent);
438 client.setWebConnection(webConnection);
439
440 final String urlString = URL_FIRST.toExternalForm();
441 final HtmlPage page = client.getPage(URL_FIRST);
442
443 assertEquals(urlString, page.getFullyQualifiedUrl(""));
444 assertEquals(urlString + "foo", page.getFullyQualifiedUrl("foo"));
445 assertEquals("http://foo.com/bar", page.getFullyQualifiedUrl("http://foo.com/bar"));
446 assertEquals("mailto:me@foo.com", page.getFullyQualifiedUrl("mailto:me@foo.com"));
447
448 assertEquals(urlString + "foo", page.getFullyQualifiedUrl("foo"));
449 assertEquals(urlString + "bbb", page.getFullyQualifiedUrl("aaa/../bbb"));
450 assertEquals(urlString + "c/d", page.getFullyQualifiedUrl("c/./d"));
451
452 final HtmlPage secondPage = client.getPage(urlString + "foo/bar?a=b&c=d");
453 assertEquals(urlString + "foo/bar?a=b&c=d", secondPage.getFullyQualifiedUrl(""));
454 assertEquals(urlString + "foo/one", secondPage.getFullyQualifiedUrl("one"));
455 assertEquals(urlString + "two", secondPage.getFullyQualifiedUrl("/two"));
456 assertEquals(urlString + "foo/two?a=b", secondPage.getFullyQualifiedUrl("two?a=b"));
457
458 final HtmlPage thirdPage = client.getPage("http://foo.com/dog/cat/one.html");
459 assertEquals("http://foo.com/dog/cat/one.html", thirdPage.getFullyQualifiedUrl(""));
460 assertEquals("http://foo.com/dog/cat/two.html", thirdPage.getFullyQualifiedUrl("two.html"));
461 }
462
463
464
465
466 @Test
467 public void getFullQualifiedUrl_WithBase() throws Exception {
468 testGetFullQualifiedUrl_WithBase("http", "");
469 testGetFullQualifiedUrl_WithBase("http", ":8080");
470 testGetFullQualifiedUrl_WithBase("https", "");
471 testGetFullQualifiedUrl_WithBase("https", ":2005");
472 }
473
474
475
476
477 private void testGetFullQualifiedUrl_WithBase(final String baseProtocol, final String basePortPart)
478 throws Exception {
479
480 final String baseUrl = baseProtocol + "://second" + basePortPart;
481 final String htmlContent = DOCTYPE_HTML
482 + "<html><head><title>foo</title>\n"
483 + "<base href='" + baseUrl + "'>\n"
484 + "</head><body>\n"
485 + "<form id='form1'>\n"
486 + "<table><tr><td><input type='text' id='foo'/></td></tr></table>\n"
487 + "</form></body></html>";
488 final HtmlPage page = loadPage(htmlContent);
489
490 assertEquals(baseUrl, page.getFullyQualifiedUrl(""));
491 assertEquals(baseUrl + "/foo", page.getFullyQualifiedUrl("foo"));
492 assertEquals(baseUrl + "/foo.js", page.getFullyQualifiedUrl("/foo.js"));
493 assertEquals("http://foo.com/bar", page.getFullyQualifiedUrl("http://foo.com/bar"));
494 assertEquals("mailto:me@foo.com", page.getFullyQualifiedUrl("mailto:me@foo.com"));
495
496 assertEquals(baseUrl + "/bbb", page.getFullyQualifiedUrl("aaa/../bbb"));
497 assertEquals(baseUrl + "/c/d", page.getFullyQualifiedUrl("c/./d"));
498 }
499
500
501
502
503 @Test
504 public void getFullQualifiedUrl_invalid() throws Exception {
505 final String htmlContent = DOCTYPE_HTML + "<html><body></body></html>";
506 final HtmlPage page = loadPage(htmlContent);
507
508 Assertions.assertThrows(MalformedURLException.class, () -> page.getFullyQualifiedUrl("http://"));
509 }
510
511
512
513
514 @Test
515 public void testBase_Multiple() throws Exception {
516 final String html = DOCTYPE_HTML
517 + "<html>\n"
518 + "<head>\n"
519 + "<base href='" + URL_SECOND + "'>\n"
520 + "<base href='" + URL_THIRD + "'>\n"
521 + "</head>\n"
522 + "<body>\n"
523 + " <a href='somepage.html'>\n"
524 + "</body></html>";
525
526 final WebClient webClient = getWebClient();
527 final List<String> collectedIncorrectness = new ArrayList<>();
528 final IncorrectnessListener listener = new IncorrectnessListener() {
529 @Override
530 public void notify(final String message, final Object origin) {
531 collectedIncorrectness.add(message);
532 }
533 };
534 webClient.setIncorrectnessListener(listener);
535
536 final MockWebConnection webConnection = new MockWebConnection();
537 webClient.setWebConnection(webConnection);
538 webConnection.setDefaultResponse(html);
539 final HtmlPage page = webClient.getPage(URL_FIRST);
540 page.getAnchors().get(0).click();
541
542 final String[] expectedIncorrectness = {"Multiple 'base' detected, only the first is used.",
543 "Multiple 'base' detected, only the first is used."};
544 assertEquals(expectedIncorrectness, collectedIncorrectness);
545 }
546
547
548
549
550 @Test
551 public void testBase_InsideBody() throws Exception {
552 final String html = DOCTYPE_HTML
553 + "<html><body>\n"
554 + " <base href='" + URL_SECOND + "'>\n"
555 + " <a href='somepage.html'>link</a>\n"
556 + "</body></html>";
557
558 final WebClient webClient = getWebClient();
559
560 final MockWebConnection webConnection = new MockWebConnection();
561 webClient.setWebConnection(webConnection);
562 webConnection.setDefaultResponse(html);
563 final HtmlPage page = webClient.getPage(URL_FIRST);
564 final HtmlAnchor anchor = page.getAnchors().get(0);
565 final HtmlPage secondPage = anchor.click();
566
567 assertEquals(URL_SECOND + "somepage.html", secondPage.getUrl());
568 }
569
570
571
572
573 @Test
574 public void onLoadHandler_BodyStatement() throws Exception {
575 final String htmlContent = DOCTYPE_HTML
576 + "<html><head><title>foo</title>\n"
577 + "</head><body onLoad='alert(\"foo\")'>\n"
578 + "</body></html>";
579 final List<String> collectedAlerts = new ArrayList<>();
580 final HtmlPage page = loadPage(htmlContent, collectedAlerts);
581 assertEquals("foo", page.getTitleText());
582
583 final String[] expectedAlerts = {"foo"};
584 assertEquals(expectedAlerts, collectedAlerts);
585 }
586
587
588
589
590
591 @Test
592 public void onLoadHandler_TwoBodyStatements() throws Exception {
593 final String htmlContent = DOCTYPE_HTML
594 + "<html><head><title>foo</title>\n"
595 + "</head><body onLoad='alert(\"foo\");alert(\"bar\")'>\n"
596 + "</body></html>";
597 final List<String> collectedAlerts = new ArrayList<>();
598 final HtmlPage page = loadPage(htmlContent, collectedAlerts);
599 assertEquals("foo", page.getTitleText());
600
601 final String[] expectedAlerts = {"foo", "bar"};
602 assertEquals(expectedAlerts, collectedAlerts);
603 }
604
605
606
607
608
609 @Test
610 public void onLoadHandler_BodyName() throws Exception {
611 final String htmlContent = DOCTYPE_HTML
612 + "<html><head><title>foo</title>\n"
613 + "<script type='text/javascript'>\n"
614 + " window.onload = function() {alert('foo')}</script>\n"
615 + "</head><body></body></html>";
616 final List<String> collectedAlerts = new ArrayList<>();
617 final HtmlPage page = loadPage(htmlContent, collectedAlerts);
618 assertEquals("foo", page.getTitleText());
619
620 final String[] expectedAlerts = {"foo"};
621 assertEquals(expectedAlerts, collectedAlerts);
622 }
623
624
625
626
627
628 @Test
629 public void onLoadHandler_BodyName_NotAFunction() throws Exception {
630 final String htmlContent = DOCTYPE_HTML
631 + "<html><head><title>foo</title></head>\n"
632 + "<body onLoad='foo=4711'>\n"
633 + "<a name='alert' href='javascript:alert(foo)'/>\n"
634 + "</body></html>";
635 final List<String> collectedAlerts = new ArrayList<>();
636 final HtmlPage page = loadPage(htmlContent, collectedAlerts);
637 assertEquals("foo", page.getTitleText());
638
639 page.getAnchorByName("alert").click();
640
641 final String[] expectedAlerts = {"4711"};
642 assertEquals(expectedAlerts, collectedAlerts);
643 }
644
645
646
647
648
649 @Test
650 public void onLoadHandler_ScriptName() throws Exception {
651 final String htmlContent = DOCTYPE_HTML
652 + "<html><head><title>foo</title>\n"
653 + "<script type='text/javascript'>\n"
654 + "load=function() {alert('foo')};\n"
655 + "onload=load\n"
656 + "</script></head><body></body></html>";
657 final List<String> collectedAlerts = new ArrayList<>();
658 final HtmlPage page = loadPage(htmlContent, collectedAlerts);
659 assertEquals("foo", page.getTitleText());
660
661 final String[] expectedAlerts = {"foo"};
662 assertEquals(expectedAlerts, collectedAlerts);
663 }
664
665
666
667
668 @Test
669 public void embeddedMetaTag_Regression() throws Exception {
670 final String htmlContent = DOCTYPE_HTML
671 + "<html><head><title>foo</title>\n"
672 + "</head><body>\n"
673 + "<table><tr><td>\n"
674 + "<meta name=vs_targetSchema content=\"http://schemas.microsoft.com/intellisense/ie5\">\n"
675 + "<form name='form1'>\n"
676 + " <input type='text' name='textfield1' id='textfield1' value='foo' />\n"
677 + " <input type='text' name='textfield2' id='textfield2'/>\n"
678 + "</form>\n"
679 + "</td></tr></table>\n"
680 + "</body></html>";
681 final List<String> collectedAlerts = new ArrayList<>();
682
683
684 final HtmlPage page = loadPage(htmlContent, collectedAlerts);
685 assertEquals("foo", page.getTitleText());
686
687 final List<?> expectedAlerts = Collections.EMPTY_LIST;
688 assertEquals(expectedAlerts, collectedAlerts);
689 }
690
691
692
693
694
695 @Test
696 public void getPageEncoding_EmptyCharset() throws Exception {
697 final String html = DOCTYPE_HTML
698 + "<html><head>\n"
699 + "<meta http-equiv='Content-Type' content='text/html; charset='>\n"
700 + "</head><body>abc</body></html>";
701 final HtmlPage page = loadPage(html);
702 assertEquals(ISO_8859_1, page.getCharset());
703 }
704
705
706
707
708
709
710 @Test
711 public void getPageEncoding_HeaderHasPrecedenceOverMetaTag() throws Exception {
712 final String html = DOCTYPE_HTML
713 + "<html><head><meta content='text/html; charset=iso-8859-1' http-equiv='Content-Type'/>\n"
714 + "</head><body></body></html>";
715 final MockWebConnection conn = new MockWebConnection();
716 conn.setResponse(URL_FIRST, html, "text/html; charset=UTF-8");
717 final WebClient client = getWebClient();
718 client.setWebConnection(conn);
719 final HtmlPage page = client.getPage(URL_FIRST);
720 assertSame(UTF_8, page.getCharset());
721 assertEquals(page.getWebResponse().getContentCharset(), page.getCharset());
722 }
723
724
725
726
727 @Test
728 public void getForms() throws Exception {
729 final String htmlContent = DOCTYPE_HTML
730 + "<html>\n"
731 + "<head><title>foo</title></head>\n"
732 + "<body>\n"
733 + "<form name='one'>\n"
734 + "<a id='c' accesskey='c'>foo</a>\n"
735 + "</form>\n"
736 + "<form name='two'>\n"
737 + "<a id='c' accesskey='c'>foo</a>\n"
738 + "</form>\n"
739 + "<input name='foo' type='submit' disabled='disabled' id='foo' accesskey='f'/>\n"
740 + "<input name='bar' type='submit' id='bar'/>\n"
741 + "</form></body></html>";
742
743 final HtmlPage page = loadPage(htmlContent);
744
745 final List<HtmlForm> expectedForms = Arrays.asList(new HtmlForm[] {page.getFormByName("one"),
746 page.getFormByName("two")});
747 assertEquals(expectedForms, page.getForms());
748 }
749
750
751
752
753
754 @Test
755 public void refresh_MetaTag_DefaultRefreshHandler() throws Exception {
756 testRefresh_MetaTag("<META HTTP-EQUIV=\"Refresh\" CONTENT=\"2;URL=§§URL§§\">");
757 }
758
759
760
761
762 @Test
763 public void refresh_MetaTag_caseSensitivity() throws Exception {
764 testRefresh_MetaTag("<META HTTP-EQUIV=\"Refresh\" CONTENT=\"2;Url=§§URL§§\">");
765 }
766
767
768
769
770
771 @Test
772 public void refresh_MetaTag_spaceSeparator() throws Exception {
773 testRefresh_MetaTag("<META HTTP-EQUIV=\"Refresh\" CONTENT=\"2 Url=§§URL§§\">");
774 testRefresh_MetaTag("<META HTTP-EQUIV=\"Refresh\" CONTENT=\"2\nUrl=§§URL§§\">");
775 }
776
777
778
779
780
781 @Test
782 public void refresh_MetaTag_NoUrl() throws Exception {
783 final String firstContent = DOCTYPE_HTML
784 + "<html><head><title>first</title>\n"
785 + "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"1\">\n"
786 + "</head><body></body></html>";
787
788 final WebClient client = getWebClient();
789 final List<Object> collectedItems = new ArrayList<>();
790 client.setRefreshHandler(new LoggingRefreshHandler(collectedItems));
791
792 final MockWebConnection webConnection = new MockWebConnection();
793 webConnection.setResponse(URL_FIRST, firstContent);
794 client.setWebConnection(webConnection);
795
796 client.getPage(URL_FIRST);
797
798
799 assertEquals("first", collectedItems.get(0));
800 assertEquals(URL_FIRST, (URL) collectedItems.get(1));
801 assertEquals(Integer.valueOf(1), collectedItems.get(2));
802 }
803
804
805
806
807
808
809
810 @Test
811 public void refresh_ImmediateRefresh_AvoidOOME() throws Exception {
812 final String firstContent = DOCTYPE_HTML
813 + "<html><head><title>first</title>\n"
814 + "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"1\">\n"
815 + "</head><body></body></html>";
816
817 final WebClient client = getWebClient();
818 assertTrue(ImmediateRefreshHandler.class.isInstance(client.getRefreshHandler()));
819 try {
820 loadPage(firstContent);
821 Assertions.fail("should have thrown");
822 }
823 catch (final RuntimeException e) {
824 assertTrue(e.getMessage().indexOf("could have caused an OutOfMemoryError") > -1);
825 }
826 Thread.sleep(1000);
827 }
828
829
830
831
832
833 @Test
834 public void refresh_MetaTagQuoted() throws Exception {
835 testRefresh_MetaTag("<META HTTP-EQUIV='Refresh' CONTENT='0;URL=\"§§URL§§\"'>");
836 }
837
838
839
840
841
842 @Test
843 public void refresh_MetaTagPartlyQuoted() throws Exception {
844 testRefresh_MetaTag("<META HTTP-EQUIV='Refresh' CONTENT=\"0;URL='§§URL§§\">");
845 }
846
847 private void testRefresh_MetaTag(final String metaTag) throws Exception {
848 final String firstContent = DOCTYPE_HTML
849 + "<html><head><title>first</title>\n"
850 + metaTag.replace("§§URL§§", URL_SECOND.toString()) + "\n"
851 + "<META HTTP-EQUIV='Refresh' CONTENT=\"0;URL='" + URL_SECOND + "\">\n"
852 + "</head><body></body></html>";
853 final String secondContent = DOCTYPE_HTML
854 + "<html><head><title>second</title></head><body></body></html>";
855
856 final WebClient client = getWebClient();
857
858 final MockWebConnection webConnection = new MockWebConnection();
859 webConnection.setResponse(URL_FIRST, firstContent);
860 webConnection.setResponse(URL_SECOND, secondContent);
861 client.setWebConnection(webConnection);
862
863 final HtmlPage page = client.getPage(URL_FIRST);
864
865 assertEquals("second", page.getTitleText());
866 }
867
868
869
870
871
872 @Test
873 public void refresh_MetaTagNoScript() throws Exception {
874 final String firstContent = DOCTYPE_HTML
875 + "<html><head><title>first</title>\n"
876 + "<noscript>\n"
877 + "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"0;URL=" + URL_SECOND + "\">\n"
878 + "</noscript>\n"
879 + "</head><body></body></html>";
880 final String secondContent = DOCTYPE_HTML + "<html><head><title>second</title></head><body></body></html>";
881
882 final WebClient client = getWebClient();
883
884 final MockWebConnection webConnection = new MockWebConnection();
885 webConnection.setResponse(URL_FIRST, firstContent);
886 webConnection.setResponse(URL_SECOND, secondContent);
887 client.setWebConnection(webConnection);
888
889 HtmlPage page = client.getPage(URL_FIRST);
890 assertEquals("first", page.getTitleText());
891
892 client.getOptions().setJavaScriptEnabled(false);
893 page = client.getPage(URL_FIRST);
894 assertEquals("second", page.getTitleText());
895 }
896
897
898
899
900
901 @Test
902 public void refresh_MetaTag_CustomRefreshHandler() throws Exception {
903 final String firstContent = DOCTYPE_HTML
904 + "<html><head><title>first</title>\n"
905 + "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"3;URL=" + URL_SECOND + "\">\n"
906 + "</head><body></body></html>";
907 final String secondContent = DOCTYPE_HTML + "<html><head><title>second</title></head><body></body></html>";
908
909 final WebClient client = getWebClient();
910 final List<Object> collectedItems = new ArrayList<>();
911 client.setRefreshHandler(new LoggingRefreshHandler(collectedItems));
912
913 final MockWebConnection webConnection = new MockWebConnection();
914 webConnection.setResponse(URL_FIRST, firstContent);
915 webConnection.setResponse(URL_SECOND, secondContent);
916 client.setWebConnection(webConnection);
917
918 final HtmlPage page = client.getPage(URL_FIRST);
919
920 assertEquals("first", page.getTitleText());
921
922
923 assertEquals("first", collectedItems.get(0));
924 assertEquals(URL_SECOND, (URL) collectedItems.get(1));
925 assertEquals(Integer.valueOf(3), collectedItems.get(2));
926 }
927
928
929
930
931
932
933 @Test
934 public void refresh_MetaTag_Whitespace() throws Exception {
935 testRefresh_MetaTag("<META HTTP-EQUIV='Refresh' CONTENT='0 ; URL=§§URL§§'>");
936 }
937
938
939
940
941
942
943 @Test
944 public void refresh_MetaTag_Double() throws Exception {
945 testRefresh_MetaTag("<META HTTP-EQUIV='Refresh' CONTENT='1.2 ; URL=§§URL§§'>");
946 }
947
948
949
950
951
952 @Test
953 public void refresh_HttpResponseHeader() throws Exception {
954 final String firstContent = DOCTYPE_HTML
955 + "<html><head><title>first</title>\n"
956 + "</head><body></body></html>";
957 final String secondContent = DOCTYPE_HTML + "<html><head><title>second</title></head><body></body></html>";
958
959 final WebClient client = getWebClient();
960
961 final MockWebConnection webConnection = new MockWebConnection();
962 webConnection.setResponse(URL_FIRST, firstContent, 200, "OK", MimeType.TEXT_HTML, Collections
963 .singletonList(new NameValuePair("Refresh", "2;URL=" + URL_SECOND)));
964 webConnection.setResponse(URL_SECOND, secondContent);
965 client.setWebConnection(webConnection);
966
967 final HtmlPage page = client.getPage(URL_FIRST);
968
969 assertEquals("second", page.getTitleText());
970 }
971
972
973
974
975
976 @Test
977 public void documentParentIsNull() throws Exception {
978 final String htmlContent = DOCTYPE_HTML
979 + "<html>\n"
980 + "<head><title>foo</title></head>\n"
981 + "<body>\n"
982 + "</body></html>";
983 final HtmlPage page = loadPage(htmlContent);
984
985 assertNotNull(page);
986 assertNull(page.getParentNode());
987 }
988
989
990
991
992 @Test
993 public void documentElement() throws Exception {
994 final String htmlContent = DOCTYPE_HTML
995 + "<html>\n"
996 + "<head><title>foo</title></head>\n"
997 + "<body>\n"
998 + "</body></html>";
999 final HtmlPage page = loadPage(htmlContent);
1000
1001 final DomElement root = page.getDocumentElement();
1002
1003 assertNotNull(root);
1004 assertEquals("html", root.getTagName());
1005 assertSame(page, root.getParentNode());
1006 }
1007
1008
1009
1010
1011 @Test
1012 public void documentNodeType() throws Exception {
1013 final String htmlContent = DOCTYPE_HTML
1014 + "<html>\n"
1015 + "<head><title>foo</title></head>\n"
1016 + "<body>\n"
1017 + "</body></html>";
1018 final HtmlPage page = loadPage(htmlContent);
1019
1020 final DomElement root = page.getDocumentElement();
1021
1022 assertEquals(org.w3c.dom.Node.DOCUMENT_NODE, page.getNodeType());
1023 assertEquals(org.w3c.dom.Node.ELEMENT_NODE, root.getNodeType());
1024 assertEquals("#document", page.getNodeName());
1025 }
1026
1027
1028
1029
1030 @Test
1031 public void deregisterFrameWithoutSrc() throws Exception {
1032 final String htmlContent = DOCTYPE_HTML
1033 + "<html>\n"
1034 + "<head><title>foo</title></head>\n"
1035 + "<body>\n"
1036 + "<iframe></iframe>\n"
1037 + "<a href='about:blank'>link</a>\n"
1038 + "</body></html>";
1039
1040 final HtmlPage page = loadPage(htmlContent);
1041 final HtmlAnchor link = page.getAnchors().get(0);
1042 link.click();
1043 }
1044
1045
1046
1047
1048
1049 @Test
1050 public void onLoadReturn() throws Exception {
1051 final String htmlContent = DOCTYPE_HTML
1052 + "<html><head><title>foo</title></head>\n"
1053 + "<body onload='return true'>\n"
1054 + "</body></html>";
1055
1056 loadPage(htmlContent);
1057 }
1058
1059
1060
1061
1062 @Test
1063 public void asXml() throws Exception {
1064 final String htmlContent =
1065 "<html><head><title>foo</title></head>"
1066 + "<body><p>helloworld</p></body>"
1067 + "</html>";
1068
1069 final HtmlPage page = loadPage(htmlContent);
1070 String xml = page.asXml();
1071 final String prefix = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
1072 assertTrue(xml.startsWith(prefix));
1073 xml = xml.substring(prefix.length());
1074 assertEquals(htmlContent, xml.replaceAll("\\s", ""));
1075 }
1076
1077
1078
1079
1080
1081 @Test
1082 public void asXmlValidHtmlOutput() throws Exception {
1083 final String html =
1084 "<html><head><title>foo</title>"
1085 + "<script src='script.js'></script></head>"
1086 + "<body><div></div><iframe src='about:blank'></iframe></body>"
1087 + "</html>";
1088
1089 final WebClient client = getWebClient();
1090 final MockWebConnection webConnection = new MockWebConnection();
1091 webConnection.setDefaultResponse(html);
1092 webConnection.setResponse(new URL(URL_FIRST, "script.js"), "", "text/javascript");
1093 client.setWebConnection(webConnection);
1094
1095 final HtmlPage page = client.getPage(URL_FIRST);
1096
1097 String xml = page.asXml();
1098 final String prefix = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
1099 assertTrue(xml.startsWith(prefix));
1100 xml = xml.substring(prefix.length());
1101 assertEquals(html, xml
1102 .replaceAll("[\\n\\r]", "")
1103 .replaceAll("\\s\\s+", "")
1104 .replaceAll("\"", "'"));
1105 }
1106
1107
1108
1109
1110 @Test
1111 public void asXml2() throws Exception {
1112 final String htmlContent = DOCTYPE_HTML
1113 + "<html><head><title>foo</title>\n"
1114 + "<script>var test = 15 < 16;</script></head>\n"
1115 + "</head>\n"
1116 + "<body onload='test=(1 > 2) && (45 < 78)'><p>helloworld &amp; helloall</p></body>\n"
1117 + "</html>";
1118
1119 final HtmlPage page = loadPage(htmlContent);
1120 assertNotNull("xml document could not be parsed", page.asXml());
1121 final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
1122 final DocumentBuilder builder = factory.newDocumentBuilder();
1123 builder.parse(IOUtils.toInputStream(page.asXml(), StandardCharsets.ISO_8859_1));
1124 }
1125
1126
1127
1128
1129 @Test
1130 public void asXml_unicode() throws Exception {
1131 final String unicodeString = "\u064A\u0627 \u0644\u064A\u064A\u0644";
1132 final String html = DOCTYPE_HTML
1133 + "<html>\n"
1134 + "<head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'></head>\n"
1135 + "<body><span id='foo'>" + unicodeString + "</span></body></html>";
1136
1137 final WebClient client = getWebClient();
1138 final MockWebConnection webConnection = new MockWebConnection();
1139
1140 webConnection.setDefaultResponse(StringUtils.toByteArray(html, UTF_8), 200, "OK", MimeType.TEXT_HTML);
1141 client.setWebConnection(webConnection);
1142
1143 final HtmlPage page = client.getPage(URL_FIRST);
1144 final String xml = page.asXml();
1145 assertTrue(xml.contains("<?xml "));
1146 assertTrue(xml.contains(unicodeString));
1147 }
1148
1149
1150
1151
1152 @Test
1153 public void asXml_noscript() throws Exception {
1154 final String html = DOCTYPE_HTML
1155 + "<html>"
1156 + "<body>"
1157 + "<noscript><p><strong>your browser does not support JavaScript</strong></p></noscript>"
1158 + "</body></html>";
1159
1160 final String expected = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n"
1161 + "<html>\r\n"
1162 + " <head/>\r\n"
1163 + " <body>\r\n"
1164 + " <noscript>"
1165 + "<p><strong>your browser does not support JavaScript</strong></p>"
1166 + "</noscript>\r\n"
1167 + " </body>\r\n"
1168 + "</html>";
1169
1170 final HtmlPage page = loadPage(html);
1171 assertEquals(expected, page.asXml());
1172 }
1173
1174
1175
1176
1177 @Test
1178 public void getElementsById() throws Exception {
1179 final String html = DOCTYPE_HTML
1180 + "<html><body>"
1181 + "<div id='a'>foo</div>"
1182 + "<div id='b'/><div id='b'/>"
1183 + "<div id='c'><div id='c'/></div>"
1184 + "</body></html>";
1185 final HtmlPage page = loadPage(html);
1186 assertEquals(1, page.getElementsById("a").size());
1187 assertEquals(2, page.getElementsById("b").size());
1188 assertEquals(2, page.getElementsById("c").size());
1189 assertEquals(0, page.getElementsById("d").size());
1190
1191 final DomElement a = page.getElementsById("a").get(0);
1192 a.remove();
1193 assertEquals(0, page.getElementsById("a").size());
1194
1195 final DomElement b1 = page.getElementsById("b").get(0);
1196 b1.appendChild(a);
1197
1198 assertEquals(1, page.getElementsById("a").size());
1199 }
1200
1201
1202
1203
1204 @Test
1205 public void getElementsByName() throws Exception {
1206 final String html = DOCTYPE_HTML
1207 + "<html><body><div name='a'>foo</div><div name='b'/><div name='b'/></body></html>";
1208 final HtmlPage page = loadPage(html);
1209 assertEquals(1, page.getElementsByName("a").size());
1210 assertEquals(2, page.getElementsByName("b").size());
1211 assertEquals(0, page.getElementsByName("c").size());
1212
1213 final DomElement a = page.getElementsByName("a").get(0);
1214 a.remove();
1215 assertEquals(0, page.getElementsByName("a").size());
1216
1217 final DomElement b1 = page.getElementsByName("b").get(0);
1218 b1.appendChild(a);
1219 assertEquals(1, page.getElementsByName("a").size());
1220 }
1221
1222
1223
1224
1225 @Test
1226 public void getElementByName() throws Exception {
1227 final String html = DOCTYPE_HTML
1228 + "<html><body>\n"
1229 + "<div id='a' name='a'>foo</div>\n"
1230 + "<div id='b1' name='b'>bar</div>\n"
1231 + "<div id='b2' name='b'>baz</div></body></html>";
1232 final HtmlPage page = loadPage(html);
1233 assertEquals(page.getElementById("a"), page.getElementByName("a"));
1234 assertEquals(page.getElementById("b1"), page.getElementByName("b"));
1235
1236 page.getElementByName("b").remove();
1237 assertEquals(page.getElementById("b2"), page.getElementByName("b"));
1238 }
1239
1240
1241
1242
1243 @Test
1244 public void getElementByNameNotfound() throws Exception {
1245 final String html = DOCTYPE_HTML
1246 + "<html><body>\n"
1247 + "<div id='a' name='a'>foo</div>\n"
1248 + "<div id='b1' name='b'>bar</div>\n"
1249 + "<div id='b2' name='b'>baz</div></body></html>";
1250 final HtmlPage page = loadPage(html);
1251
1252 Assertions.assertThrows(ElementNotFoundException.class, () -> page.getElementByName("c"));
1253 }
1254
1255
1256
1257
1258 @Test
1259 public void getHtmlElementsByIdAndOrName() throws Exception {
1260 final String html = DOCTYPE_HTML
1261 + "<html><body><div name='a' id='a'>foo</div><div name='b' id='c'>bar</div>"
1262 + "<div name='b' id='d'>bar</div></body></html>";
1263 final HtmlPage page = loadPage(html);
1264 assertEquals(1, page.getElementsByIdAndOrName("a").size());
1265 assertEquals(2, page.getElementsByIdAndOrName("b").size());
1266 assertEquals(1, page.getElementsByIdAndOrName("c").size());
1267 assertEquals(1, page.getElementsByIdAndOrName("d").size());
1268
1269 final DomElement a = page.getElementsByIdAndOrName("a").get(0);
1270 a.remove();
1271 assertEquals(0, page.getElementsByIdAndOrName("a").size());
1272
1273 final DomElement b1 = page.getElementsByIdAndOrName("b").get(0);
1274 b1.appendChild(a);
1275 assertEquals(1, page.getElementsByIdAndOrName("a").size());
1276 }
1277
1278
1279
1280
1281
1282 @Test
1283 public void getHtmlElementByIdAfterRemove() throws Exception {
1284 final String htmlContent = DOCTYPE_HTML
1285 + "<html><head><title>foo</title></head>\n"
1286 + "<body>\n"
1287 + "<div id='div1'>\n"
1288 + "<div id='div2'>\n"
1289 + "</div>\n"
1290 + "</div>\n"
1291 + "</body>\n"
1292 + "</html>";
1293
1294 final HtmlPage page = loadPage(htmlContent);
1295 final HtmlElement div1 = page.getHtmlElementById("div1");
1296 page.getHtmlElementById("div2");
1297 div1.remove();
1298 try {
1299 page.getHtmlElementById("div1");
1300 Assertions.fail("div1 should have been removed");
1301 }
1302 catch (final ElementNotFoundException e) {
1303
1304 }
1305
1306 try {
1307 page.getHtmlElementById("div2");
1308 Assertions.fail("div2 should have been removed");
1309 }
1310 catch (final ElementNotFoundException e) {
1311
1312 }
1313 }
1314
1315
1316
1317
1318
1319
1320 @Test
1321 public void getHtmlElementById_idTwice() throws Exception {
1322 final String htmlContent = DOCTYPE_HTML
1323 + "<html><head><title>foo</title></head>\n"
1324 + "<body>\n"
1325 + "<div id='id1'>foo</div>\n"
1326 + "<span id='id1'>bla</span>\n"
1327 + "</body>\n"
1328 + "</html>";
1329
1330 final HtmlPage page = loadPage(htmlContent);
1331 final HtmlElement elt1 = page.getHtmlElementById("id1");
1332 assertEquals("div", elt1.getNodeName());
1333 elt1.remove();
1334 assertEquals("span", page.getHtmlElementById("id1").getNodeName());
1335 }
1336
1337
1338
1339
1340
1341 @Test
1342 @Alerts("webm=none")
1343 public void setCookieMetaTag() throws Exception {
1344 final String content = DOCTYPE_HTML
1345 + "<html><head>\n"
1346 + "<meta http-equiv='set-cookie' content='webm=none; path=/;'>\n"
1347 + "</head><body>\n"
1348 + "<script>document.title = document.cookie</script>\n"
1349 + "</body></html>";
1350
1351 final HtmlPage page = loadPage(content);
1352 assertEquals(getExpectedAlerts()[0], page.getTitleText());
1353
1354 final Set<Cookie> cookies = page.getWebClient().getCookieManager().getCookies();
1355 assertEquals(1, cookies.size());
1356 final Cookie cookie = cookies.iterator().next();
1357 assertEquals(page.getUrl().getHost(), cookie.getDomain());
1358 assertEquals("webm", cookie.getName());
1359 assertEquals("none", cookie.getValue());
1360 assertEquals("/", cookie.getPath());
1361 }
1362
1363
1364
1365
1366
1367 @Test
1368 public void noSlashURL() throws Exception {
1369 testNoSlashURL("http:/second");
1370 testNoSlashURL("http:second");
1371 }
1372
1373 private void testNoSlashURL(final String url) throws Exception {
1374 final String firstContent = DOCTYPE_HTML
1375 + "<html><body>\n"
1376 + "<iframe id='myIFrame' src='" + url + "'></iframe>\n"
1377 + "</body></html>";
1378
1379 final String secondContent = DOCTYPE_HTML + "<html><body></body></html>";
1380 final WebClient client = getWebClient();
1381
1382 final URL secondURL = new URL("http://second/");
1383 final MockWebConnection webConnection = new MockWebConnection();
1384 webConnection.setResponse(URL_FIRST, firstContent);
1385 webConnection.setResponse(secondURL, secondContent);
1386
1387 client.setWebConnection(webConnection);
1388
1389 final HtmlPage firstPage = client.getPage(URL_FIRST);
1390 final HtmlInlineFrame iframe = firstPage.getHtmlElementById("myIFrame");
1391
1392 assertEquals(secondURL, iframe.getEnclosedPage().getUrl());
1393 }
1394
1395
1396
1397
1398 @Test
1399 public void metaTagWithEmptyURL() throws Exception {
1400 final WebClient client = getWebClient();
1401 client.setRefreshHandler(new ImmediateRefreshHandler());
1402
1403
1404
1405 final MockWebConnection webConnection = new MockWebConnection() {
1406 private int nbCalls_ = 0;
1407 @Override
1408 public WebResponse getResponse(final WebRequest request) throws IOException {
1409 String content = DOCTYPE_HTML + "<html><head>\n";
1410 if (nbCalls_ == 0) {
1411 content += "<meta http-equiv='refresh' content='1; URL='>\n";
1412 }
1413 content += "</head><body></body></html>";
1414 nbCalls_++;
1415
1416 final StringWebResponse response = new StringWebResponse(content, request.getUrl());
1417 response.getWebRequest().setHttpMethod(request.getHttpMethod());
1418 return response;
1419 }
1420 };
1421 client.setWebConnection(webConnection);
1422
1423 final WebRequest request = new WebRequest(URL_FIRST);
1424 request.setHttpMethod(HttpMethod.POST);
1425 client.getPage(request);
1426 }
1427
1428
1429
1430
1431 @Test
1432 public void serialization() throws Exception {
1433
1434
1435
1436 final String content = DOCTYPE_HTML
1437 + "<html><body>\n"
1438 + "<div id='myId'>Hello there!</div>\n"
1439 + "<script>\n"
1440 + " var x = document.all;\n"
1441 + " window.onload = function() {alert('foo')};\n"
1442
1443
1444
1445 + " var aktiv = window.setInterval('foo()', 1000);\n"
1446 + " var i = 0;\n"
1447 + " function foo() {\n"
1448 + " i = i + 1;\n"
1449 + " if (i >= 10)\n"
1450 + " window.clearInterval(aktiv);\n"
1451 + " }\n"
1452 + "</script>\n"
1453 + "<form name='f' id='f'></form>\n"
1454 + "<script>var y = document.getElementById('f').elements;</script>\n"
1455 + "</body></html>";
1456
1457
1458
1459 final List<String> expectedAlerts = new LinkedList<>();
1460 expectedAlerts.add("foo");
1461
1462 final HtmlPage page1 = loadPage(content, expectedAlerts);
1463 final byte[] bytes = SerializationUtils.serialize(page1);
1464
1465 final HtmlPage page2 = (HtmlPage) SerializationUtils.deserialize(bytes);
1466
1467 final Iterator<HtmlElement> iterator1 = page1.getHtmlElementDescendants().iterator();
1468 final Iterator<HtmlElement> iterator2 = page2.getHtmlElementDescendants().iterator();
1469 while (iterator1.hasNext()) {
1470 assertTrue(iterator2.hasNext());
1471 final HtmlElement element1 = iterator1.next();
1472 final HtmlElement element2 = iterator2.next();
1473 assertEquals(element1.getNodeName(), element2.getNodeName());
1474 }
1475 assertFalse(iterator2.hasNext());
1476 assertEquals("Hello there!", page2.getHtmlElementById("myId").getFirstChild().getNodeValue());
1477 }
1478
1479
1480
1481
1482
1483 @Test
1484 public void serializationLambda() throws Exception {
1485 final String content = DOCTYPE_HTML
1486 + "<html><body>\n"
1487 + "<div id='myId'>Hello there!</div>\n"
1488 + "<form name='f' id='f'></form>\n"
1489 + "<script>var y = document.body.getElementsByTagName('form').elements;</script>\n"
1490 + "</body></html>";
1491
1492 final HtmlPage page1 = loadPage(content);
1493 final byte[] bytes = SerializationUtils.serialize(page1);
1494
1495 final HtmlPage page2 = (HtmlPage) SerializationUtils.deserialize(bytes);
1496
1497 final Iterator<HtmlElement> iterator1 = page1.getHtmlElementDescendants().iterator();
1498 final Iterator<HtmlElement> iterator2 = page2.getHtmlElementDescendants().iterator();
1499 while (iterator1.hasNext()) {
1500 assertTrue(iterator2.hasNext());
1501 final HtmlElement element1 = iterator1.next();
1502 final HtmlElement element2 = iterator2.next();
1503 assertEquals(element1.getNodeName(), element2.getNodeName());
1504 }
1505 assertFalse(iterator2.hasNext());
1506 assertEquals("Hello there!", page2.getHtmlElementById("myId").getFirstChild().getNodeValue());
1507 }
1508
1509
1510
1511
1512 @Test
1513 public void serializationStaticDomNodeList() throws Exception {
1514 final String content = DOCTYPE_HTML
1515 + "<html><body>\n"
1516 + "<div id='myId'>Hello there!</div>\n"
1517 + "<form name='f' id='f'></form>\n"
1518 + "<script>var y = document.querySelectorAll('*');</script>\n"
1519 + "</body></html>";
1520
1521 final HtmlPage page1 = loadPage(content);
1522 final byte[] bytes = SerializationUtils.serialize(page1);
1523
1524 final HtmlPage page2 = (HtmlPage) SerializationUtils.deserialize(bytes);
1525
1526 final Iterator<HtmlElement> iterator1 = page1.getHtmlElementDescendants().iterator();
1527 final Iterator<HtmlElement> iterator2 = page2.getHtmlElementDescendants().iterator();
1528 while (iterator1.hasNext()) {
1529 assertTrue(iterator2.hasNext());
1530 final HtmlElement element1 = iterator1.next();
1531 final HtmlElement element2 = iterator2.next();
1532 assertEquals(element1.getNodeName(), element2.getNodeName());
1533 }
1534 assertFalse(iterator2.hasNext());
1535 assertEquals("Hello there!", page2.getHtmlElementById("myId").getFirstChild().getNodeValue());
1536 }
1537
1538
1539
1540
1541
1542 @Test
1543 public void clonedPageHasOwnIdMap() throws Exception {
1544 final String content = DOCTYPE_HTML
1545 + "<html><head><title>foo</title>"
1546 + "<body>"
1547 + "<div id='id1' class='cl1'><div id='id2' class='cl2'></div></div>"
1548 + "</body></html>";
1549
1550 final HtmlPage page = loadPage(content);
1551 final HtmlElement id1 = (HtmlElement) page.getDocumentElement().getLastChild().getLastChild();
1552 assertEquals("id1", id1.getId());
1553 assertSame(id1, page.getHtmlElementById("id1"));
1554 final HtmlPage clone = page.cloneNode(true);
1555 assertSame(id1, page.getHtmlElementById("id1"));
1556 final HtmlElement id1clone = (HtmlElement) clone.getDocumentElement().getLastChild().getLastChild();
1557 assertNotSame(id1, id1clone);
1558 assertEquals("id1", id1clone.getId());
1559 assertSame(id1clone, clone.getHtmlElementById("id1"));
1560 assertNotSame(id1clone, page.getHtmlElementById("id1"));
1561 assertNotSame(id1, clone.getHtmlElementById("id1"));
1562
1563 page.getHtmlElementById("id2").remove();
1564 try {
1565 page.getHtmlElementById("id2");
1566 Assertions.fail("should have thrown ElementNotFoundException");
1567 }
1568 catch (final ElementNotFoundException expected) {
1569 }
1570 assertNotNull(clone.getHtmlElementById("id2"));
1571 }
1572
1573
1574
1575
1576
1577 @Test
1578 public void clonedPageHasOwnDocumentElement() throws Exception {
1579 final String content = DOCTYPE_HTML
1580 + "<html><head><title>foo</title>\n"
1581 + "<body>\n"
1582 + "<div id='id1' class='cl1'><div id='id2' class='cl2'></div></div>\n"
1583 + "</body></html>";
1584
1585 final HtmlPage page = loadPage(content);
1586 final HtmlPage clone = page.cloneNode(true);
1587 assertTrue(page != clone);
1588 final DomElement doc = page.getDocumentElement();
1589 final DomElement docclone = clone.getDocumentElement();
1590 assertTrue(doc != docclone);
1591 }
1592
1593
1594
1595
1596 @Test
1597 public void htmlAttributeChangeListener_AddAttribute() throws Exception {
1598 final String htmlContent = DOCTYPE_HTML
1599 + "<html><head><title>foo</title>\n"
1600 + "<script>\n"
1601 + " function clickMe() {\n"
1602 + " var p1 = document.getElementById('p1');\n"
1603 + " p1.setAttribute('title', 'myTitle');\n"
1604 + " }\n"
1605 + "</script>\n"
1606 + "</head>\n"
1607 + "<body>\n"
1608 + "<p id='p1'></p>\n"
1609 + "<input id='myButton' type='button' onclick='clickMe()'>\n"
1610 + "</body></html>";
1611
1612 final String[] expectedValues = {"attributeAdded: p,title,myTitle"};
1613 final HtmlPage page = loadPage(htmlContent);
1614 final HtmlAttributeChangeListenerTestImpl listenerImpl = new HtmlAttributeChangeListenerTestImpl();
1615 page.addHtmlAttributeChangeListener(listenerImpl);
1616 final HtmlButtonInput myButton = page.getHtmlElementById("myButton");
1617
1618 myButton.click();
1619 assertEquals(expectedValues, listenerImpl.getCollectedValues());
1620 }
1621
1622
1623
1624
1625 @Test
1626 public void htmlAttributeChangeListener_ReplaceAttribute() throws Exception {
1627 final String htmlContent = DOCTYPE_HTML
1628 + "<html><head><title>foo</title>\n"
1629 + "<script>\n"
1630 + " function clickMe() {\n"
1631 + " var p1 = document.getElementById('p1');\n"
1632 + " p1.setAttribute('title', p1.getAttribute('title') + 'a');\n"
1633 + " }\n"
1634 + "</script>\n"
1635 + "</head>\n"
1636 + "<body>\n"
1637 + "<p id='p1' title='myTitle'></p>\n"
1638 + "<input id='myButton' type='button' onclick='clickMe()'>\n"
1639 + "</body></html>";
1640
1641 final String[] expectedValues = {"attributeReplaced: p,title,myTitle"};
1642 final HtmlPage page = loadPage(htmlContent);
1643 final HtmlAttributeChangeListenerTestImpl listenerImpl = new HtmlAttributeChangeListenerTestImpl();
1644 page.addHtmlAttributeChangeListener(listenerImpl);
1645 final HtmlButtonInput myButton = page.getHtmlElementById("myButton");
1646
1647 myButton.click();
1648 assertEquals(expectedValues, listenerImpl.getCollectedValues());
1649 }
1650
1651
1652
1653
1654 @Test
1655 public void htmlAttributeChangeListener_RemoveAttribute() throws Exception {
1656 final String htmlContent = DOCTYPE_HTML
1657 + "<html><head><title>foo</title>\n"
1658 + "<script>\n"
1659 + " function clickMe() {\n"
1660 + " var p1 = document.getElementById('p1');\n"
1661 + " p1.removeAttribute('title');\n"
1662 + " }\n"
1663 + "</script>\n"
1664 + "</head>\n"
1665 + "<body>\n"
1666 + "<p id='p1' title='myTitle'></p>\n"
1667 + "<input id='myButton' type='button' onclick='clickMe()'>\n"
1668 + "</body></html>";
1669
1670 final String[] expectedValues = {"attributeRemoved: p,title,myTitle"};
1671 final HtmlPage page = loadPage(htmlContent);
1672 final HtmlAttributeChangeListenerTestImpl listenerImpl = new HtmlAttributeChangeListenerTestImpl();
1673 page.addHtmlAttributeChangeListener(listenerImpl);
1674 final HtmlButtonInput myButton = page.getHtmlElementById("myButton");
1675
1676 myButton.click();
1677 assertEquals(expectedValues, listenerImpl.getCollectedValues());
1678 }
1679
1680
1681
1682
1683 @Test
1684 public void htmlAttributeChangeListener_RemoveListener() throws Exception {
1685 final String htmlContent = DOCTYPE_HTML
1686 + "<html><head><title>foo</title>\n"
1687 + "<script>\n"
1688 + " function clickMe() {\n"
1689 + " var p1 = document.getElementById('p1');\n"
1690 + " p1.setAttribute('title', p1.getAttribute('title') + 'a');\n"
1691 + " }\n"
1692 + "</script>\n"
1693 + "</head>\n"
1694 + "<body>\n"
1695 + "<p id='p1' title='myTitle'></p>\n"
1696 + "<input id='myButton' type='button' onclick='clickMe()'>\n"
1697 + "</body></html>";
1698
1699 final String[] expectedValues = {"attributeReplaced: p,title,myTitle"};
1700 final HtmlPage page = loadPage(htmlContent);
1701 final HtmlAttributeChangeListenerTestImpl listenerImpl = new HtmlAttributeChangeListenerTestImpl();
1702 page.addHtmlAttributeChangeListener(listenerImpl);
1703 final HtmlButtonInput myButton = page.getHtmlElementById("myButton");
1704
1705 myButton.click();
1706 page.removeHtmlAttributeChangeListener(listenerImpl);
1707 myButton.click();
1708 assertEquals(expectedValues, listenerImpl.getCollectedValues());
1709 }
1710
1711
1712
1713
1714 @Test
1715 public void htmlAttributeChangeListener_ListenerRegistersNewListener() throws Exception {
1716 final String htmlContent = DOCTYPE_HTML
1717 + "<html><head><title>foo</title>\n"
1718 + "</head>\n"
1719 + "<body>\n"
1720 + "<p id='p1' title='myTitle'></p>\n"
1721 + "</body></html>";
1722
1723 final HtmlPage page = loadPage(htmlContent);
1724
1725 final List<String> collector = new ArrayList<>();
1726 final HtmlAttributeChangeListener listener2 = new HtmlAttributeChangeListenerTestImpl() {
1727 @Override
1728 public void attributeReplaced(final HtmlAttributeChangeEvent event) {
1729 collector.add("in listener 2");
1730 }
1731 };
1732 final HtmlAttributeChangeListener listener1 = new HtmlAttributeChangeListenerTestImpl() {
1733 @Override
1734 public void attributeReplaced(final HtmlAttributeChangeEvent event) {
1735 collector.add("in listener 1");
1736 page.addHtmlAttributeChangeListener(listener2);
1737 }
1738 };
1739
1740 page.addHtmlAttributeChangeListener(listener1);
1741
1742 final HtmlElement p = page.getHtmlElementById("p1");
1743 p.setAttribute("title", "new title");
1744
1745 final String[] expectedValues = {"in listener 1"};
1746 assertEquals(expectedValues, collector);
1747 collector.clear();
1748
1749 p.setAttribute("title", "new new title");
1750 final String[] expectedValues2 = {"in listener 1", "in listener 2"};
1751 assertEquals(expectedValues2, collector);
1752 }
1753
1754
1755
1756
1757 @Test
1758 public void caseInsensitiveRegexReplacement() throws Exception {
1759 final String html = DOCTYPE_HTML
1760 + "<html><body><script>\n"
1761 + "var r = /^([#.]?)([a-z0-9\\*_-]*)/i;\n"
1762 + "var s = '#userAgent';\n"
1763 + "s = s.replace(r, '');\n"
1764 + "alert(s.length);\n"
1765 + "</script></body></html>";
1766 final String[] expectedAlerts = {"0"};
1767 final List<String> actualAlerts = new ArrayList<>();
1768 loadPage(html, actualAlerts);
1769 assertEquals(expectedAlerts, actualAlerts);
1770 }
1771
1772
1773
1774
1775 @Test
1776 public void regexReplacementWithFunction() throws Exception {
1777 final String html = DOCTYPE_HTML
1778 + "<html><body><script>\n"
1779 + "var r = /-([a-z])/ig;\n"
1780 + "var s = 'font-size';\n"
1781 + "s = s.replace(r, function(z,b){return b.toUpperCase();});\n"
1782 + "alert(s);\n"
1783 + "</script></body></html>";
1784 final String[] expectedAlerts = {"fontSize"};
1785 final List<String> collectedAlerts = new ArrayList<>();
1786 loadPage(html, collectedAlerts);
1787 assertEquals(expectedAlerts, collectedAlerts);
1788 }
1789
1790
1791
1792
1793 @Test
1794 public void title_EmptyXmlTagExpanded() throws Exception {
1795 final String content = DOCTYPE_HTML
1796 + "<html><head><title/></head>\n"
1797 + "<body>Hello World!</body></html>";
1798 final HtmlPage page = loadPage(content);
1799 assertTrue(page.asXml().indexOf("</title>") != -1);
1800 }
1801
1802
1803
1804
1805 @Test
1806 public void onunLoadHandler() throws Exception {
1807 final String htmlContent = DOCTYPE_HTML
1808 + "<html><head><title>foo</title>\n"
1809 + "</head><body onunload='alert(\"foo\");alert(\"bar\")'>\n"
1810 + "</body></html>";
1811
1812 final String[] expectedAlerts = {"foo", "bar"};
1813 final List<String> collectedAlerts = new ArrayList<>();
1814 final WebClient client = getWebClient();
1815 client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
1816 final MockWebConnection conn = new MockWebConnection();
1817 conn.setResponse(URL_FIRST, htmlContent);
1818 client.setWebConnection(conn);
1819
1820 client.getPage(URL_FIRST);
1821 client.getPage(URL_FIRST);
1822
1823 assertEquals(expectedAlerts, collectedAlerts);
1824 }
1825
1826
1827
1828
1829 @Test
1830 public void onbeforeunloadHandler_ok() throws Exception {
1831 testOnbeforeunloadHandler(true, "second");
1832 }
1833
1834
1835
1836
1837 @Test
1838 public void onbeforeunloadHandler_cancel() throws Exception {
1839 testOnbeforeunloadHandler(false, "first");
1840 }
1841
1842
1843
1844
1845
1846
1847 private void testOnbeforeunloadHandler(final boolean handlerOk, final String expectedPageTitle) throws Exception {
1848 final WebClient webClient = getWebClient();
1849 final MockWebConnection webConnection = new MockWebConnection();
1850 final List<String> collectedConfirms = new ArrayList<>();
1851
1852 webClient.setOnbeforeunloadHandler(new OnbeforeunloadHandler() {
1853 @Override
1854 public boolean handleEvent(final Page page, final String message) {
1855 collectedConfirms.add(message);
1856 return handlerOk;
1857 }
1858 });
1859
1860 final String expectedMessage = "Any string value here forces a dialog box to appear before closing the window.";
1861 final String firstContent = DOCTYPE_HTML
1862 + "<html><head><title>first</title>\n"
1863 + "<script>\n"
1864 + " function closeIt(event) {\n"
1865 + " event.returnValue = '" + expectedMessage + "';\n"
1866 + " }\n"
1867 + "</script>\n"
1868 + "</head><body onbeforeunload='closeIt(event)'>\n"
1869 + " <a href='" + URL_SECOND + "'>Second page</a>\n"
1870 + "</body></html>";
1871
1872 final String secondContent = DOCTYPE_HTML
1873 + "<html><head><title>second</title>\n"
1874 + "</head><body>\n"
1875 + "</body></html>";
1876
1877 webConnection.setResponse(URL_FIRST, firstContent);
1878 webConnection.setResponse(URL_SECOND, secondContent);
1879 webClient.setWebConnection(webConnection);
1880
1881 final HtmlPage page = webClient.getPage(URL_FIRST);
1882 final HtmlAnchor anchor = page.getAnchors().get(0);
1883 final HtmlPage secondPage = anchor.click();
1884
1885 assertEquals(new String[] {expectedMessage}, collectedConfirms);
1886 assertEquals(expectedPageTitle, secondPage.getTitleText());
1887 }
1888
1889
1890
1891
1892 @Test
1893 public void srcJavaScript() throws Exception {
1894 final String htmlContent = DOCTYPE_HTML
1895 + "<html><head><title>foo</title></head><body>\n"
1896 + "<script id='ie_ready' src='javascript:void(0)'></script>\n"
1897 + "</body></html>";
1898
1899 loadPage(htmlContent);
1900 }
1901
1902
1903
1904
1905
1906
1907 @Test
1908 public void asNormalizedText() throws Exception {
1909 final String htmlContent = DOCTYPE_HTML
1910 + "<html><head><title>test</title></head>\n"
1911 + "<body><table>\n"
1912 + "<tr><form><td>a</td></form></tr>\n"
1913 + "</table></body></html>";
1914
1915 final HtmlPage page = loadPage(htmlContent);
1916 assertEquals("test\na", page.asNormalizedText());
1917 }
1918
1919
1920
1921
1922 @Test
1923 public void getElementsByTagName() throws Exception {
1924 final String firstContent = DOCTYPE_HTML
1925 + "<html><head><title>First</title></head>\n"
1926 + "<body>\n"
1927 + "<form><input type='button' name='button1' value='pushme'></form>\n"
1928 + "<div>a</div> <div>b</div> <div>c</div>\n"
1929 + "</body></html>";
1930
1931 final HtmlPage page = loadPage(firstContent);
1932
1933 NodeList inputs = page.getElementsByTagName("input");
1934 assertEquals(1, inputs.getLength());
1935 assertEquals("button", inputs.item(0).getAttributes().getNamedItem("type").getNodeValue());
1936
1937 final NodeList divs = page.getElementsByTagName("div");
1938 assertEquals(3, divs.getLength());
1939
1940 final HtmlDivision newDiv = new HtmlDivision(HtmlDivision.TAG_NAME, page, null);
1941 page.getBody().appendChild(newDiv);
1942 assertEquals(4, divs.getLength());
1943
1944
1945 inputs = page.getElementsByTagName("inPUT");
1946 assertEquals(1, inputs.getLength());
1947
1948
1949 inputs = page.getElementsByTagName("");
1950 assertEquals(0, inputs.getLength());
1951
1952
1953 inputs = page.getElementsByTagName(null);
1954 assertEquals(0, inputs.getLength());
1955 }
1956
1957
1958
1959
1960
1961
1962 @Test
1963 public void readyState() throws Exception {
1964 final String htmlContent = DOCTYPE_HTML
1965 + "<html><head><title>test</title></head>\n"
1966 + "<body><table>\n"
1967 + "<tr><form><td>a</td></form></tr>\n"
1968 + "</table></body></html>";
1969
1970 final HtmlPage page = loadPage(htmlContent);
1971 assertEquals(DomNode.READY_STATE_COMPLETE, page.getReadyState());
1972 }
1973
1974
1975
1976
1977 @Test
1978 public void cloneNode() throws Exception {
1979 final String html = DOCTYPE_HTML
1980 + "<html>\n"
1981 + "<head><title>foo</title></head>\n"
1982 + "<body>\n"
1983 + "<p>hello world</p>\n"
1984 + "</body></html>";
1985 final HtmlPage page = loadPage(html);
1986 page.getByXPath("//p");
1987 final HtmlPage clonedPage = page.cloneNode(true);
1988 clonedPage.getByXPath("//p");
1989 }
1990
1991
1992
1993
1994 @Test
1995 public void cloneHtmlPageWithFrame() throws Exception {
1996 final String html = DOCTYPE_HTML
1997 + "<html>\n"
1998 + "<head></head><body>\n"
1999 + "<div id='content'>"
2000 + " <iframe name='content' src='frame1.html'></iframe>"
2001 + "</div>"
2002 + "</body></html>";
2003
2004 final String frameContent = DOCTYPE_HTML
2005 + "<html>\n"
2006 + "<head></head>\n"
2007 + "<body>"
2008 + " <p>frame1</p>"
2009 + "</body></html>";
2010
2011 final MockWebConnection webConnection = getMockWebConnection();
2012 webConnection.setResponse(new URL("http://example/index.html"), html);
2013 webConnection.setResponse(new URL("http://example/frame1.html"), frameContent);
2014
2015 final WebClient webClient = getWebClientWithMockWebConnection();
2016
2017 final HtmlPage page = webClient.getPage("http://example/index.html");
2018
2019
2020 final List<FrameWindow> frames = page.getFrames();
2021 assertEquals(1, frames.size());
2022 assertEquals("frame1", ((HtmlPage) frames.get(0).getEnclosedPage()).asNormalizedText());
2023
2024
2025 HtmlPage clonedPage = page.cloneNode(false);
2026
2027 assertEquals(1, page.getFrames().size());
2028 assertEquals(1, clonedPage.getFrames().size());
2029
2030
2031 clonedPage = page.cloneNode(true);
2032
2033
2034 assertEquals(1, page.getFrames().size());
2035 assertEquals(1, clonedPage.getFrames().size());
2036
2037
2038 page.executeJavaScript("document.cloneNode(true)");
2039
2040
2041 assertEquals(1, page.getFrames().size());
2042 assertEquals(1, clonedPage.getFrames().size());
2043 }
2044
2045
2046
2047
2048 @Test
2049 public void addAutoCloseable() throws Exception {
2050 final String html = "";
2051 final HtmlPage page = loadPage(html);
2052 page.addAutoCloseable(new AutoCloseable() {
2053 @Override
2054 public void close() throws Exception {
2055 page.addAutoCloseable(new AutoCloseable() {
2056 @Override
2057 public void close() throws Exception {
2058 throw new NullPointerException("close failed");
2059 }
2060 });
2061 }
2062 });
2063 page.cleanUp();
2064 }
2065
2066
2067
2068
2069 @Test
2070 public void addAutoCloseableNull() throws Exception {
2071 final String html = "";
2072 final HtmlPage page = loadPage(html);
2073 page.addAutoCloseable(null);
2074 page.cleanUp();
2075 }
2076
2077
2078
2079
2080 @Test
2081 public void getBaseUrl() throws Exception {
2082 final String html = DOCTYPE_HTML
2083 + "<html>\n"
2084 + "<head></head>\n"
2085 + "<body>body</body>\n"
2086 + "</html>";
2087
2088 HtmlPage page = loadPage(getBrowserVersion(), html, null, URL_FIRST);
2089 assertEquals(URL_FIRST.toExternalForm(), page.getBaseURL().toExternalForm());
2090
2091
2092 String path = "details/abc";
2093 page = loadPage(getBrowserVersion(), html, null, new URL(URL_FIRST.toString() + path));
2094 assertEquals(URL_FIRST.toExternalForm() + path, page.getBaseURL().toExternalForm());
2095
2096 path = "details/abc?x=y&z=z";
2097 page = loadPage(getBrowserVersion(), html, null, new URL(URL_FIRST.toString() + path));
2098 assertEquals(URL_FIRST.toExternalForm() + path, page.getBaseURL().toExternalForm());
2099
2100 path = "details/abc;jsessionid=42?x=y&z=z";
2101 page = loadPage(getBrowserVersion(), html, null, new URL(URL_FIRST.toString() + path));
2102 assertEquals(URL_FIRST.toExternalForm() + path, page.getBaseURL().toExternalForm());
2103 }
2104 }