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  
21  /**
22   * Tests for {@link MutationEvent}.
23   *
24   * @author Ahmed Ashour
25   * @author Frank Danek
26   * @author Ronald Brill
27   */
28  public class MutationEventTest extends WebDriverTestCase {
29  
30      private static final String DUMP_EVENT_FUNCTION = "  function dump(event) {\n"
31              + "    log(event);\n"
32              + "    log(event.type);\n"
33              + "    log(event.bubbles);\n"
34              + "    log(event.cancelable);\n"
35              + "    log(event.composed);\n"
36  
37              // TODO all properties
38              + "  }\n";
39  
40      /**
41       * @throws Exception if the test fails
42       */
43      @Test
44      @Alerts(DEFAULT = "ReferenceError",
45              FF_ESR = "TypeError")
46      public void create_ctor() throws Exception {
47          final String html = DOCTYPE_HTML
48              + "<html><head><script>\n"
49              + LOG_TITLE_FUNCTION
50              + "  function test() {\n"
51              + "    try {\n"
52              + "      var event = new MutationEvent('mutant');\n"
53              + "      dump(event);\n"
54              + "    } catch(e) { logEx(e) }\n"
55              + "  }\n"
56              + DUMP_EVENT_FUNCTION
57              + "</script></head><body onload='test()'>\n"
58              + "</body></html>";
59  
60          loadPageVerifyTitle2(html);
61      }
62  
63      /**
64       * @throws Exception if the test fails
65       */
66      @Test
67      @Alerts(DEFAULT = "ReferenceError",
68              FF_ESR = "TypeError")
69      public void create_ctorWithoutType() throws Exception {
70          final String html = DOCTYPE_HTML
71              + "<html><head><script>\n"
72              + LOG_TITLE_FUNCTION
73              + "  function test() {\n"
74              + "    try {\n"
75              + "      var event = new MutationEvent();\n"
76              + "      dump(event);\n"
77              + "    } catch(e) { logEx(e) }\n"
78              + "  }\n"
79              + DUMP_EVENT_FUNCTION
80              + "</script></head><body onload='test()'>\n"
81              + "</body></html>";
82  
83          loadPageVerifyTitle2(html);
84      }
85  
86      /**
87       * @throws Exception if the test fails
88       */
89      @Test
90      @Alerts(DEFAULT = "ReferenceError",
91              FF_ESR = "TypeError")
92      public void create_ctorNumericType() throws Exception {
93          final String html = DOCTYPE_HTML
94              + "<html><head><script>\n"
95              + LOG_TITLE_FUNCTION
96              + "  function test() {\n"
97              + "    try {\n"
98              + "      var event = new MutationEvent(42);\n"
99              + "      dump(event);\n"
100             + "    } catch(e) { logEx(e) }\n"
101             + "  }\n"
102             + DUMP_EVENT_FUNCTION
103             + "</script></head><body onload='test()'>\n"
104             + "</body></html>";
105 
106         loadPageVerifyTitle2(html);
107     }
108 
109     /**
110      * @throws Exception if the test fails
111      */
112     @Test
113     @Alerts(DEFAULT = "ReferenceError",
114             FF_ESR = "TypeError")
115     public void create_ctorNullType() throws Exception {
116         final String html = DOCTYPE_HTML
117             + "<html><head><script>\n"
118             + LOG_TITLE_FUNCTION
119             + "  function test() {\n"
120             + "    try {\n"
121             + "      var event = new MutationEvent(null);\n"
122             + "      dump(event);\n"
123             + "    } catch(e) { logEx(e) }\n"
124             + "  }\n"
125             + DUMP_EVENT_FUNCTION
126             + "</script></head><body onload='test()'>\n"
127             + "</body></html>";
128 
129         loadPageVerifyTitle2(html);
130     }
131 
132     /**
133      * @throws Exception if the test fails
134      */
135     @Test
136     @Alerts("ReferenceError")
137     public void create_ctorUnknownType() throws Exception {
138         final String html = DOCTYPE_HTML
139             + "<html><head><script>\n"
140             + LOG_TITLE_FUNCTION
141             + "  function test() {\n"
142             + "    try {\n"
143             + "      var event = new MutationEvent(unknown);\n"
144             + "      dump(event);\n"
145             + "    } catch(e) { logEx(e) }\n"
146             + "  }\n"
147             + DUMP_EVENT_FUNCTION
148             + "</script></head><body onload='test()'>\n"
149             + "</body></html>";
150 
151         loadPageVerifyTitle2(html);
152     }
153 
154     /**
155      * @throws Exception if the test fails
156      */
157     @Test
158     @Alerts(DEFAULT = "ReferenceError",
159             FF_ESR = "TypeError")
160     public void create_ctorArbitraryType() throws Exception {
161         final String html = DOCTYPE_HTML
162             + "<html><head><script>\n"
163             + LOG_TITLE_FUNCTION
164             + "  function test() {\n"
165             + "    try {\n"
166             + "      var event = new MutationEvent('HtmlUnitEvent');\n"
167             + "      dump(event);\n"
168             + "    } catch(e) { logEx(e) }\n"
169             + "  }\n"
170             + DUMP_EVENT_FUNCTION
171             + "</script></head><body onload='test()'>\n"
172             + "</body></html>";
173 
174         loadPageVerifyTitle2(html);
175     }
176 
177     /**
178      * @throws Exception if the test fails
179      */
180     @Test
181     @Alerts(DEFAULT = "ReferenceError",
182             FF_ESR = "TypeError")
183     public void create_ctorAllDetails() throws Exception {
184         final String html = DOCTYPE_HTML
185             + "<html><head><script>\n"
186             + LOG_TITLE_FUNCTION
187             + "  function test() {\n"
188             + "    try {\n"
189             + "      var event = new MutationEvent('mutant', {\n"
190             // + "        'data': 'mozart'\n"
191             + "      });\n"
192             + "      dump(event);\n"
193             + "    } catch(e) { logEx(e) }\n"
194             + "  }\n"
195             + DUMP_EVENT_FUNCTION
196             + "</script></head><body onload='test()'>\n"
197             + "</body></html>";
198 
199         loadPageVerifyTitle2(html);
200     }
201 
202     /**
203      * @throws Exception if the test fails
204      */
205     @Test
206     @Alerts(DEFAULT = "ReferenceError",
207             FF_ESR = "TypeError")
208     public void create_ctorAllDetailsMissingData() throws Exception {
209         final String html = DOCTYPE_HTML
210             + "<html><head><script>\n"
211             + LOG_TITLE_FUNCTION
212             + "  function test() {\n"
213             + "    try {\n"
214             + "      var event = new MutationEvent('mutant', {\n"
215             + "      });\n"
216             + "      dump(event);\n"
217             + "    } catch(e) { logEx(e) }\n"
218             + "  }\n"
219             + DUMP_EVENT_FUNCTION
220             + "</script></head><body onload='test()'>\n"
221             + "</body></html>";
222 
223         loadPageVerifyTitle2(html);
224     }
225 
226     /**
227      * @throws Exception if the test fails
228      */
229     @Test
230     @Alerts(DEFAULT = "ReferenceError",
231             FF_ESR = "TypeError")
232     public void create_ctorAllDetailsWrongData() throws Exception {
233         final String html = DOCTYPE_HTML
234             + "<html><head><script>\n"
235             + LOG_TITLE_FUNCTION
236             + "  function test() {\n"
237             + "    try {\n"
238             + "      var event = new MutationEvent('mutant', {\n"
239             + "        'data': ['Html', 'Unit']\n"
240             + "      });\n"
241             + "      dump(event);\n"
242             + "    } catch(e) { logEx(e) }\n"
243             + "  }\n"
244             + DUMP_EVENT_FUNCTION
245             + "</script></head><body onload='test()'>\n"
246             + "</body></html>";
247 
248         loadPageVerifyTitle2(html);
249     }
250 
251     /**
252      * @throws Exception if the test fails
253      */
254     @Test
255     @Alerts(DEFAULT = "false",
256             FF_ESR = "true")
257     public void inWindow() throws Exception {
258         final String html = DOCTYPE_HTML
259             + "<html>\n"
260             + "<head>\n"
261             + "  <script>\n"
262             + LOG_TITLE_FUNCTION
263             + "    function test() {\n"
264             + "      log('MutationEvent' in window);\n"
265             + "    }\n"
266             + "  </script>\n"
267             + "</head>\n"
268             + "<body onload='test()'>\n"
269             + "</body>\n"
270             + "</html>";
271 
272         loadPageVerifyTitle2(html);
273     }
274 
275     /**
276      * @throws Exception if the test fails
277      */
278     @Test
279     @Alerts(DEFAULT = {"DOM2: exception", "DOM3: exception"},
280             FF = {"DOM2: [object MutationEvent]", "DOM3: [object MutationEvent]"},
281             FF_ESR = {"DOM2: [object MutationEvent]", "DOM3: [object MutationEvent]"})
282     public void createEvent() throws Exception {
283         final String html = DOCTYPE_HTML
284             + "<html><head><script>\n"
285             + "  function test() {\n"
286             + LOG_TITLE_FUNCTION
287             + "    try {\n"
288             + "      log('DOM2: ' + document.createEvent('MutationEvents'));\n"
289             + "    } catch(e) {log('DOM2: exception')}\n"
290             + "    try {\n"
291             + "      log('DOM3: ' + document.createEvent('MutationEvent'));\n"
292             + "    } catch(e) {log('DOM3: exception')}\n"
293             + "  }\n"
294             + "</script></head><body onload='test()'>\n"
295             + "</body></html>";
296         loadPageVerifyTitle2(html);
297     }
298 
299     /**
300      * @throws Exception if the test fails
301      */
302     @Test
303     @Alerts(DEFAULT = {"false", "undefined", "ReferenceError", "ReferenceError", "ReferenceError",
304                        "false", "undefined", "ReferenceError", "ReferenceError", "ReferenceError"},
305             FF_ESR = {"false", "undefined", "ReferenceError", "ReferenceError", "ReferenceError",
306                       "true", "function MutationEvent() { [native code] }",
307                       "function MutationEvent() { [native code] }",
308                       "[object MutationEvent]", "function Event() { [native code] }"})
309     public void windowScope() throws Exception {
310         final String html = DOCTYPE_HTML
311             + "<html></body>\n"
312             + "<script>\n"
313             + LOG_TITLE_FUNCTION
314             + "  log('mutationEvent' in window);\n"
315             + "  log(window.mutationEvent);\n"
316             + "  try { log(mutationEvent); } catch(e) { logEx(e); };\n"
317             + "  try { log(mutationEvent.prototype); } catch(e) { logEx(e); };\n"
318             + "  try { log(mutationEvent.__proto__); } catch(e) { logEx(e); };\n"
319 
320             + "  log('MutationEvent' in window);\n"
321             + "  log(window.MutationEvent);\n"
322             + "  try { log(MutationEvent); } catch(e) { logEx(e); };\n"
323             + "  try { log(MutationEvent.prototype); } catch(e) { logEx(e); };\n"
324             + "  try { log(MutationEvent.__proto__); } catch(e) { logEx(e); };\n"
325             + "</script>\n"
326             + "</body></html>";
327 
328         loadPageVerifyTitle2(html);
329     }
330 }