View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.html;
16  
17  import static org.apache.commons.lang3.StringUtils.right;
18  
19  import java.awt.image.BufferedImage;
20  import java.io.InputStream;
21  import java.net.URL;
22  import java.util.ArrayList;
23  import java.util.Collections;
24  import java.util.LinkedList;
25  import java.util.List;
26  
27  import javax.imageio.ImageIO;
28  import javax.imageio.stream.ImageInputStream;
29  
30  import org.htmlunit.CollectingAlertHandler;
31  import org.htmlunit.HttpHeader;
32  import org.htmlunit.HttpMethod;
33  import org.htmlunit.MockWebConnection;
34  import org.htmlunit.Page;
35  import org.htmlunit.SimpleWebTestCase;
36  import org.htmlunit.TopLevelWindow;
37  import org.htmlunit.UnexpectedPage;
38  import org.htmlunit.WebClient;
39  import org.htmlunit.WebResponse;
40  import org.htmlunit.WebWindow;
41  import org.htmlunit.attachment.AttachmentHandler;
42  import org.htmlunit.junit.BrowserRunner;
43  import org.htmlunit.junit.annotation.Alerts;
44  import org.htmlunit.util.MimeType;
45  import org.junit.Test;
46  import org.junit.runner.RunWith;
47  
48  /**
49   * Tests for {@link HtmlAnchor}.
50   *
51   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
52   * @author Marc Guillemot
53   * @author Stefan Anzinger
54   * @author Ahmed Ashour
55   * @author Ronald Brill
56   * @author Lai Quang Duong
57   */
58  @RunWith(BrowserRunner.class)
59  public class HtmlAnchor2Test extends SimpleWebTestCase {
60  
61      /**
62       * @throws Exception if the test fails
63       */
64      @Test
65      public void click_onClickHandler() throws Exception {
66          final String firstContent = DOCTYPE_HTML
67              + "<html><head><title>First</title></head><body>\n"
68              + "<a href='http://www.foo1.com' id='a1'>link to foo1</a>\n"
69              + "<a href='" + URL_SECOND + "' id='a2' "
70              + "onClick='alert(\"clicked\")'>link to foo2</a>\n"
71              + "<a href='http://www.foo3.com' id='a3'>link to foo3</a>\n"
72              + "</body></html>";
73          final String secondContent = DOCTYPE_HTML
74              + "<html><head><title>Second</title></head><body></body></html>";
75  
76          final WebClient client = getWebClient();
77          final List<String> collectedAlerts = new ArrayList<>();
78          client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
79  
80          final MockWebConnection webConnection = new MockWebConnection();
81          webConnection.setResponse(URL_FIRST, firstContent);
82          webConnection.setResponse(URL_SECOND, secondContent);
83          client.setWebConnection(webConnection);
84  
85          final HtmlPage page = client.getPage(URL_FIRST);
86          final HtmlAnchor anchor = page.getHtmlElementById("a2");
87  
88          assertEquals(Collections.EMPTY_LIST, collectedAlerts);
89  
90          final HtmlPage secondPage = anchor.click();
91  
92          assertEquals(new String[] {"clicked"}, collectedAlerts);
93          assertEquals("Second", secondPage.getTitleText());
94      }
95  
96      /**
97       * @throws Exception if the test fails
98       */
99      @Test
100     public void click_onClickHandler_returnFalse() throws Exception {
101         final String firstContent = DOCTYPE_HTML
102             + "<html><head><title>First</title></head><body>\n"
103             + "<a href='http://www.foo1.com' id='a1'>link to foo1</a>\n"
104             + "<a href='" + URL_SECOND + "' id='a2' "
105             + "onClick='alert(\"clicked\");return false;'>link to foo2</a>\n"
106             + "<a href='http://www.foo3.com' id='a3'>link to foo3</a>\n"
107             + "</body></html>";
108         final String secondContent = DOCTYPE_HTML + "<html><head><title>Second</title></head><body></body></html>";
109 
110         final WebClient client = getWebClient();
111         final List<String> collectedAlerts = new ArrayList<>();
112         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
113 
114         final MockWebConnection webConnection = new MockWebConnection();
115         webConnection.setResponse(URL_FIRST, firstContent);
116         webConnection.setResponse(URL_SECOND, secondContent);
117         client.setWebConnection(webConnection);
118 
119         final HtmlPage page = client.getPage(URL_FIRST);
120         final HtmlAnchor anchor = page.getHtmlElementById("a2");
121 
122         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
123 
124         final HtmlPage secondPage = anchor.click();
125 
126         assertEquals(new String[] {"clicked"}, collectedAlerts);
127         assertSame(page, secondPage);
128     }
129 
130     /**
131      * @throws Exception if the test fails
132      */
133     @Test
134     public void click_onClickHandler_javascriptDisabled() throws Exception {
135         final String htmlContent = DOCTYPE_HTML
136             + "<html><head><title>foo</title></head><body>\n"
137             + "<a href='http://www.foo1.com' id='a1'>link to foo1</a>\n"
138             + "<a href='http://www.foo2.com' id='a2' "
139             + "onClick='alert(\"clicked\")'>link to foo2</a>\n"
140             + "<a href='http://www.foo3.com' id='a3'>link to foo3</a>\n"
141             + "</body></html>";
142         final WebClient client = getWebClient();
143         client.getOptions().setJavaScriptEnabled(false);
144 
145         final List<String> collectedAlerts = new ArrayList<>();
146         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
147 
148         final MockWebConnection webConnection = new MockWebConnection();
149         webConnection.setDefaultResponse(htmlContent);
150         client.setWebConnection(webConnection);
151 
152         final HtmlPage page = client.getPage(URL_FIRST);
153         final HtmlAnchor anchor = page.getHtmlElementById("a2");
154 
155         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
156 
157         final HtmlPage secondPage = anchor.click();
158 
159         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
160         final List<?> expectedParameters = Collections.EMPTY_LIST;
161 
162         assertEquals("url", "http://www.foo2.com/", secondPage.getUrl());
163         assertSame("method", HttpMethod.GET, webConnection.getLastMethod());
164         assertEquals("parameters", expectedParameters, webConnection.getLastParameters());
165     }
166 
167     /**
168      * @throws Exception if the test fails
169      */
170     @Test
171     public void click_javascriptUrl() throws Exception {
172         final String htmlContent = DOCTYPE_HTML
173             + "<html><head><title>foo</title></head><body>\n"
174             + "<a href='http://www.foo1.com' id='a1'>link to foo1</a>\n"
175             + "<a href='javascript:alert(\"clicked\")' id='a2'>link to foo2</a>\n"
176             + "<a href='http://www.foo3.com' id='a3'>link to foo3</a>\n"
177             + "</body></html>";
178         final List<String> collectedAlerts = new ArrayList<>();
179         final HtmlPage page = loadPage(htmlContent, collectedAlerts);
180 
181         final HtmlAnchor anchor = page.getHtmlElementById("a2");
182 
183         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
184 
185         final HtmlPage secondPage = anchor.click();
186 
187         assertEquals(new String[] {"clicked"}, collectedAlerts);
188         assertSame(page, secondPage);
189     }
190 
191     /**
192      * @throws Exception if the test fails
193      */
194     @Test
195     public void click_javascriptUrlMixedCase() throws Exception {
196         final String htmlContent = DOCTYPE_HTML
197             + "<html><head><title>foo</title></head><body>\n"
198             + "<a href='JAVAscrIpt:alert(\"clicked\")' id='a2'>link to foo2</a>\n"
199             + "</body></html>";
200         final List<String> collectedAlerts = new ArrayList<>();
201         final HtmlPage page = loadPage(htmlContent, collectedAlerts);
202 
203         final HtmlAnchor anchor = page.getHtmlElementById("a2");
204 
205         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
206 
207         final HtmlPage secondPage = anchor.click();
208 
209         assertEquals(new String[] {"clicked"}, collectedAlerts);
210         assertSame(page, secondPage);
211     }
212 
213     /**
214      * @throws Exception if the test fails
215      */
216     @Test
217     public void click_javascriptUrlLeadingWhitespace() throws Exception {
218         final String htmlContent = DOCTYPE_HTML
219             + "<html><head><title>foo</title></head><body>\n"
220             + "<a href='  javascript:alert(\"clicked\")' id='a2'>link to foo2</a>\n"
221             + "</body></html>";
222         final List<String> collectedAlerts = new ArrayList<>();
223         final HtmlPage page = loadPage(htmlContent, collectedAlerts);
224 
225         final HtmlAnchor anchor = page.getHtmlElementById("a2");
226 
227         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
228 
229         final HtmlPage secondPage = anchor.click();
230 
231         assertEquals(new String[] {"clicked"}, collectedAlerts);
232         assertSame(page, secondPage);
233     }
234 
235     /**
236      * @throws Exception if the test fails
237      */
238     @Test
239     public void click_javascriptUrl_javascriptDisabled() throws Exception {
240         final String htmlContent = DOCTYPE_HTML
241             + "<html><head><title>foo</title></head><body>\n"
242             + "<a href='http://www.foo1.com' id='a1'>link to foo1</a>\n"
243             + "<a href='javascript:alert(\"clicked\")' id='a2'>link to foo2</a>\n"
244             + "<a href='http://www.foo3.com' id='a3'>link to foo3</a>\n"
245             + "</body></html>";
246         final WebClient client = getWebClient();
247         client.getOptions().setJavaScriptEnabled(false);
248 
249         final List<String> collectedAlerts = new ArrayList<>();
250         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
251 
252         final MockWebConnection webConnection = new MockWebConnection();
253         webConnection.setDefaultResponse(htmlContent);
254         client.setWebConnection(webConnection);
255 
256         final HtmlPage page = client.getPage(URL_FIRST);
257         final HtmlAnchor anchor = page.getHtmlElementById("a2");
258 
259         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
260 
261         final HtmlPage secondPage = anchor.click();
262 
263         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
264         assertSame(page, secondPage);
265     }
266 
267     /**
268      * @throws Exception if the test fails
269      */
270     @Test
271     public void click_javascriptUrl_InvalidReturn_RegressionTest() throws Exception {
272         final String htmlContent = DOCTYPE_HTML
273             + "<html><head><SCRIPT lang=\"JavaScript\">\n"
274             + "function doSubmit(formName) {\n"
275             + "  return false;\n"
276             + "}\n"
277             + "</SCRIPT></head><body>\n"
278             + "<form name='formName' method='POST' action='../foo'>\n"
279             + "<a href='.' id='testJavascript' name='testJavascript'"
280             + "onclick='return false'>Test Link </a>\n"
281             + "<input type='submit' value='Login' name='loginButton'>\n"
282             + "</form></body></html>";
283 
284         final HtmlPage page = loadPage(htmlContent);
285         final HtmlAnchor testAnchor = page.getAnchorByName("testJavascript");
286         testAnchor.click();  // blows up here
287     }
288 
289     /**
290      * @throws Exception if the test fails
291      */
292     @Test
293     public void click_javascriptUrl_targetPageWithIframe() throws Exception {
294         final String firstContent = DOCTYPE_HTML
295             + " <html>\n"
296             + "<head><title>Page A</title></head>\n"
297             + "<body><a href='#' onclick=\"document.location.href='" + URL_SECOND + "'\" id='link'>link</a></body>\n"
298             + "</html>";
299         final String secondContent = DOCTYPE_HTML
300             + "<html>\n"
301             + "<head><title>Page B</title></head>\n"
302             + "<body><iframe src='" + URL_THIRD + "'></iframe></body>\n"
303             + "</html>";
304         final String thirdContent = DOCTYPE_HTML
305             + "<html>\n"
306             + "<head><title>Page C</title></head>\n"
307             + "<body>test</body>\n"
308             + "</html>";
309 
310         final WebClient client = getWebClient();
311         final MockWebConnection conn = new MockWebConnection();
312         conn.setResponse(URL_FIRST, firstContent);
313         conn.setResponse(URL_SECOND, secondContent);
314         conn.setResponse(URL_THIRD, thirdContent);
315         client.setWebConnection(conn);
316         final HtmlPage firstPage = client.getPage(URL_FIRST);
317         final HtmlAnchor a = firstPage.getHtmlElementById("link");
318         final HtmlPage secondPage = a.click();
319         assertEquals("url", URL_SECOND, secondPage.getUrl());
320         assertEquals("title", "Page B", secondPage.getTitleText());
321     }
322 
323     /**
324      * Regression test for bug #894.
325      * @throws Exception if the test fails
326      */
327     @Test
328     public void click_javascriptUrl_encoded() throws Exception {
329         final String htmlContent = DOCTYPE_HTML
330             + "<html><body><script>function hello() { alert('hello') }</script>\n"
331             + "<a href='javascript:%20hello%28%29' id='a1'>a1</a>\n"
332             + "<a href='javascript: hello%28%29' id='a2'>a2</a>\n"
333             + "<a href='javascript:hello%28%29' id='a3'>a3</a>\n"
334             + "</body></html>";
335 
336         final List<String> collectedAlerts = new ArrayList<>();
337         final HtmlPage page = loadPage(htmlContent, collectedAlerts);
338         assertEquals(Collections.EMPTY_LIST, collectedAlerts);
339 
340         page.getHtmlElementById("a1").click();
341         page.getHtmlElementById("a2").click();
342         page.getHtmlElementById("a3").click();
343         assertEquals(new String[] {"hello", "hello", "hello"}, collectedAlerts);
344     }
345 
346     /**
347      * Test for new openLinkInNewWindow() method.
348      * @throws Exception on test failure
349      */
350     @Test
351     public void openLinkInNewWindow() throws Exception {
352         final String htmlContent = DOCTYPE_HTML
353             + "<html><head><title>foo</title></head><body>\n"
354             + "<a href='http://www.foo1.com' id='a1'>link to foo1</a>\n"
355             + "</body></html>";
356 
357         final HtmlPage page = loadPage(htmlContent);
358         final HtmlAnchor anchor = page.getHtmlElementById("a1");
359 
360         assertEquals("size incorrect before test", 1, page.getWebClient().getWebWindows().size());
361 
362         final HtmlPage secondPage = (HtmlPage) anchor.openLinkInNewWindow();
363 
364         assertNotSame("new page not returned", page, secondPage);
365         assertTrue("new page in wrong window type",
366                 TopLevelWindow.class.isInstance(secondPage.getEnclosingWindow()));
367         assertEquals("new window not created", 2, page.getWebClient().getWebWindows().size());
368         assertNotSame("new window not used", page.getEnclosingWindow(), secondPage
369                 .getEnclosingWindow());
370     }
371 
372     /**
373      * Links with an href and a non-false returning onclick that opens a new window should still
374      * open the href in the first window.
375      *
376      * http://sourceforge.net/p/htmlunit/bugs/394/
377      *
378      * @throws Exception on test failure
379      */
380     @Test
381     public void correctLinkTargetWhenOnclickOpensWindow() throws Exception {
382         final String firstContent = DOCTYPE_HTML
383             + "<html><head><title>First</title></head><body>\n"
384             + "<a href='page2.html' id='clickme' onclick=\"window.open('popup.html', 'newWindow');\">X</a>\n"
385             + "</body></html>";
386         final String html2 = DOCTYPE_HTML + "<html><head><title>Second</title></head><body></body></html>";
387         final String htmlPopup = DOCTYPE_HTML + "<html><head><title>Popup</title></head><body></body></html>";
388 
389         final WebClient client = getWebClient();
390         final List<String> collectedAlerts = new ArrayList<>();
391         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
392 
393         final MockWebConnection webConnection = new MockWebConnection();
394         webConnection.setResponse(URL_FIRST, firstContent);
395         webConnection.setResponse(new URL(URL_FIRST, "page2.html"), html2);
396         webConnection.setResponse(new URL(URL_FIRST, "popup.html"), htmlPopup);
397         client.setWebConnection(webConnection);
398 
399         final HtmlPage firstPage = client.getPage(URL_FIRST);
400         final HtmlAnchor anchor = firstPage.getHtmlElementById("clickme");
401         final HtmlPage pageAfterClick = anchor.click();
402 
403         assertEquals("Second window did not open", 2, client.getWebWindows().size());
404         assertNotSame("New Page was not returned", firstPage, pageAfterClick);
405         assertEquals("Wrong new Page returned", "Popup", pageAfterClick.getTitleText());
406         assertEquals("Original window not updated", "Second",
407             ((HtmlPage) firstPage.getEnclosingWindow().getEnclosedPage()).getTitleText());
408     }
409 
410     /**
411      * @throws Exception if an error occurs
412      */
413     @Test
414     public void preventDefault1() throws Exception {
415         final String html = DOCTYPE_HTML
416             + "<html><head><script>\n"
417             + "  function handler(e) {\n"
418             + "    if (e)\n"
419             + "      e.preventDefault();\n"
420             + "    else\n"
421             + "      return false;\n"
422             + "  }\n"
423             + "  function init() {\n"
424             + "    document.getElementById('a1').onclick = handler;\n"
425             + "  }\n"
426             + "</script></head>\n"
427             + "<body onload='init()'>\n"
428             + "<a href='" + URL_SECOND + "' id='a1'>Test</a>\n"
429             + "</body></html>";
430 
431         final HtmlPage page = loadPage(html);
432         final HtmlAnchor a1 = page.getHtmlElementById("a1");
433         final HtmlPage secondPage = a1.click();
434         assertEquals(URL_FIRST, secondPage.getUrl());
435     }
436 
437     /**
438      * @throws Exception if an error occurs
439      */
440     @Test
441     public void preventDefault2() throws Exception {
442         final String html = DOCTYPE_HTML
443             + "<html><head><script>\n"
444             + "  function handler(e) {\n"
445             + "    if (e.preventDefault)\n"
446             + "      e.preventDefault();\n"
447             + "    else\n"
448             + "      e.returnValue = false;\n"
449             + "  }\n"
450             + "</script></head>\n"
451             + "<body>\n"
452             + "<a href='" + URL_SECOND + "' id='a1' onclick='handler(event)'>Test</a>\n"
453             + "</body></html>";
454 
455         final HtmlPage page = loadPage(html);
456         final HtmlAnchor a1 = page.getHtmlElementById("a1");
457         final HtmlPage secondPage = a1.click();
458         assertEquals(URL_FIRST, secondPage.getUrl());
459     }
460 
461     /**
462      * @throws Exception if an error occurs
463      */
464     @Test
465     public void preventDefault3() throws Exception {
466         final String html = DOCTYPE_HTML
467             + "<html><body>\n"
468             + "<a href='" + URL_SECOND + "' id='a1' onclick='return false'>Test</a>\n"
469             + "</body></html>";
470 
471         final HtmlPage page = loadPage(html);
472         final HtmlAnchor a1 = page.getHtmlElementById("a1");
473         final HtmlPage secondPage = a1.click();
474         assertEquals(URL_FIRST, secondPage.getUrl());
475     }
476 
477     /**
478      * Test for bug #826.
479      * @throws Exception if an error occurs
480      */
481     @Test
482     public void hashAnchor() throws Exception {
483         final String html = DOCTYPE_HTML
484                 + "<html><body>\n"
485                 + "<a id='a' href='#a'>a</a>\n"
486                 + "<a id='a_target' href='#target' target='_blank'>target</a>\n"
487                 + "</body></html>";
488         HtmlPage page = loadPage(html);
489         HtmlPage targetPage = page.getHtmlElementById("a").click();
490         assertEquals(new URL(URL_FIRST, "#a"), page.getUrl());
491         assertEquals(page.getEnclosingWindow(), targetPage.getEnclosingWindow());
492 
493         page = loadPage(html);
494         targetPage = page.getHtmlElementById("a_target").click();
495         assertEquals(new URL(URL_FIRST, "#target"), targetPage.getUrl());
496         assertFalse(page.getEnclosingWindow().equals(targetPage.getEnclosingWindow()));
497     }
498 
499     /**
500      * @throws Exception if an error occurs
501      */
502     @Test
503     public void targetWithRelativeUrl() throws Exception {
504         final WebClient client = getWebClient();
505 
506         final URL url = getClass().getResource("HtmlAnchorTest_targetWithRelativeUrl_a.html");
507         assertNotNull(url);
508 
509         final HtmlPage page = client.getPage(url);
510         final WebWindow a = page.getEnclosingWindow();
511         final WebWindow b = page.getFrameByName("b");
512         final WebWindow c = page.getFrameByName("c");
513 
514         assertEquals("a.html", right(getUrl(a), 6));
515         assertEquals("b.html", right(getUrl(b), 6));
516         assertEquals("c.html", right(getUrl(c), 6));
517 
518         ((HtmlPage) c.getEnclosedPage()).getAnchorByHref("#foo").click();
519 
520         assertEquals("a.html", right(getUrl(a), 6));
521         assertEquals("c.html#foo", right(getUrl(b), 10));
522         assertEquals("c.html", right(getUrl(c), 6));
523     }
524 
525     /**
526      * Returns the URL of the page loaded in the specified window.
527      * @param w the window
528      * @return the URL of the page loaded in the specified window
529      */
530     private static String getUrl(final WebWindow w) {
531         return w.getEnclosedPage().getUrl().toString();
532     }
533 
534     /**
535      * @throws Exception if an error occurs
536      */
537     @Test
538     public void clickNestedElement_jsDisabled() throws Exception {
539         final String html = DOCTYPE_HTML
540             + "<html>\n"
541             + "<body>\n"
542             + "<a href='page2.html'>\n"
543             + "<span id='theSpan'>My Link</span></a>\n"
544             + "</body></html>";
545 
546         getMockWebConnection().setDefaultResponse("");
547         getWebClient().getOptions().setJavaScriptEnabled(false);
548         final HtmlPage page = loadPage(html);
549         final HtmlElement span = page.getHtmlElementById("theSpan");
550         assertEquals("span", span.getTagName());
551         final HtmlPage page2 = span.click();
552         assertEquals(new URL(URL_FIRST, "page2.html"), page2.getUrl());
553     }
554 
555     /**
556      * @throws Exception if the test fails
557      */
558     @Test
559     public void asXml_emptyTag() throws Exception {
560         final String html = DOCTYPE_HTML
561             + "<html><body>\n"
562             + "<a name='foo'></a>\n"
563             + "</body></html>";
564 
565         final HtmlPage page = loadPage(html);
566         final HtmlAnchor htmlAnchor = page.getAnchorByName("foo");
567         assertTrue(htmlAnchor.asXml().contains("</a>"));
568     }
569 
570     /**
571      * @throws Exception if the test fails
572      */
573     @Test
574     public void clickShift() throws Exception {
575         final String first = DOCTYPE_HTML
576             + "<html><head><title>First</title></head><body>\n"
577             + "  <a href='" + URL_SECOND + "' id='a2'>link to foo2</a>\n"
578             + "</body></html>";
579         final String second = DOCTYPE_HTML
580             + "<html><head><title>Second</title></head><body></body></html>";
581 
582         final WebClient client = getWebClient();
583         final List<String> collectedAlerts = new ArrayList<>();
584         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
585 
586         final MockWebConnection webConnection = new MockWebConnection();
587         webConnection.setResponse(URL_FIRST, first);
588         webConnection.setResponse(URL_SECOND, second);
589         client.setWebConnection(webConnection);
590 
591         assertEquals(1, getWebClient().getTopLevelWindows().size());
592         final HtmlPage page = client.getPage(URL_FIRST);
593         final HtmlAnchor anchor = page.getHtmlElementById("a2");
594 
595         final HtmlPage secondPage = anchor.click(true, false, false);
596         assertEquals(2, getWebClient().getTopLevelWindows().size());
597         assertEquals("Second", secondPage.getTitleText());
598     }
599 
600     /**
601      * @throws Exception if the test fails
602      */
603     @Test
604     public void clickCtrl() throws Exception {
605         final String first = DOCTYPE_HTML
606             + "<html><head><title>First</title></head><body>\n"
607             + "  <a href='" + URL_SECOND + "' id='a2'>link to foo2</a>\n"
608             + "</body></html>";
609         final String second = DOCTYPE_HTML
610             + "<html><head><title>Second</title></head><body></body></html>";
611 
612         final WebClient client = getWebClient();
613         final List<String> collectedAlerts = new ArrayList<>();
614         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
615 
616         final MockWebConnection webConnection = new MockWebConnection();
617         webConnection.setResponse(URL_FIRST, first);
618         webConnection.setResponse(URL_SECOND, second);
619         client.setWebConnection(webConnection);
620 
621         assertEquals(1, getWebClient().getTopLevelWindows().size());
622         final HtmlPage page = client.getPage(URL_FIRST);
623         final HtmlAnchor anchor = page.getHtmlElementById("a2");
624 
625         final HtmlPage secondPage = anchor.click(false, true, false);
626         assertEquals(2, getWebClient().getTopLevelWindows().size());
627         assertEquals("First", secondPage.getTitleText());
628     }
629 
630     /**
631      * @throws Exception if the test fails
632      */
633     @Test
634     public void clickCtrlShift() throws Exception {
635         final String first = DOCTYPE_HTML
636             + "<html><head><title>First</title></head><body>\n"
637             + "  <a href='" + URL_SECOND + "' id='a2'>link to foo2</a>\n"
638             + "</body></html>";
639         final String second = DOCTYPE_HTML
640             + "<html><head><title>Second</title></head><body></body></html>";
641 
642         final WebClient client = getWebClient();
643         final List<String> collectedAlerts = new ArrayList<>();
644         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
645 
646         final MockWebConnection webConnection = new MockWebConnection();
647         webConnection.setResponse(URL_FIRST, first);
648         webConnection.setResponse(URL_SECOND, second);
649         client.setWebConnection(webConnection);
650 
651         assertEquals(1, getWebClient().getTopLevelWindows().size());
652         final HtmlPage page = client.getPage(URL_FIRST);
653         final HtmlAnchor anchor = page.getHtmlElementById("a2");
654 
655         final HtmlPage secondPage = anchor.click(true, true, false);
656         assertEquals(2, getWebClient().getTopLevelWindows().size());
657         assertEquals("First", secondPage.getTitleText());
658     }
659 
660     /**
661      * @throws Exception if the test fails
662      */
663     @Test
664     public void clickShiftJavascript() throws Exception {
665         final String first = DOCTYPE_HTML
666             + "<html><head><title>First</title></head><body>\n"
667             + "  <a href='javascript: window.location=\"" + URL_SECOND + "\"' id='a2'>link to foo2</a>\n"
668             + "</body></html>";
669         final String second = DOCTYPE_HTML
670             + "<html><head><title>Second</title></head><body></body></html>";
671 
672         final WebClient client = getWebClient();
673         final List<String> collectedAlerts = new ArrayList<>();
674         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
675 
676         final MockWebConnection webConnection = new MockWebConnection();
677         webConnection.setResponse(URL_FIRST, first);
678         webConnection.setResponse(URL_SECOND, second);
679         client.setWebConnection(webConnection);
680 
681         assertEquals(1, getWebClient().getTopLevelWindows().size());
682         final HtmlPage page = client.getPage(URL_FIRST);
683         final HtmlAnchor anchor = page.getHtmlElementById("a2");
684 
685         final HtmlPage secondPage = anchor.click(true, false, false);
686         assertEquals(2, getWebClient().getTopLevelWindows().size());
687         assertEquals("Second", secondPage.getTitleText());
688     }
689 
690     /**
691      * @throws Exception if the test fails
692      */
693     @Test
694     public void clickCtrlJavascript() throws Exception {
695         final String first = DOCTYPE_HTML
696             + "<html><head><title>First</title></head><body>\n"
697             + "  <a href='javascript: window.location=\"" + URL_SECOND + "\"' id='a2'>link to foo2</a>\n"
698             + "</body></html>";
699         final String second = DOCTYPE_HTML
700             + "<html><head><title>Second</title></head><body></body></html>";
701 
702         final WebClient client = getWebClient();
703         final List<String> collectedAlerts = new ArrayList<>();
704         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
705 
706         final MockWebConnection webConnection = new MockWebConnection();
707         webConnection.setResponse(URL_FIRST, first);
708         webConnection.setResponse(URL_SECOND, second);
709         client.setWebConnection(webConnection);
710 
711         assertEquals(1, getWebClient().getTopLevelWindows().size());
712         final HtmlPage page = client.getPage(URL_FIRST);
713         final HtmlAnchor anchor = page.getHtmlElementById("a2");
714 
715         final HtmlPage secondPage = anchor.click(false, true, false);
716         assertEquals(2, getWebClient().getTopLevelWindows().size());
717         assertEquals("First", secondPage.getTitleText());
718     }
719 
720     /**
721      * @throws Exception if the test fails
722      */
723     @Test
724     public void clickShiftCtrlJavascript() throws Exception {
725         final String first = DOCTYPE_HTML
726             + "<html><head><title>First</title></head><body>\n"
727             + "  <a href='javascript: window.location=\"" + URL_SECOND + "\"' id='a2'>link to foo2</a>\n"
728             + "</body></html>";
729         final String second = DOCTYPE_HTML
730             + "<html><head><title>Second</title></head><body></body></html>";
731 
732         final WebClient client = getWebClient();
733         final List<String> collectedAlerts = new ArrayList<>();
734         client.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
735 
736         final MockWebConnection webConnection = new MockWebConnection();
737         webConnection.setResponse(URL_FIRST, first);
738         webConnection.setResponse(URL_SECOND, second);
739         client.setWebConnection(webConnection);
740 
741         assertEquals(1, getWebClient().getTopLevelWindows().size());
742         final HtmlPage page = client.getPage(URL_FIRST);
743         final HtmlAnchor anchor = page.getHtmlElementById("a2");
744 
745         final HtmlPage secondPage = anchor.click(true, true, false);
746         assertEquals(2, getWebClient().getTopLevelWindows().size());
747         assertEquals("First", secondPage.getTitleText());
748     }
749 
750     /**
751      * @throws Exception if the test fails
752      */
753     @Test
754     public void asText_getTextContent() throws Exception {
755         final String html = DOCTYPE_HTML
756             + "<html>\n"
757             + "<head></head>\n"
758             + "<body>\n"
759             + "  <a href='localhost' id='a2'>\n"
760             + "    <span>Last Name</span>, <span>First Name</span>\n"
761             + "  </a>\n"
762             + "</body></html>";
763 
764         final HtmlPage page = loadPage(html);
765         final HtmlAnchor anchor = page.getHtmlElementById("a2");
766 
767         assertEquals("Last Name, First Name", anchor.asNormalizedText());
768         assertEquals("\n    Last Name, First Name\n  ", anchor.getTextContent());
769     }
770 
771     /**
772      * Not testable with Selenium.
773      *
774      * @exception Exception If the test fails
775      */
776     @Test
777     @Alerts({"1", "First"})
778     public void clickWithDownloadAttribute() throws Exception {
779         final String html = DOCTYPE_HTML
780                 + "<html>\n"
781                 + "<head>\n"
782                 + "  <title>First</title>\n"
783                 + "</head>\n"
784                 + "<body>\n"
785                 + "  <a id='clickMe' href='" + URL_SECOND + "' download='lora.html'>Click Me</a>\n"
786                 + "</body></html>";
787 
788         getMockWebConnection().setResponse(URL_SECOND, "<head><title>Second</title>");
789         final int windowsSize = getWebClient().getWebWindows().size();
790         final HtmlPage page = loadPage(html);
791 
792         page.getElementById("clickMe").click();
793 
794         assertEquals("Should have opened a new window",
795                 windowsSize + Integer.parseInt(getExpectedAlerts()[0]), getWebClient().getWebWindows().size());
796         assertEquals("Should not have navigated away", getExpectedAlerts()[1], page.getTitleText());
797     }
798 
799     /**
800      * Not testable with Selenium.
801      *
802      * @exception Exception If the test fails
803      */
804     @Test
805     @Alerts({"1", "First"})
806     public void clickWithDownloadAttributeFromJs() throws Exception {
807         final String html = DOCTYPE_HTML
808                 + "<html>\n"
809                 + "<head>\n"
810                 + "  <title>First</title>\n"
811                 + "  <script>\n"
812                 + "    function test(e) {\n"
813                 + "      var a = document.getElementById('clickMe');"
814                 + "      a.setAttribute('download', 'lora.png');"
815                 + "      a.click();"
816                 + "    }\n"
817                 + "  </script>\n"
818                 + "</head>\n"
819                 + "<body onload='test()'>\n"
820                 + "  <a id='clickMe' href='" + URL_SECOND + "' >Click Me</a>\n"
821                 + "</body></html>";
822 
823         getMockWebConnection().setResponse(URL_SECOND, "<head><title>Second</title>");
824 
825         final int windowsSize = getWebClient().getWebWindows().size();
826         final HtmlPage page = loadPage(html);
827 
828         assertEquals("Should have opened a new window",
829                 windowsSize + Integer.parseInt(getExpectedAlerts()[0]), getWebClient().getWebWindows().size());
830         assertEquals("Should not have navigated away", getExpectedAlerts()[1], page.getTitleText());
831     }
832 
833     /**
834      * Not testable with Selenium.
835      *
836      * @exception Exception If the test fails
837      */
838     @Test
839     @Alerts({"1", "First",
840              "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAAL"
841                     + "GPC/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IAAAAddEVYdENvbW1l"
842                     + "bnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1JREFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C"
843                     + "7OwQg2JoQ9LE1exdlYvBBeZ7jqch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI"
844                     + "97CER3N0vr4MkhoXe0rZigAAAABJRU5ErkJggg=="})
845     public void clickWithDownloadAttributeDataUrl() throws Exception {
846         final String html = DOCTYPE_HTML
847                 + "<html>\n"
848                 + "<head>\n"
849                 + "  <title>First</title>\n"
850                 + "</head>\n"
851                 + "<body>\n"
852                 + "  <a id='clickMe' href='data:image/png;base64,"
853                     + "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGP"
854                     + "C/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IA"
855                     + "AAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1J"
856                     + "REFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jq"
857                     + "ch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0"
858                     + "vr4MkhoXe0rZigAAAABJRU5ErkJggg==' download='lora.html'>Click Me</a>\n"
859                 + "</body></html>";
860 
861         getMockWebConnection().setResponse(URL_SECOND, "<head><title>Second</title>");
862         final int windowsSize = getWebClient().getWebWindows().size();
863         final HtmlPage page = loadPage(html);
864 
865         page.getElementById("clickMe").click();
866 
867         assertEquals("Should have opened a new window",
868                 windowsSize + Integer.parseInt(getExpectedAlerts()[0]), getWebClient().getWebWindows().size());
869         assertEquals("Should not have navigated away", getExpectedAlerts()[1], page.getTitleText());
870 
871         final WebWindow dataWindow = getWebClient().getWebWindows().get(getWebClient().getWebWindows().size() - 1);
872         final Page dataPage = dataWindow.getEnclosedPage();
873         assertTrue("Should be an UnexpectedPage", dataPage instanceof UnexpectedPage);
874 
875         try (InputStream resultInputStream = ((UnexpectedPage) dataPage).getInputStream()) {
876             final ImageInputStream resultImageIS = ImageIO.createImageInputStream(resultInputStream);
877             final BufferedImage resultBufferedIIS = ImageIO.read(resultImageIS);
878             compareImages(getExpectedAlerts()[2], null, resultBufferedIIS);
879         }
880     }
881 
882     /**
883      * @throws Exception if the test fails
884      */
885     @Test
886     public void click_unexpectedPage() throws Exception {
887         final String html = DOCTYPE_HTML
888             + "<html><head></head>\n"
889             + "<body>\n"
890             + "  <a href='" + URL_SECOND + "' id='link'>link</a>\n"
891             + "</body>\n"
892             + "</html>";
893 
894         getMockWebConnection().setResponse(URL_SECOND, "{name: \"Test\"};", MimeType.APPLICATION_JSON);
895 
896         final HtmlPage page = loadPage(html);
897         assertEquals(1, getWebClient().getWebWindows().size());
898 
899         page.getElementById("link").click();
900         assertEquals(1, getWebClient().getWebWindows().size());
901         assertTrue(page.getEnclosingWindow().getEnclosedPage() instanceof UnexpectedPage);
902     }
903 
904     /**
905      * @throws Exception if the test fails
906      */
907     @Test
908     public void click_unexpectedPageAttachmentHandlerDoesNotHandleContentType() throws Exception {
909         final String html = DOCTYPE_HTML
910             + "<html><head></head>\n"
911             + "<body>\n"
912             + "  <a href='" + URL_SECOND + "' id='link'>link</a>\n"
913             + "</body>\n"
914             + "</html>";
915 
916         getMockWebConnection().setResponse(URL_SECOND, "{name: \"Test\"};", MimeType.APPLICATION_JSON);
917 
918         final LinkedList<Page> pages = new LinkedList<>();
919         getWebClient().setAttachmentHandler(new AttachmentHandler() {
920 
921             @Override
922             public void handleAttachment(final Page page, final String attachmentFilename) {
923                 pages.add(page);
924             }
925         });
926 
927         try {
928             final HtmlPage page = loadPage(html);
929             assertEquals(1, getWebClient().getWebWindows().size());
930 
931             page.getElementById("link").click();
932 
933             assertEquals(1, getWebClient().getWebWindows().size());
934             assertTrue(getWebClient().getCurrentWindow().getEnclosedPage() instanceof UnexpectedPage);
935 
936             assertEquals(0, pages.size());
937         }
938         finally {
939             getWebClient().setAttachmentHandler(null);
940         }
941     }
942 
943 
944     /**
945      * @throws Exception if the test fails
946      */
947     @Test
948     public void click_unexpectedPageAttachmentHandlerHandleContentType() throws Exception {
949         final String html = DOCTYPE_HTML
950             + "<html><head></head>\n"
951             + "<body>\n"
952             + "  <a href='" + URL_SECOND + "' id='link'>link</a>\n"
953             + "</body>\n"
954             + "</html>";
955 
956         getMockWebConnection().setResponse(URL_SECOND, "{name: \"Test\"};", MimeType.APPLICATION_JSON);
957 
958         final LinkedList<Page> pages = new LinkedList<>();
959         getWebClient().setAttachmentHandler(new AttachmentHandler() {
960 
961             @Override
962             public boolean isAttachment(final WebResponse response) {
963                 return MimeType.APPLICATION_JSON
964                         .equalsIgnoreCase(response.getResponseHeaderValue(HttpHeader.CONTENT_TYPE));
965             }
966 
967             @Override
968             public void handleAttachment(final Page page, final String attachmentFilename) {
969                 pages.add(page);
970             }
971         });
972 
973         try {
974             final HtmlPage page = loadPage(html);
975             assertEquals(1, getWebClient().getWebWindows().size());
976 
977             page.getElementById("link").click();
978 
979             final WebWindow newWindow = getWebClient().getWebWindows().get(getWebClient().getWebWindows().size() - 1);
980             assertTrue(newWindow.getEnclosedPage() instanceof UnexpectedPage);
981 
982             assertEquals(1, pages.size());
983         }
984         finally {
985             getWebClient().setAttachmentHandler(null);
986         }
987     }
988 
989     /**
990      * @throws Exception if the test fails
991      */
992     @Test
993     public void click_unexpectedPageAttachmentHandlerHandleResponseDoesNotHandleContentType() throws Exception {
994         final String html = DOCTYPE_HTML
995             + "<html><head></head>\n"
996             + "<body>\n"
997             + "  <a href='" + URL_SECOND + "' id='link'>link</a>\n"
998             + "</body>\n"
999             + "</html>";
1000 
1001         getMockWebConnection().setResponse(URL_SECOND, "{name: \"Test\"};", MimeType.APPLICATION_JSON);
1002 
1003         final LinkedList<WebResponse> pages = new LinkedList<>();
1004         getWebClient().setAttachmentHandler(new AttachmentHandler() {
1005 
1006             @Override
1007             public boolean handleAttachment(final WebResponse response, final String attachmentFilename) {
1008                 pages.add(response);
1009                 return true;
1010             }
1011 
1012             @Override
1013             public void handleAttachment(final Page page, final String attachmentFilename) {
1014                 throw new IllegalAccessError("handleAttachment(Page) called");
1015             }
1016         });
1017 
1018         try {
1019             final HtmlPage page = loadPage(html);
1020             assertEquals(1, getWebClient().getWebWindows().size());
1021 
1022             page.getElementById("link").click();
1023             assertEquals(1, getWebClient().getWebWindows().size());
1024             assertTrue(page.getEnclosingWindow().getEnclosedPage() instanceof UnexpectedPage);
1025 
1026             assertEquals(0, pages.size());
1027         }
1028         finally {
1029             getWebClient().setAttachmentHandler(null);
1030         }
1031     }
1032 
1033     /**
1034      * @throws Exception if the test fails
1035      */
1036     @Test
1037     public void click_unexpectedPageAttachmentHandlerHandleResponseHandlesContentType() throws Exception {
1038         final String html = DOCTYPE_HTML
1039             + "<html><head></head>\n"
1040             + "<body>\n"
1041             + "  <a href='" + URL_SECOND + "' id='link'>link</a>\n"
1042             + "</body>\n"
1043             + "</html>";
1044 
1045         getMockWebConnection().setResponse(URL_SECOND, "{name: \"Test\"};", MimeType.APPLICATION_JSON);
1046 
1047         final LinkedList<WebResponse> pages = new LinkedList<>();
1048         getWebClient().setAttachmentHandler(new AttachmentHandler() {
1049 
1050             @Override
1051             public boolean isAttachment(final WebResponse response) {
1052                 return MimeType.APPLICATION_JSON
1053                         .equalsIgnoreCase(response.getResponseHeaderValue(HttpHeader.CONTENT_TYPE));
1054             }
1055 
1056             @Override
1057             public boolean handleAttachment(final WebResponse response, final String attachmentFilename) {
1058                 pages.add(response);
1059                 return true;
1060             }
1061 
1062             @Override
1063             public void handleAttachment(final Page page, final String attachmentFilename) {
1064                 throw new IllegalAccessError("handleAttachment(Page) called");
1065             }
1066         });
1067 
1068         try {
1069             final HtmlPage page = loadPage(html);
1070             assertEquals(1, getWebClient().getWebWindows().size());
1071 
1072             page.getElementById("link").click();
1073             assertEquals(1, getWebClient().getWebWindows().size());
1074             assertTrue(page.getEnclosingWindow().getEnclosedPage() == page);
1075 
1076             assertEquals(1, pages.size());
1077         }
1078         finally {
1079             getWebClient().setAttachmentHandler(null);
1080         }
1081     }
1082 
1083     /**
1084      * @throws Exception if the test fails
1085      */
1086     @Test
1087     public void click_unexpectedPageDownloadAttribute() throws Exception {
1088         final String html = DOCTYPE_HTML
1089             + "<html><head></head>\n"
1090             + "<body>\n"
1091             + "  <a href='" + URL_SECOND + "' id='link' download='test.json'>link</a>\n"
1092             + "</body>\n"
1093             + "</html>";
1094 
1095         getMockWebConnection().setResponse(URL_SECOND, "{name: \"Test\"};", MimeType.APPLICATION_JSON);
1096 
1097         final HtmlPage page = loadPage(html);
1098         assertEquals(1, getWebClient().getWebWindows().size());
1099 
1100         page.getElementById("link").click();
1101         assertEquals(2, getWebClient().getWebWindows().size());
1102 
1103         final WebWindow newWindow = getWebClient().getWebWindows().get(getWebClient().getWebWindows().size() - 1);
1104         assertTrue(newWindow.getEnclosedPage() instanceof UnexpectedPage);
1105     }
1106 
1107     /**
1108      * @throws Exception if the test fails
1109      */
1110     @Test
1111     public void click_unexpectedPageDownloadAttributeAttachmentHandler() throws Exception {
1112         final String html = DOCTYPE_HTML
1113             + "<html><head></head>\n"
1114             + "<body>\n"
1115             + "  <a href='" + URL_SECOND + "' id='link' download='test.json'>link</a>\n"
1116             + "</body>\n"
1117             + "</html>";
1118 
1119         getMockWebConnection().setResponse(URL_SECOND, "{name: \"Test\"};", MimeType.APPLICATION_JSON);
1120 
1121         final LinkedList<Page> pages = new LinkedList<>();
1122         getWebClient().setAttachmentHandler(new AttachmentHandler() {
1123             @Override
1124             public void handleAttachment(final Page page, final String attachmentFilename) {
1125                 pages.add(page);
1126             }
1127         });
1128 
1129         try {
1130             final HtmlPage page = loadPage(html);
1131             assertEquals(1, getWebClient().getWebWindows().size());
1132 
1133             page.getElementById("link").click();
1134             assertEquals(2, getWebClient().getWebWindows().size());
1135 
1136             final WebWindow newWindow = getWebClient().getWebWindows().get(getWebClient().getWebWindows().size() - 1);
1137             assertTrue(newWindow.getEnclosedPage() instanceof UnexpectedPage);
1138 
1139             assertEquals(1, pages.size());
1140             assertTrue(pages.get(0) instanceof UnexpectedPage);
1141         }
1142         finally {
1143             getWebClient().setAttachmentHandler(null);
1144         }
1145     }
1146 
1147     /**
1148      * @throws Exception if the test fails
1149      */
1150     @Test
1151     public void click_unexpectedPageDownloadAttributeAttachmentHandlerHandleResponse() throws Exception {
1152         final String html = DOCTYPE_HTML
1153             + "<html><head></head>\n"
1154             + "<body>\n"
1155             + "  <a href='" + URL_SECOND + "' id='link' download='test.json'>link</a>\n"
1156             + "</body>\n"
1157             + "</html>";
1158 
1159         getMockWebConnection().setResponse(URL_SECOND, "{name: \"Test\"};", MimeType.APPLICATION_JSON);
1160 
1161         final LinkedList<WebResponse> pages = new LinkedList<>();
1162         getWebClient().setAttachmentHandler(new AttachmentHandler() {
1163             @Override
1164             public boolean handleAttachment(final WebResponse response, final String attachmentFilename) {
1165                 pages.add(response);
1166                 return true;
1167             }
1168 
1169             @Override
1170             public void handleAttachment(final Page page, final String attachmentFilename) {
1171                 throw new IllegalAccessError("handleAttachment(Page) called");
1172             }
1173         });
1174 
1175         try {
1176             final HtmlPage page = loadPage(html);
1177             assertEquals(1, getWebClient().getWebWindows().size());
1178 
1179             page.getElementById("link").click();
1180             assertEquals(1, getWebClient().getWebWindows().size());
1181             assertTrue(page.getEnclosingWindow().getEnclosedPage() == page);
1182 
1183             assertEquals(1, pages.size());
1184         }
1185         finally {
1186             getWebClient().setAttachmentHandler(null);
1187         }
1188     }
1189 }