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.event;
16  
17  import org.htmlunit.WebDriverTestCase;
18  import org.htmlunit.junit.annotation.Alerts;
19  import org.junit.jupiter.api.Test;
20  import org.openqa.selenium.By;
21  import org.openqa.selenium.WebDriver;
22  
23  /**
24   * Tests for {@link HashChangeEvent}.
25   *
26   * @author Frank Danek
27   * @author Ronald Brill
28   */
29  public class HashChangeEventTest extends WebDriverTestCase {
30  
31      private static final String DUMP_EVENT_FUNCTION = "  function dump(event) {\n"
32          + "    if (event) {\n"
33          + "      log(event);\n"
34          + "      log(event.type);\n"
35          + "      log(event.bubbles);\n"
36          + "      log(event.cancelable);\n"
37          + "      log(event.composed);\n"
38  
39          + "      log(event.oldURL);\n"
40          + "      log(event.newURL);\n"
41          + "    } else {\n"
42          + "      log('no event');\n"
43          + "    }\n"
44          + "  }\n";
45  
46      /**
47       * @throws Exception if the test fails
48       */
49      @Test
50      @Alerts({"[object HashChangeEvent]", "hashchange", "false", "false", "false", "", ""})
51      public void create_ctor() throws Exception {
52          final String html = DOCTYPE_HTML
53              + "<html><head><script>\n"
54              + LOG_TITLE_FUNCTION
55              + "  function test() {\n"
56              + "    try {\n"
57              + "      var event = new HashChangeEvent('hashchange');\n"
58              + "      dump(event);\n"
59              + "    } catch(e) { logEx(e) }\n"
60              + "  }\n"
61              + DUMP_EVENT_FUNCTION
62              + "</script></head><body onload='test()'>\n"
63              + "</body></html>";
64  
65          loadPageVerifyTitle2(html);
66      }
67  
68      /**
69       * @throws Exception if the test fails
70       */
71      @Test
72      @Alerts({"[object HashChangeEvent]", "hashchange", "true", "false", "false", "null", "§§URL§§#1"})
73      public void create_ctorWithDetails() throws Exception {
74          final String html = DOCTYPE_HTML
75              + "<html><head><script>\n"
76              + LOG_TITLE_FUNCTION
77              + "  function test() {\n"
78              + "    try {\n"
79              + "      var event = new HashChangeEvent('hashchange', {\n"
80              + "        'bubbles': true,\n"
81              + "        'oldURL': null,\n"
82              + "        'newURL': '" + URL_FIRST + "#1'\n"
83              + "      });\n"
84              + "      dump(event);\n"
85              + "    } catch(e) { logEx(e) }\n"
86              + "  }\n"
87              + DUMP_EVENT_FUNCTION
88              + "</script></head><body onload='test()'>\n"
89              + "</body></html>";
90  
91          expandExpectedAlertsVariables(URL_FIRST);
92          loadPageVerifyTitle2(html);
93      }
94  
95      /**
96       * @throws Exception if the test fails
97       */
98      @Test
99      @Alerts({"[object HashChangeEvent]", "", "false", "false", "false", "", ""})
100     public void create_createEvent() throws Exception {
101         final String html = DOCTYPE_HTML
102             + "<html><head><script>\n"
103             + LOG_TITLE_FUNCTION
104             + "  function test() {\n"
105             + "    try {\n"
106             + "      var event = document.createEvent('HashChangeEvent');\n"
107             + "      dump(event);\n"
108             + "    } catch(e) { logEx(e) }\n"
109             + "  }\n"
110             + DUMP_EVENT_FUNCTION
111             + "</script></head><body onload='test()'>\n"
112             + "</body></html>";
113 
114         loadPageVerifyTitle2(html);
115     }
116 
117     /**
118      * @throws Exception if the test fails
119      */
120     @Test
121     @Alerts({"[object HashChangeEvent]", "missing initHashChangeEvent"})
122     public void initHashChangeEvent() throws Exception {
123         final String html = DOCTYPE_HTML
124             + "<html><head><script>\n"
125             + LOG_TITLE_FUNCTION
126             + "  function test() {\n"
127             + "    try {\n"
128             + "      var event = document.createEvent('HashChangeEvent');\n"
129             + "      log(event);\n"
130             + "    } catch(e) { log('exception createEvent'); logEx(e); return; }\n"
131 
132             + "    if (!event.initHashChangeEvent) {log('missing initHashChangeEvent'); return;}\n"
133 
134             + "    try {\n"
135             + "      event.initHashChangeEvent('hashchange', true, false, '" + URL_FIRST + "', '"
136             + URL_FIRST + "#1');\n"
137             + "      dump(event);\n"
138             + "    } catch(e) { log('exception initHashChangeEvent'); logEx(e); }\n"
139             + "  }\n"
140             + DUMP_EVENT_FUNCTION
141             + "</script></head><body onload='test()'>\n"
142             + "</body></html>";
143 
144         expandExpectedAlertsVariables(URL_FIRST);
145         loadPageVerifyTitle2(html);
146     }
147 
148     /**
149      * @throws Exception if the test fails
150      */
151     @Test
152     @Alerts("TypeError")
153     public void dispatchEvent() throws Exception {
154         final String html = DOCTYPE_HTML
155             + "<html><head><script>\n"
156             + LOG_TITLE_FUNCTION
157             + "  function test() {\n"
158             + "    try {\n"
159             + "      var event = document.createEvent('HashChangeEvent');\n"
160             + "      event.initHashChangeEvent('hashchange', true, false, '" + URL_FIRST + "', '"
161             + URL_FIRST + "#1');\n"
162             + "      dispatchEvent(event);\n"
163             + "    } catch(e) { logEx(e) }\n"
164             + "  }\n"
165             + DUMP_EVENT_FUNCTION
166             + "  window.onhashchange = dump;\n"
167             + "</script></head><body onload='test()'>\n"
168             + "</body></html>";
169 
170         expandExpectedAlertsVariables(URL_FIRST);
171         loadPageVerifyTitle2(html);
172     }
173 
174     /**
175      * @throws Exception if the test fails
176      */
177     @Test
178     @Alerts({"[object Event]", "hashchange", "true", "false", "false", "undefined", "undefined"})
179     public void dispatchEvent_event() throws Exception {
180         final String html = DOCTYPE_HTML
181             + "<html><head><script>\n"
182             + LOG_TITLE_FUNCTION
183             + "  function test() {\n"
184             + "    try {\n"
185             + "      var event = document.createEvent('Event');\n"
186             + "      event.initEvent('hashchange', true, false);\n"
187             + "      dispatchEvent(event);\n"
188             + "    } catch(e) { logEx(e) }\n"
189             + "  }\n"
190             + DUMP_EVENT_FUNCTION
191             + "  window.onhashchange = dump;\n"
192             + "</script></head><body onload='test()'>\n"
193             + "</body></html>";
194 
195         loadPageVerifyTitle2(html);
196     }
197 
198     /**
199      * @throws Exception if the test fails
200      */
201     @Test
202     @Alerts("supported")
203     public void onHashChange_supported() throws Exception {
204         final String html = DOCTYPE_HTML
205             + "<html><head><script>\n"
206             + LOG_TITLE_FUNCTION
207             + "  function test() {\n"
208             + "    if ('onhashchange' in window) { log('supported') }\n"
209             + "  }\n"
210             + "</script></head><body onload='test()'>\n"
211             + "</body></html>";
212 
213         loadPageVerifyTitle2(html);
214     }
215 
216     /**
217      * @throws Exception if the test fails
218      */
219     @Test
220     @Alerts({"[object HashChangeEvent]", "hashchange", "false", "false", "false", "§§URL§§", "§§URL§§#1"})
221     public void onHashChange() throws Exception {
222         final String html = DOCTYPE_HTML
223             + "<html><head><script>\n"
224             + LOG_TITLE_FUNCTION
225             + DUMP_EVENT_FUNCTION
226             + "  window.onhashchange = dump;\n"
227             + "</script></head><body>\n"
228             + "  <a id='click' href='#1'>change hash</a>\n"
229             + "</body></html>";
230 
231         expandExpectedAlertsVariables(URL_FIRST);
232         final WebDriver driver = loadPage2(html);
233         driver.findElement(By.id("click")).click();
234 
235         verifyTitle2(driver, getExpectedAlerts());
236     }
237 }