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;
16  
17  import java.net.URL;
18  import java.nio.charset.StandardCharsets;
19  
20  import org.htmlunit.html.HtmlPage;
21  import org.htmlunit.junit.annotation.Alerts;
22  import org.htmlunit.junit.annotation.HtmlUnitNYI;
23  import org.junit.jupiter.api.AfterEach;
24  import org.junit.jupiter.api.Assertions;
25  import org.junit.jupiter.api.Nested;
26  import org.junit.jupiter.api.Test;
27  import org.openqa.selenium.By;
28  import org.openqa.selenium.WebDriver;
29  import org.openqa.selenium.WebDriverException;
30  
31  /**
32   * Tests for handling HttpClient's {@link org.apache.http.NoHttpResponseException}.
33   *
34   * @author Marc Guillemot
35   * @author Frank Danek
36   * @author Ronald Brill
37   */
38  public class NoHttpResponseTest {
39      private static final String HTML
40          = "<html><body><script>\n"
41          + "  function fillField() {\n"
42          + "    document.forms.loginform.textfield.value = 'new value';\n"
43          + "  }\n"
44          + "</script>\n"
45          + "<form name='loginform' action='page2' method='get'>\n"
46          + "  <input type='text' name='textfield' value='' />\n"
47  
48          + "  <input type='submit' onclick='this.form.submit(); fillField(); return true;' id='jsSubmit'/>\n"
49          + "  <input type='submit' id='inputSubmit'>Submit</input>\n"
50          + "</form>\n"
51          + "</body></html>";
52  
53      /**
54       * Test using WebDriver.
55       */
56      @Nested
57      public class WithWebDriverTest extends WebDriverTestCase {
58  
59          /**
60           * Resets the {@link MiniServer}.
61           *
62           * @throws Exception in case of error
63           */
64          @AfterEach
65          public void after() throws Exception {
66              MiniServer.resetDropRequests();
67          }
68  
69          /**
70           * @throws Exception if the test fails
71           */
72          @Test
73          @Alerts(DEFAULT = "§§URL§§page2?textfield=",
74                  FF = "WebDriverException",
75                  FF_ESR = "WebDriverException")
76          @HtmlUnitNYI(FF = "§§URL§§page2?textfield=",
77                  FF_ESR = "§§URL§§page2?textfield=")
78          public void submit() throws Exception {
79              final MockWebConnection mockWebConnection = getMockWebConnection();
80              mockWebConnection.setResponse(URL_FIRST, HTML);
81              MiniServer.configureDropRequest(new URL(URL_FIRST, "page2?textfield="));
82              final URL urlRightSubmit = new URL(URL_FIRST, "page2?textfield=new+value");
83              mockWebConnection.setResponse(urlRightSubmit,
84                      DOCTYPE_HTML + "<html><head><title>right submit</title></head></html>");
85  
86              expandExpectedAlertsVariables(URL_FIRST);
87              final WebDriver driver = getWebDriver();
88  
89              try (MiniServer miniServer = new MiniServer(PORT, mockWebConnection)) {
90                  miniServer.start();
91  
92                  driver.get(URL_FIRST.toString());
93                  driver.findElement(By.id("inputSubmit")).click();
94                  if (useRealBrowser()) {
95                      Thread.sleep(400);
96                  }
97                  assertEquals(getExpectedAlerts()[0], driver.getCurrentUrl());
98              }
99              catch (final WebDriverException e) {
100                 assertEquals(getExpectedAlerts()[0], "WebDriverException");
101             }
102         }
103 
104         /**
105          * @throws Exception if the test fails
106          */
107         @Test
108         @Alerts("right submit")
109         public void callSubmitInButtonAndReturnTrue() throws Exception {
110             final MockWebConnection mockWebConnection = getMockWebConnection();
111             mockWebConnection.setResponse(URL_FIRST, HTML);
112             MiniServer.configureDropRequest(new URL(URL_FIRST, "page2?textfield="));
113             final URL urlRightSubmit = new URL(URL_FIRST, "page2?textfield=new+value");
114             mockWebConnection.setResponse(urlRightSubmit,
115                     DOCTYPE_HTML + "<html><head><title>right submit</title></head></html>");
116 
117             final WebDriver driver = getWebDriver();
118 
119             try (MiniServer miniServer = new MiniServer(PORT, mockWebConnection)) {
120                 miniServer.start();
121 
122                 driver.get(URL_FIRST.toString());
123                 driver.findElement(By.id("jsSubmit")).click();
124                 assertTitle(driver, getExpectedAlerts()[0]);
125             }
126         }
127     }
128 
129     /**
130      * Test using WebClient with default configuration allowing to throw exception.
131      */
132     @Nested
133     public class WithWebClientTest extends SimpleWebTestCase {
134 
135         /**
136          * Resets the {@link MiniServer}.
137          *
138          * @throws Exception in case of error
139          */
140         @AfterEach
141         public void after() throws Exception {
142             MiniServer.resetDropRequests();
143         }
144 
145         /**
146          * @throws Throwable if the test fails
147          */
148         @Test
149         @Alerts("§§URL§§")
150         public void submit() throws Throwable {
151             expandExpectedAlertsVariables(URL_FIRST);
152 
153             final MockWebConnection mockWebConnection = getMockWebConnection();
154             mockWebConnection.setResponse(URL_FIRST, HTML);
155 
156             MiniServer.configureDropRequest(new URL(URL_FIRST, "page2?textfield="));
157             final URL urlRightSubmit = new URL(URL_FIRST, "page2?textfield=new+value");
158             mockWebConnection.setResponse(urlRightSubmit,
159                     DOCTYPE_HTML + "<html><head><title>right submit</title></head></html>");
160 
161             expandExpectedAlertsVariables(URL_FIRST);
162 
163             try (MiniServer miniServer = new MiniServer(PORT, mockWebConnection)) {
164                 miniServer.start();
165 
166                 final HtmlPage page = getWebClient().getPage(URL_FIRST);
167 
168                 Assertions.assertThrows(FailingHttpStatusCodeException.class,
169                             () -> page.getElementById("inputSubmit").click());
170 
171                 assertEquals(getExpectedAlerts()[0], page.getUrl());
172             }
173         }
174 
175         /**
176          * @throws Throwable if the test fails
177          */
178         @Test
179         public void callSubmitInButtonAndReturnTrue() throws Throwable {
180             final MockWebConnection mockWebConnection = getMockWebConnection();
181             mockWebConnection.setResponse(URL_FIRST, HTML);
182             MiniServer.configureDropRequest(new URL(URL_FIRST, "page2?textfield="));
183             final URL urlRightSubmit = new URL(URL_FIRST, "page2?textfield=new+value");
184             mockWebConnection.setResponse(urlRightSubmit,
185                     DOCTYPE_HTML + "<html><head><title>right submit</title></head></html>");
186 
187             try (MiniServer miniServer = new MiniServer(PORT, mockWebConnection)) {
188                 miniServer.start();
189 
190                 HtmlPage page = getWebClient().getPage(URL_FIRST);
191                 page = page.getElementById("jsSubmit").click();
192                 assertEquals("right submit", page.getTitleText());
193             }
194         }
195 
196         /**
197          * @throws Exception if the test fails
198          */
199         @Test
200         public void htmlUnitDriverUsesGetPage() throws Exception {
201             final MockWebConnection mockWebConnection = getMockWebConnection();
202             MiniServer.configureDropRequest(URL_FIRST);
203 
204             try (MiniServer miniServer = new MiniServer(PORT, mockWebConnection)) {
205                 miniServer.start();
206 
207                 final WebRequest request = new WebRequest(new URL(URL_FIRST.toString()),
208                         getBrowserVersion().getHtmlAcceptHeader(), getBrowserVersion().getAcceptEncodingHeader());
209                 request.setCharset(StandardCharsets.UTF_8);
210 
211                 try {
212                     getWebClient().getPage(getWebClient().getCurrentWindow().getTopWindow(), request);
213                     Assertions.fail("FailingHttpStatusCodeException expected");
214                 }
215                 catch (final FailingHttpStatusCodeException e) {
216                     // expected
217                     assertEquals(0, e.getStatusCode());
218                     assertEquals("0 No HTTP Response for " + URL_FIRST.toString(), e.getMessage());
219                 }
220             }
221         }
222     }
223 }