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.javascript.host.html;
16  
17  import java.net.URL;
18  import java.util.ArrayList;
19  import java.util.List;
20  
21  import org.htmlunit.CollectingAlertHandler;
22  import org.htmlunit.CookieManager;
23  import org.htmlunit.ScriptException;
24  import org.htmlunit.SimpleWebTestCase;
25  import org.htmlunit.WebClient;
26  import org.htmlunit.html.HtmlPage;
27  import org.htmlunit.junit.annotation.Alerts;
28  import org.htmlunit.util.Cookie;
29  import org.junit.jupiter.api.Assertions;
30  import org.junit.jupiter.api.Test;
31  
32  /**
33   * Tests for {@link HTMLDocument}.
34   *
35   * @author Ahmed Ashour
36   * @author Marc Guillemot
37   * @author Ronald Brill
38   */
39  public class HTMLDocument2Test extends SimpleWebTestCase {
40  
41      /**
42       * @throws Exception if the test fails
43       */
44      @Test
45      @Alerts({"www.gargoylesoftware.com", "gargoylesoftware.com"})
46      public void domain() throws Exception {
47          final String html = DOCTYPE_HTML
48              + "<html><head><title>foo</title><script>\n"
49              + "function doTest() {\n"
50              + "  alert(document.domain);\n"
51              + "  document.domain = 'gargoylesoftware.com';\n"
52              + "  alert(document.domain);\n"
53              + "}\n"
54              + "</script></head>\n"
55              + "<body onload='doTest()'>\n"
56              + "</body></html>";
57  
58          loadPageWithAlerts(html, new URL("http://www.gargoylesoftware.com/"), null);
59      }
60  
61      /**
62       * @throws Exception if the test fails
63       */
64      @Test
65      @Alerts({"localhost", "gargoylesoftware.com"})
66      public void domainFromLocalhost() throws Exception {
67          final String html = DOCTYPE_HTML
68              + "<html><head><title>foo</title><script>\n"
69              + "function doTest() {\n"
70              + "  alert(document.domain);\n"
71              + "  document.domain = 'gargoylesoftware.com';\n"
72              + "  alert(document.domain);\n"
73              + "}\n"
74              + "</script></head>\n"
75              + "<body onload='doTest()'>\n"
76              + "</body></html>";
77  
78          getMockWebConnection().setDefaultResponse(html);
79          loadPageWithAlerts(html, new URL("http://localhost"), null);
80      }
81  
82      /**
83       * @throws Exception if the test fails
84       */
85      @Test
86      @Alerts({"www.gargoylesoftware.com", "gargoylesoftware.com"})
87      public void domainMixedCaseNetscape() throws Exception {
88          final URL urlGargoyleUpperCase = new URL("http://WWW.GARGOYLESOFTWARE.COM/");
89  
90          final String html = DOCTYPE_HTML
91              + "<html><head><title>foo</title><script>\n"
92              + "function doTest() {\n"
93              + "  alert(document.domain);\n"
94              + "  document.domain = 'GaRgOyLeSoFtWaRe.CoM';\n"
95              + "  alert(document.domain);\n"
96              + "}\n"
97              + "</script></head>\n"
98              + "<body onload='doTest()'>\n"
99              + "</body></html>";
100 
101         getMockWebConnection().setDefaultResponse(html);
102         loadPageWithAlerts(html, urlGargoyleUpperCase, null);
103     }
104 
105     /**
106      * @throws Exception if the test fails
107      */
108     @Test
109     @Alerts({"www.gargoylesoftware.com", "gargoylesoftware.com"})
110     public void domainMixedCase() throws Exception {
111         final String html = DOCTYPE_HTML
112             + "<html><head><title>foo</title><script>\n"
113             + "function doTest() {\n"
114             + "  alert(document.domain);\n"
115             + "  document.domain = 'GaRgOyLeSoFtWaRe.CoM';\n"
116             + "  alert(document.domain);\n"
117             + "}\n"
118             + "</script></head>\n"
119             + "<body onload='doTest()'>\n"
120             + "</body></html>";
121 
122         loadPageWithAlerts(html, new URL("http://www.gargoylesoftware.com/"), null);
123     }
124 
125     /**
126      * @throws Exception if the test fails
127      */
128     @Test
129     @Alerts({"d4.d3.d2.d1.gargoylesoftware.com", "d4.d3.d2.d1.gargoylesoftware.com", "d1.gargoylesoftware.com"})
130     public void domainLong() throws Exception {
131         final String html = DOCTYPE_HTML
132             + "<html><head><title>foo</title><script>\n"
133             + "function doTest() {\n"
134             + "  alert(document.domain);\n"
135             + "  document.domain = 'd4.d3.d2.d1.gargoylesoftware.com';\n"
136             + "  alert(document.domain);\n"
137             + "  document.domain = 'd1.gargoylesoftware.com';\n"
138             + "  alert(document.domain);\n"
139             + "}\n"
140             + "</script></head>\n"
141             + "<body onload='doTest()'>\n"
142             + "</body></html>";
143 
144         getMockWebConnection().setDefaultResponse(html);
145         loadPageWithAlerts(html, new URL("http://d4.d3.d2.d1.gargoylesoftware.com"), null);
146     }
147 
148     /**
149      * @throws Exception if the test fails
150      */
151     @Test
152     @Alerts({"localhost", "localhost"})
153     public void domainSetSelf() throws Exception {
154         final String html = DOCTYPE_HTML
155             + "<html><head><title>foo</title><script>\n"
156             + "function doTest() {\n"
157             + "  alert(document.domain);\n"
158             + "  document.domain = 'localhost';\n"
159             + "  alert(document.domain);\n"
160             + "}\n"
161             + "</script></head>\n"
162             + "<body onload='doTest()'>\n"
163             + "</body></html>";
164 
165         getMockWebConnection().setDefaultResponse(html);
166         loadPageWithAlerts(html, new URL("http://localhost"), null);
167     }
168 
169     /**
170      * @throws Exception if the test fails
171      */
172     @Test
173     public void domainTooShort() throws Exception {
174         final String html = DOCTYPE_HTML
175             + "<html><head><title>foo</title><script>\n"
176             + "function doTest() {\n"
177             + "  alert(document.domain);\n"
178             + "  document.domain = 'com';\n"
179             + "  alert(document.domain);\n"
180             + "}\n"
181             + "</script></head>\n"
182             + "<body onload='doTest()'>\n"
183             + "</body></html>";
184 
185         final List<String> collectedAlerts = new ArrayList<>();
186         try {
187             loadPage(getWebClient(), html, collectedAlerts);
188         }
189         catch (final ScriptException ex) {
190             return;
191         }
192         Assertions.fail();
193     }
194 
195     /**
196      * @throws Exception if the test fails
197      */
198     @Test
199     @Alerts({"www.gargoylesoftware.com", "www.gargoylesoftware.com"})
200     public void domain_set_for_about_blank() throws Exception {
201         final String html = DOCTYPE_HTML
202             + "<html><head><title>foo</title><script>\n"
203             + "function doTest() {\n"
204             + "  var domain = document.domain;\n"
205             + "  alert(domain);\n"
206             + "  var frameDoc = frames[0].document;\n"
207             + "  alert(frameDoc.domain);\n"
208             + "  try {\n"
209             + "    frameDoc.domain = domain;\n"
210             + "  } catch(e) { alert('exception'); }\n"
211             + "}\n"
212             + "</script></head>\n"
213             + "<body onload='doTest()'>\n"
214             + "<iframe src='about:blank'></iframe>\n"
215             + "</body></html>";
216 
217         loadPageWithAlerts(html, new URL("http://www.gargoylesoftware.com/"), null);
218     }
219 
220     /**
221      * @throws Exception if the test fails
222      */
223     @Test
224     @Alerts({"one", "two", "three", "four"})
225     public void cookie_read() throws Exception {
226         final WebClient webClient = getWebClientWithMockWebConnection();
227 
228         final String html = DOCTYPE_HTML
229             + "<html><head><title>First</title><script>\n"
230             + "function doTest() {\n"
231             + "  var cookieSet = document.cookie.split('; ');\n"
232             + "  var setSize = cookieSet.length;\n"
233             + "  var crumbs;\n"
234             + "  for (var x = 0; x < setSize; x++) {\n"
235             + "    crumbs = cookieSet[x].split('=');\n"
236             + "    alert(crumbs[0]);\n"
237             + "    alert(crumbs[1]);\n"
238             + "  }\n"
239             + "}\n"
240             + "</script></head><body onload='doTest()'>\n"
241             + "</body></html>";
242 
243         final URL url = URL_FIRST;
244         getMockWebConnection().setResponse(url, html);
245 
246         final CookieManager mgr = webClient.getCookieManager();
247         mgr.addCookie(new Cookie(url.getHost(), "one", "two", "/", null, false));
248         mgr.addCookie(new Cookie(url.getHost(), "three", "four", "/", null, false));
249 
250         final List<String> collectedAlerts = new ArrayList<>();
251         webClient.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
252 
253         final HtmlPage firstPage = webClient.getPage(url);
254         assertEquals("First", firstPage.getTitleText());
255 
256         assertEquals(getExpectedAlerts(), collectedAlerts);
257     }
258 
259     /**
260      * This one can't be tested with WebDriver.
261      * @throws Exception if an error occurs
262      */
263     @Test
264     @Alerts({"false", "", "", ""})
265     public void cookie_write_cookiesDisabled() throws Exception {
266         final String html = DOCTYPE_HTML
267               + "html><head><script>\n"
268               + "  alert(navigator.cookieEnabled);\n"
269               + "  alert(document.cookie);\n"
270               + "  document.cookie = 'foo=bar';\n"
271               + "  alert(document.cookie);\n"
272               + "  document.cookie = 'foo=hello world';\n"
273               + "  alert(document.cookie);\n"
274               + "</script>\n"
275               + "</head>\n"
276               + "<body>abc</body>\n"
277               + "</html>";
278 
279         final WebClient client = getWebClientWithMockWebConnection();
280         client.getCookieManager().setCookiesEnabled(false);
281 
282         loadPage(html);
283     }
284 
285     /**
286      * Verifies that cookies work when working with local files (not remote sites with real domains).
287      * Required for local testing of Dojo 1.1.1.
288      * @throws Exception if an error occurs
289      */
290     @Test
291     @Alerts({"", "", "blah=bleh"})
292     public void cookieInLocalFile() throws Exception {
293         final WebClient client = getWebClient();
294 
295         final List<String> actual = new ArrayList<>();
296         client.setAlertHandler(new CollectingAlertHandler(actual));
297 
298         final URL url = getClass().getResource("HTMLDocumentTest_cookieInLocalFile.html");
299         client.getPage(url);
300 
301         assertEquals(getExpectedAlerts(), actual);
302     }
303 
304 }