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.BrowserRunner;
19  import org.htmlunit.junit.annotation.Alerts;
20  import org.junit.Test;
21  import org.junit.runner.RunWith;
22  import org.openqa.selenium.By;
23  import org.openqa.selenium.WebDriver;
24  import org.openqa.selenium.interactions.Actions;
25  
26  /**
27   * Unit tests for {@link UIEvent}.
28   *
29   * @author Daniel Gredler
30   * @author Frank Danek
31   * @author Ronald Brill
32   */
33  @RunWith(BrowserRunner.class)
34  public class UIEventTest extends WebDriverTestCase {
35  
36      private static final String DUMP_EVENT_FUNCTION = "  function dump(event) {\n"
37              + "    log(event);\n"
38              + "    log(event.type);\n"
39              + "    log(event.bubbles);\n"
40              + "    log(event.cancelable);\n"
41              + "    log(event.composed);\n"
42  
43              + "    log(event.view == window);\n"
44              + "  }\n";
45  
46      /**
47       * @throws Exception if the test fails
48       */
49      @Test
50      @Alerts({"[object UIEvent]", "event", "false", "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 UIEvent('event');\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 UIEvent]", "event", "true", "false", "false", "true"})
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 UIEvent('event', {\n"
80              + "        'bubbles': true,\n"
81              + "        'view': window\n"
82              + "      });\n"
83              + "      dump(event);\n"
84              + "    } catch(e) { logEx(e) }\n"
85              + "  }\n"
86              + DUMP_EVENT_FUNCTION
87              + "</script></head><body onload='test()'>\n"
88              + "</body></html>";
89  
90          loadPageVerifyTitle2(html);
91      }
92  
93      /**
94       * @throws Exception if the test fails
95       */
96      @Test
97      @Alerts("TypeError")
98      public void create_ctorWithDetailsViewNotWindow() throws Exception {
99          final String html = DOCTYPE_HTML
100             + "<html><head><script>\n"
101             + LOG_TITLE_FUNCTION
102             + "  function test() {\n"
103             + "    try {\n"
104             + "      var event = new UIEvent('event', {\n"
105             + "        'view': {}\n"
106             + "      });\n"
107             + "    } catch(e) { logEx(e) }\n"
108             + "  }\n"
109             + DUMP_EVENT_FUNCTION
110             + "</script></head><body onload='test()'>\n"
111             + "</body></html>";
112 
113         loadPageVerifyTitle2(html);
114     }
115 
116     /**
117      * @throws Exception if the test fails
118      */
119     @Test
120     @Alerts({"DOM2: [object UIEvent]", "DOM3: [object UIEvent]"})
121     public void createEvent() throws Exception {
122         final String html = DOCTYPE_HTML
123             + "<html><head><script>\n"
124             + LOG_TITLE_FUNCTION
125             + "  function test() {\n"
126             + "    try {\n"
127             + "      log('DOM2: ' + document.createEvent('UIEvents'));\n"
128             + "    } catch(e) {log('DOM2: exception')}\n"
129             + "    try {\n"
130             + "      log('DOM3: ' + document.createEvent('UIEvent'));\n"
131             + "    } catch(e) {log('DOM3: exception')}\n"
132             + "  }\n"
133             + "</script></head><body onload='test()'>\n"
134             + "</body></html>";
135         loadPageVerifyTitle2(html);
136     }
137 
138     /**
139      * @throws Exception if an error occurs
140      */
141     @Test
142     @Alerts({"[object UIEvent]", "click", "true", "true", "true", "7"})
143     public void initUIEvent() throws Exception {
144         final String html = DOCTYPE_HTML
145             + "<html><body><script>\n"
146             + LOG_TITLE_FUNCTION
147             + "try {\n"
148             + "  var e = document.createEvent('UIEvents');\n"
149             + "  log(e);\n"
150             + "  e.initUIEvent('click', true, true, window, 7);\n"
151             + "  log(e.type);\n"
152             + "  log(e.bubbles);\n"
153             + "  log(e.cancelable);\n"
154             + "  log(e.view == window);\n"
155             + "  log(e.detail);\n"
156             + "} catch(e) { logEx(e) }\n"
157             + "</script></body></html>";
158         loadPageVerifyTitle2(html);
159     }
160 
161     /**
162      * @throws Exception if an error occurs
163      */
164     @Test
165     @Alerts(CHROME = {"[object Event]", "undefined", "[object PointerEvent]", "1",
166                       "[object MouseEvent]", "2", "[object PointerEvent]", "0"},
167             EDGE = {"[object Event]", "undefined", "[object PointerEvent]", "1",
168                     "[object MouseEvent]", "2", "[object PointerEvent]", "0"},
169             FF = {"[object Event]", "undefined", "[object PointerEvent]", "1",
170                   "[object MouseEvent]", "2", "[object PointerEvent]", "1"},
171             FF_ESR = {"[object Event]", "undefined", "[object MouseEvent]", "1",
172                       "[object MouseEvent]", "2", "[object MouseEvent]", "1"})
173     public void detail() throws Exception {
174         final String html = DOCTYPE_HTML
175             + "<html><head><script>\n"
176             + LOG_TITLE_FUNCTION
177             + "  function alertDetail(e) {\n"
178             + "    log(e);\n"
179             + "    log(e.detail);\n"
180             + "  }\n"
181             + "</script></head>\n"
182             + "<body onload='alertDetail(event)'>\n"
183             + "  <div id='a' onclick='alertDetail(event)'>abc</div>\n"
184             + "  <div id='b' ondblclick='alertDetail(event)'>xyz</div>\n"
185             + "  <div id='c' oncontextmenu='alertDetail(event)'>xyz</div>\n"
186             + "</body></html>";
187 
188         final String[] alerts = getExpectedAlerts();
189         int i = 0;
190 
191         final WebDriver driver = loadPage2(html);
192         verifyTitle2(driver, alerts[i++], alerts[i++]);
193 
194         i = 0;
195         driver.findElement(By.id("a")).click();
196         verifyTitle2(driver, alerts[i++], alerts[i++], alerts[i++], alerts[i++]);
197 
198         i = 0;
199         Actions action = new Actions(driver);
200         action.doubleClick(driver.findElement(By.id("b")));
201         action.perform();
202         verifyTitle2(driver, alerts[i++], alerts[i++], alerts[i++], alerts[i++], alerts[i++], alerts[i++]);
203 
204         action = new Actions(driver);
205         action.contextClick(driver.findElement(By.id("c")));
206         action.perform();
207         verifyTitle2(driver, alerts);
208     }
209 
210     /**
211      * @throws Exception if an error occurs
212      */
213     @Test
214     @Alerts(CHROME = {"[object Event]", "undefined", "[object PointerEvent]", "1",
215                       "[object MouseEvent]", "2", "[object PointerEvent]", "0"},
216             EDGE = {"[object Event]", "undefined", "[object PointerEvent]", "1",
217                     "[object MouseEvent]", "2", "[object PointerEvent]", "0"},
218             FF = {"[object Event]", "undefined", "[object PointerEvent]", "1",
219                   "[object MouseEvent]", "2", "[object PointerEvent]", "1"},
220             FF_ESR = {"[object Event]", "undefined", "[object MouseEvent]", "1",
221                       "[object MouseEvent]", "2", "[object MouseEvent]", "1"})
222     public void detailInputText() throws Exception {
223         final String html = DOCTYPE_HTML
224             + "<html><head><script>\n"
225             + LOG_TITLE_FUNCTION
226             + "  function alertDetail(e) {\n"
227             + "    log(e);\n"
228             + "    log(e.detail);\n"
229             + "  }\n"
230             + "</script></head>\n"
231             + "<body onload='alertDetail(event)'>\n"
232             + "  <input type='text' id='a' onclick='alertDetail(event)'>\n"
233             + "  <input type='text' id='b' ondblclick='alertDetail(event)'>\n"
234             + "  <input type='text' id='c' oncontextmenu='alertDetail(event)'>\n"
235             + "</body></html>";
236 
237         final String[] alerts = getExpectedAlerts();
238         int i = 0;
239 
240         final WebDriver driver = loadPage2(html);
241         verifyTitle2(driver, alerts[i++], alerts[i++]);
242 
243         i = 0;
244         driver.findElement(By.id("a")).click();
245         verifyTitle2(driver, alerts[i++], alerts[i++], alerts[i++], alerts[i++]);
246 
247 
248         i = 0;
249         Actions action = new Actions(driver);
250         action.doubleClick(driver.findElement(By.id("b")));
251         action.perform();
252         verifyTitle2(driver, alerts[i++], alerts[i++], alerts[i++], alerts[i++], alerts[i++], alerts[i++]);
253 
254         action = new Actions(driver);
255         action.contextClick(driver.findElement(By.id("c")));
256         action.perform();
257         verifyTitle2(driver, alerts);
258     }
259 
260     /**
261      * @throws Exception if an error occurs
262      */
263     @Test
264     @Alerts(CHROME = {"[object Event]", "undefined", "[object PointerEvent]", "1",
265                       "[object MouseEvent]", "2", "[object PointerEvent]", "0"},
266             EDGE = {"[object Event]", "undefined", "[object PointerEvent]", "1",
267                     "[object MouseEvent]", "2", "[object PointerEvent]", "0"},
268             FF = {"[object Event]", "undefined", "[object PointerEvent]", "1",
269                   "[object MouseEvent]", "2", "[object PointerEvent]", "1"},
270             FF_ESR = {"[object Event]", "undefined", "[object MouseEvent]", "1",
271                       "[object MouseEvent]", "2", "[object MouseEvent]", "1"})
272     public void detailInputRadio() throws Exception {
273         final String html = DOCTYPE_HTML
274             + "<html><head><script>\n"
275             + LOG_TITLE_FUNCTION
276             + "  function alertDetail(e) {\n"
277             + "    log(e);\n"
278             + "    log(e.detail);\n"
279             + "  }\n"
280             + "</script></head>\n"
281             + "<body onload='alertDetail(event)'>\n"
282             + "  <input type='radio' id='a' onclick='alertDetail(event)'>\n"
283             + "  <input type='radio' id='b' ondblclick='alertDetail(event)'>\n"
284             + "  <input type='radio' id='c' oncontextmenu='alertDetail(event)'>\n"
285             + "</body></html>";
286 
287         final String[] alerts = getExpectedAlerts();
288         int i = 0;
289 
290         final WebDriver driver = loadPage2(html);
291         verifyTitle2(driver, alerts[i++], alerts[i++]);
292 
293         i = 0;
294         driver.findElement(By.id("a")).click();
295         verifyTitle2(driver, alerts[i++], alerts[i++], alerts[i++], alerts[i++]);
296 
297 
298         i = 0;
299         Actions action = new Actions(driver);
300         action.doubleClick(driver.findElement(By.id("b")));
301         action.perform();
302         verifyTitle2(driver, alerts[i++], alerts[i++], alerts[i++], alerts[i++], alerts[i++], alerts[i++]);
303 
304         action = new Actions(driver);
305         action.contextClick(driver.findElement(By.id("c")));
306         action.perform();
307         verifyTitle2(driver, alerts);
308     }
309 
310     /**
311      * @throws Exception if an error occurs
312      */
313     @Test
314     @Alerts(DEFAULT = {"[object Event]", "undefined", "[object PointerEvent]", "[object Window]"},
315             FF_ESR = {"[object Event]", "undefined", "[object MouseEvent]", "[object Window]"})
316     public void view() throws Exception {
317         final String html = DOCTYPE_HTML
318             + "<html><body onload='alertView(event)'><script>\n"
319             + LOG_TITLE_FUNCTION
320             + "  function alertView(e) {\n"
321             + "    log(e);\n"
322             + "    log(e.view);\n"
323             + "  }\n"
324             + "</script>\n"
325             + "<form><input type='button' id='b' onclick='alertView(event)'></form>\n"
326             + "</body></html>";
327 
328         final String[] alerts = getExpectedAlerts();
329 
330         final WebDriver driver = loadPage2(html);
331         verifyTitle2(driver, alerts[0], alerts[1]);
332 
333         driver.findElement(By.id("b")).click();
334         verifyTitle2(driver, alerts);
335     }
336 }