1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host;
16
17 import org.htmlunit.WebDriverTestCase;
18 import org.htmlunit.junit.annotation.Alerts;
19 import org.htmlunit.junit.annotation.HtmlUnitNYI;
20 import org.junit.jupiter.api.Test;
21 import org.openqa.selenium.WebDriver;
22 import org.openqa.selenium.WindowType;
23
24
25
26
27
28
29 public class BroadcastChannelTest extends WebDriverTestCase {
30
31
32
33
34 @Test
35 @Alerts({"channel1", "i got [object MessageEvent]", "i got data Hello from main page!",
36 "i got origin http://localhost:22222", "i got lastEventId ",
37 "i got source null", "i got ports ",
38 "got [object MessageEvent]", "got data post: Response from iframe",
39 "got origin http://localhost:22222", "got lastEventId ", "got source null", "got ports "})
40 public void basicBroadcastTest() throws Exception {
41 final String html = DOCTYPE_HTML
42 + "<html><body>\n"
43 + "<iframe src='" + URL_SECOND + "'></iframe>\n"
44 + "<script>\n"
45 + LOG_SESSION_STORAGE_FUNCTION
46 + " var bc = new BroadcastChannel('channel1');\n"
47 + " log(bc.name);\n"
48 + " var ifr = document.querySelector('iframe');\n"
49 + " function iframeLoaded() {\n"
50 + " bc.postMessage('Hello from main page!');\n"
51 + " }\n"
52 + " ifr.addEventListener('load', iframeLoaded, false);\n"
53 + " bc.onmessage = function(e) {\n"
54 + " log('got ' + e);\n"
55 + " log('got data ' + e.data);\n"
56 + " log('got origin ' + e.origin);\n"
57 + " log('got lastEventId ' + e.lastEventId);\n"
58 + " log('got source ' + e.source);\n"
59 + " log('got ports ' + e.ports);\n"
60 + " };\n"
61 + "</script>\n"
62 + "</body></html>";
63
64 final String html2 = DOCTYPE_HTML
65 + "<html><body>\n"
66 + "<script>\n"
67 + LOG_SESSION_STORAGE_FUNCTION
68 + " var bc = new BroadcastChannel('channel1');\n"
69 + " bc.onmessage = function(e) {\n"
70 + " log('i got ' + e);\n"
71 + " log('i got data ' + e.data);\n"
72 + " log('i got origin ' + e.origin);\n"
73 + " log('i got lastEventId ' + e.lastEventId);\n"
74 + " log('i got source ' + e.source);\n"
75 + " log('i got ports ' + e.ports);\n"
76 + " bc.postMessage('post: Response from iframe');\n"
77 + " };\n"
78 + "</script>\n"
79 + "</body></html>";
80
81 getMockWebConnection().setResponse(URL_SECOND, html2);
82
83 final WebDriver driver = loadPage2(html);
84 verifySessionStorage2(driver, getExpectedAlerts());
85
86 shutDownAll();
87 }
88
89
90
91
92 @Test
93 @Alerts({"channel1", "channel2", "bc1: Message for channel1", "bc2: Message for channel2"})
94 public void differentChannelsTest() throws Exception {
95 final String html = DOCTYPE_HTML
96 + "<html><body>\n"
97 + "<iframe src='" + URL_SECOND + "'></iframe>\n"
98 + "<script>\n"
99 + LOG_SESSION_STORAGE_FUNCTION
100 + " var bc1 = new BroadcastChannel('channel1');\n"
101 + " log(bc1.name);\n"
102
103 + " var bc2 = new BroadcastChannel('channel2');\n"
104 + " log(bc2.name);\n"
105
106 + " bc1.onmessage = function(e) {\n"
107 + " log('bc1: ' + e.data);\n"
108 + " };\n"
109 + " bc2.onmessage = function(e) {\n"
110 + " log('bc2: ' + e.data);\n"
111 + " };\n"
112 + "</script>\n"
113 + "</body></html>";
114
115 final String html2 = DOCTYPE_HTML
116 + "<html><body>\n"
117 + "<script>\n"
118 + LOG_SESSION_STORAGE_FUNCTION
119 + " var bc1 = new BroadcastChannel('channel1');\n"
120 + " bc1.postMessage('Message for channel1');\n"
121
122 + " var bc2 = new BroadcastChannel('channel2');\n"
123 + " bc2.postMessage('Message for channel2');\n"
124
125 + " var bc3 = new BroadcastChannel('channel3');\n"
126 + " bc3.postMessage('Message for channel3');\n"
127 + "</script>\n"
128 + "</body></html>";
129
130 getMockWebConnection().setResponse(URL_SECOND, html2);
131
132 final WebDriver driver = loadPage2(html);
133 verifySessionStorage2(driver, getExpectedAlerts());
134
135 shutDownAll();
136 }
137
138
139
140
141 @Test
142 @Alerts({"Trigger close()", "postMessage() done", "done"})
143 public void closeChannelTest() throws Exception {
144 final String html = DOCTYPE_HTML
145 + "<html><body>\n"
146 + "<iframe src='" + URL_SECOND + "'></iframe>\n"
147 + "<script>\n"
148 + LOG_SESSION_STORAGE_FUNCTION
149 + " var bc = new BroadcastChannel('test');\n"
150 + " var ifr = document.querySelector('iframe');\n"
151 + " bc.onmessage = function(e) {\n"
152 + " log(e.data);\n"
153 + " bc.close();\n"
154 + " };\n"
155 + "</script>\n"
156 + "</body></html>";
157
158 final String html2 = DOCTYPE_HTML
159 + "<html><body>\n"
160 + "<script>\n"
161 + LOG_SESSION_STORAGE_FUNCTION
162 + " var bc = new BroadcastChannel('test');\n"
163 + " // This message should not be received after close\n"
164 + " bc.postMessage('Trigger close()');\n"
165 + " setTimeout(function() {\n"
166 + " bc.postMessage('Should not receive this');\n"
167 + " log('postMessage() done');\n"
168 + " }, 50);\n"
169 + " setTimeout(function() {\n"
170 + " log('done');\n"
171 + " }, 100);\n"
172 + "</script>\n"
173 + "</body></html>";
174
175 getMockWebConnection().setResponse(URL_SECOND, html2);
176
177 final WebDriver driver = loadPage2(html);
178 Thread.sleep(DEFAULT_WAIT_TIME.dividedBy(2).toMillis());
179 verifySessionStorage2(driver, getExpectedAlerts());
180
181 shutDownAll();
182 }
183
184
185
186
187 @Test
188 @Alerts("cross-origin")
189 public void sameOrigin() throws Exception {
190 final String html = DOCTYPE_HTML
191 + "<html><head><script>\n"
192 + LOG_TITLE_FUNCTION
193 + " var bc = new BroadcastChannel('test');\n"
194 + " bc.onmessage = function(e) {\n"
195 + " log(e.data);\n"
196 + " };\n"
197 + "</script>\n"
198 + "</head>\n"
199 + "<body></body>\n"
200 + "</html>";
201
202 final String html2 = DOCTYPE_HTML
203 + "<html><body>\n"
204 + "<script>\n"
205 + " var bc = new BroadcastChannel('test');\n"
206 + " bc.postMessage('cross-origin');\n"
207 + "</script>\n"
208 + "</body></html>";
209
210 getMockWebConnection().setResponse(URL_SECOND, html2);
211
212 final WebDriver driver = loadPage2(html);
213 final Object[] windowHandles = driver.getWindowHandles().toArray();
214 driver.switchTo().newWindow(WindowType.TAB);
215 driver.get(URL_SECOND.toExternalForm());
216 driver.close();
217 driver.switchTo().window((String) windowHandles[0]);
218
219 verifyTitle2(driver, getExpectedAlerts());
220
221 shutDownAll();
222 }
223
224
225
226
227 @Test
228 @Alerts({})
229 public void crossOrigin() throws Exception {
230 final String html = DOCTYPE_HTML
231 + "<html><head>\n"
232 + "<script>\n"
233 + LOG_TITLE_FUNCTION
234 + " var bc = new BroadcastChannel('test');\n"
235 + " bc.onmessage = function(e) {\n"
236 + " log(e.data);\n"
237 + " };\n"
238 + "</script>\n"
239 + "</head>\n"
240 + "<body></body>\n"
241 + "</html>";
242
243 final String html2 = DOCTYPE_HTML
244 + "<html><body>\n"
245 + "<script>\n"
246 + " var bc = new BroadcastChannel('test');\n"
247 + " bc.postMessage('cross-origin');\n"
248 + "</script>\n"
249 + "</body></html>";
250
251 getMockWebConnection().setResponse(URL_THIRD, html2);
252
253 final WebDriver driver = loadPage2(html);
254 final Object[] windowHandles = driver.getWindowHandles().toArray();
255 driver.switchTo().newWindow(WindowType.TAB);
256 driver.get(URL_THIRD.toExternalForm());
257 driver.close();
258 driver.switchTo().window((String) windowHandles[0]);
259
260 verifyTitle2(driver, getExpectedAlerts());
261
262 shutDownAll();
263 }
264
265
266
267
268 @Test
269 @Alerts("postMessage done")
270 public void noSelfMessageTest() throws Exception {
271 final String html = DOCTYPE_HTML
272 + "<html><body>\n"
273 + "<script>\n"
274 + LOG_TITLE_FUNCTION
275 + " var bc = new BroadcastChannel('selftest');\n"
276 + " bc.onmessage = function(e) {\n"
277 + " log('received: ' + e.data);\n"
278 + " };\n"
279 + " bc.postMessage('self message');\n"
280 + " log('postMessage done');\n"
281 + "</script>\n"
282 + "</body></html>";
283
284 loadPageVerifyTitle2(html);
285 }
286
287
288
289
290 @Test
291 @Alerts("null")
292 public void constructorWithNullTest() throws Exception {
293 final String html = DOCTYPE_HTML
294 + "<html><body>\n"
295 + "<script>\n"
296 + LOG_TITLE_FUNCTION
297 + " try {\n"
298 + " var bc = new BroadcastChannel(null);\n"
299 + " log(bc.name);\n"
300 + " } catch (e) { logEx(e); }\n"
301 + "</script>\n"
302 + "</body></html>";
303
304 loadPageVerifyTitle2(html);
305 }
306
307
308
309
310 @Test
311 @Alerts("undefined")
312 @HtmlUnitNYI(CHROME = "TypeError",
313 EDGE = "TypeError",
314 FF = "TypeError",
315 FF_ESR = "TypeError")
316 public void constructorWithUndefinedTest() throws Exception {
317 final String html = DOCTYPE_HTML
318 + "<html><body>\n"
319 + "<script>\n"
320 + LOG_TITLE_FUNCTION
321 + " try {\n"
322 + " var bc = new BroadcastChannel(undefined);\n"
323 + " log(bc.name);\n"
324 + " } catch (e) { logEx(e); }\n"
325 + "</script>\n"
326 + "</body></html>";
327
328 loadPageVerifyTitle2(html);
329 }
330
331
332
333
334 @Test
335 @Alerts("")
336 public void constructorWithEmptyStringTest() throws Exception {
337 final String html = DOCTYPE_HTML
338 + "<html><body>\n"
339 + "<script>\n"
340 + LOG_TITLE_FUNCTION
341 + " try {\n"
342 + " var bc = new BroadcastChannel('');\n"
343 + " log(bc.name);\n"
344 + " } catch (e) { logEx(e); }\n"
345 + "</script>\n"
346 + "</body></html>";
347
348 loadPageVerifyTitle2(html);
349 }
350
351
352
353
354 @Test
355 @Alerts("\\s\\sa\\sb\\s\\sc\\texu\\s\\s\\s\\s\\t\\s")
356 public void constructorWithStringWhitespaceTest() throws Exception {
357 final String html = DOCTYPE_HTML
358 + "<html><body>\n"
359 + "<script>\n"
360 + LOG_TITLE_FUNCTION_NORMALIZE
361 + " try {\n"
362 + " var bc = new BroadcastChannel(' a b c\texu \t ');\n"
363 + " log(bc.name);\n"
364 + " } catch (e) { logEx(e); }\n"
365 + "</script>\n"
366 + "</body></html>";
367
368 loadPageVerifyTitle2(html);
369 }
370
371
372
373
374 @Test
375 @Alerts("123")
376 public void constructorWithNumberTest() throws Exception {
377 final String html = DOCTYPE_HTML
378 + "<html><body>\n"
379 + "<script>\n"
380 + LOG_TITLE_FUNCTION
381 + " try {\n"
382 + " var bc = new BroadcastChannel(123);\n"
383 + " log(bc.name);\n"
384 + " } catch (e) { logEx(e); }\n"
385 + "</script>\n"
386 + "</body></html>";
387
388 loadPageVerifyTitle2(html);
389 }
390
391
392
393
394 @Test
395 @Alerts("custom")
396 public void constructorWithObjectTest() throws Exception {
397 final String html = DOCTYPE_HTML
398 + "<html><body>\n"
399 + "<script>\n"
400 + LOG_TITLE_FUNCTION
401 + " try {\n"
402 + " var bc = new BroadcastChannel({toString: function() { return 'custom'; }});\n"
403 + " log(bc.name);\n"
404 + " } catch (e) { logEx(e); }\n"
405 + "</script>\n"
406 + "</body></html>";
407
408 loadPageVerifyTitle2(html);
409 }
410
411
412
413
414 @Test
415 @Alerts("special!@#$%^&*()_+-=[]{}|;':\",./<>?`~")
416 public void constructorWithSpecialCharactersTest() throws Exception {
417 final String html = DOCTYPE_HTML
418 + "<html><body>\n"
419 + "<script>\n"
420 + LOG_TITLE_FUNCTION
421 + " try {\n"
422 + " var bc = new BroadcastChannel('special!@#$%^&*()_+-=[]{}|;\\':\\\",./<>?`~');\n"
423 + " log(bc.name);\n"
424 + " } catch (e) { logEx(e); }\n"
425 + "</script>\n"
426 + "</body></html>";
427
428 loadPageVerifyTitle2(html);
429 }
430
431
432
433
434 @Test
435 @Alerts("TypeError")
436 public void constructorWithNoArgumentsTest() throws Exception {
437 final String html = DOCTYPE_HTML
438 + "<html><body>\n"
439 + "<script>\n"
440 + LOG_TITLE_FUNCTION
441 + " try {\n"
442 + " var bc = new BroadcastChannel();\n"
443 + " log('success: ' + bc.name);\n"
444 + " } catch (e) { logEx(e); }\n"
445 + "</script>\n"
446 + "</body></html>";
447
448 loadPageVerifyTitle2(html);
449 }
450
451
452
453
454 @Test
455 @Alerts("message received")
456 public void constructorWithWhitespaceChannelsTest() throws Exception {
457 final String html = DOCTYPE_HTML
458 + "<html><body>\n"
459 + "<iframe src='" + URL_SECOND + "'></iframe>\n"
460 + "<script>\n"
461 + LOG_TITLE_FUNCTION
462 + " var bc = new BroadcastChannel(' spaced ');\n"
463 + " var ifr = document.querySelector('iframe');\n"
464 + " function iframeLoaded() {\n"
465 + " bc.postMessage('test message');\n"
466 + " }\n"
467 + " ifr.addEventListener('load', iframeLoaded, false);\n"
468 + " bc.onmessage = function(e) {\n"
469 + " log('message received');\n"
470 + " };\n"
471 + "</script>\n"
472 + "</body></html>";
473
474 final String html2 = DOCTYPE_HTML
475 + "<html><body>\n"
476 + "<script>\n"
477 + " var bc = new BroadcastChannel(' spaced ');\n"
478 + " bc.onmessage = function(e) {\n"
479 + " bc.postMessage('response');\n"
480 + " };\n"
481 + "</script>\n"
482 + "</body></html>";
483
484 getMockWebConnection().setResponse(URL_SECOND, html2);
485 loadPageVerifyTitle2(html);
486 }
487 }