1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host.worker;
16
17 import java.net.URL;
18
19 import org.htmlunit.WebDriverTestCase;
20 import org.htmlunit.junit.annotation.Alerts;
21 import org.htmlunit.util.MimeType;
22 import org.junit.jupiter.api.Test;
23 import org.openqa.selenium.WebDriver;
24
25
26
27
28
29
30
31 public class WorkerTest extends WebDriverTestCase {
32
33
34
35
36 @Test
37 @Alerts("Received:worker loaded")
38 public void postMessageFromWorker() throws Exception {
39 final String html = DOCTYPE_HTML
40 + "<html><body>\n"
41 + "<script async>\n"
42 + LOG_TITLE_FUNCTION
43 + "try {\n"
44 + " var myWorker = new Worker('worker.js');\n"
45 + " myWorker.onmessage = function(e) {\n"
46 + " log('Received:' + e.data);\n"
47 + " };\n"
48 + "} catch(e) { logEx(e); }\n"
49 + "</script></body></html>\n";
50
51 final String workerJs = "postMessage('worker loaded');\n";
52
53 getMockWebConnection().setResponse(new URL(URL_FIRST, "worker.js"), workerJs, MimeType.TEXT_JAVASCRIPT);
54
55 loadPage2(html);
56 verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
57 }
58
59
60
61
62 @Test
63 @Alerts("Received:worker loaded")
64 public void postMessageFromWorker2() throws Exception {
65 final String html = DOCTYPE_HTML
66 + "<html><body>\n"
67 + "<script async>\n"
68 + LOG_TITLE_FUNCTION
69 + "try {\n"
70 + " var myWorker = new Worker('worker.js');\n"
71 + " myWorker.addEventListener('message', (e) => {\n"
72 + " log('Received:' + e.data);\n"
73 + " });\n"
74 + "} catch(e) { logEx(e); }\n"
75 + "</script></body></html>\n";
76
77 final String workerJs = "postMessage('worker loaded');\n";
78
79 getMockWebConnection().setResponse(new URL(URL_FIRST, "worker.js"), workerJs, MimeType.TEXT_JAVASCRIPT);
80
81 loadPage2(html);
82 verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
83 }
84
85
86
87
88 @Test
89 @Alerts("Received: Result = 15")
90 public void postMessageToWorker() throws Exception {
91 final String html = DOCTYPE_HTML
92 + "<html><body><script>\n"
93 + LOG_TITLE_FUNCTION
94 + "try {\n"
95 + " var myWorker = new Worker('worker.js');\n"
96 + " myWorker.onmessage = function(e) {\n"
97 + " log('Received: ' + e.data);\n"
98 + " };\n"
99 + " setTimeout(function() { myWorker.postMessage([5, 3]);}, 10);\n"
100 + "} catch(e) { logEx(e); }\n"
101 + "</script></body></html>\n";
102
103 final String workerJs = "onmessage = function(e) {\n"
104 + " var workerResult = 'Result = ' + (e.data[0] * e.data[1]);\n"
105 + " postMessage(workerResult);\n"
106 + "}\n";
107
108 getMockWebConnection().setResponse(new URL(URL_FIRST, "worker.js"), workerJs, MimeType.TEXT_JAVASCRIPT);
109
110 loadPage2(html);
111 verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
112 }
113
114
115
116
117 @Test
118 @Alerts("start worker in imported script1 in imported script2 end worker")
119 public void importScripts() throws Exception {
120 final String html = DOCTYPE_HTML
121 + "<html><body><script>\n"
122 + "try {\n"
123 + " var myWorker = new Worker('worker.js');\n"
124 + " myWorker.onmessage = function(e) {\n"
125 + " document.title += e.data;\n"
126 + " };\n"
127 + "} catch(e) { document.title += ' exception'; }\n"
128 + "</script></body></html>\n";
129
130 final String workerJs = "postMessage('start worker');\n"
131 + "importScripts('scriptToImport1.js', 'scriptToImport2.js');\n"
132 + "postMessage(' end worker');\n";
133
134 final String scriptToImportJs1 = "postMessage(' in imported script1');\n";
135 final String scriptToImportJs2 = "postMessage(' in imported script2');\n";
136
137 getMockWebConnection().setResponse(new URL(URL_FIRST, "worker.js"), workerJs, MimeType.TEXT_JAVASCRIPT);
138 getMockWebConnection().setResponse(new URL(URL_FIRST, "scriptToImport1.js"), scriptToImportJs1,
139 MimeType.TEXT_JAVASCRIPT);
140 getMockWebConnection().setResponse(new URL(URL_FIRST, "scriptToImport2.js"), scriptToImportJs2,
141 MimeType.TEXT_JAVASCRIPT);
142
143 final WebDriver driver = loadPage2(html);
144 assertTitle(driver, getExpectedAlerts()[0]);
145 }
146
147
148
149
150 @Test
151 @Alerts("start worker import exception end worker")
152 public void importScriptsWrongContentType() throws Exception {
153 importScripts(MimeType.TEXT_HTML);
154 }
155
156
157
158
159 @Test
160 @Alerts("start worker in imported script1 end worker")
161 public void importScriptsContentType() throws Exception {
162 importScripts("application/ecmascript");
163 importScripts("application/javascript");
164 importScripts("application/x-ecmascript");
165 importScripts("application/x-javascript");
166 importScripts(MimeType.TEXT_JAVASCRIPT);
167 importScripts("text/javascript");
168 importScripts("text/javascript1.0");
169 importScripts("text/javascript1.1");
170 importScripts("text/javascript1.2");
171 importScripts("text/javascript1.3");
172 importScripts("text/javascript1.4");
173 importScripts("text/javascript1.5");
174 importScripts("text/jscript");
175 importScripts("text/livescript");
176 importScripts("text/x-ecmascript");
177 importScripts("text/x-javascript");
178 }
179
180 private void importScripts(final String contentType) throws Exception {
181 final String html = DOCTYPE_HTML
182 + "<html><body><script>\n"
183 + "try {\n"
184 + " var myWorker = new Worker('worker.js');\n"
185 + " myWorker.onmessage = function(e) {\n"
186 + " document.title += e.data;\n"
187 + " };\n"
188 + "} catch(e) { document.title += ' exception'; }\n"
189 + "</script></body></html>\n";
190
191 final String workerJs = "postMessage('start worker');\n"
192 + "try {\n"
193 + " importScripts('scriptToImport1.js');\n"
194 + "} catch(e) { postMessage(' import exception'); }\n"
195 + "postMessage(' end worker');\n";
196
197 final String scriptToImportJs1 = "postMessage(' in imported script1');\n";
198
199 getMockWebConnection().setResponse(new URL(URL_FIRST, "worker.js"), workerJs, MimeType.TEXT_JAVASCRIPT);
200 getMockWebConnection().setResponse(new URL(URL_FIRST, "scriptToImport1.js"), scriptToImportJs1,
201 contentType);
202
203 final WebDriver driver = loadPage2(html);
204 assertTitle(driver, getExpectedAlerts()[0]);
205 }
206
207
208
209
210 @Test
211 @Alerts("[object DedicatedWorkerGlobalScope] [object DedicatedWorkerGlobalScope] true")
212 public void thisAndSelf() throws Exception {
213 final String html = DOCTYPE_HTML
214 + "<html><body><script>\n"
215 + "try {\n"
216 + " var myWorker = new Worker('worker.js');\n"
217 + " myWorker.onmessage = function(e) {\n"
218 + " document.title += e.data;\n"
219 + " };\n"
220 + "} catch(e) { document.tilte += ' exception'; }\n"
221 + "</script></body></html>\n";
222
223 final String workerJs = "postMessage(' ' + this);\n"
224 + "postMessage(' ' + self);\n"
225 + "postMessage(' ' + (this == self));\n";
226
227 getMockWebConnection().setResponse(new URL(URL_FIRST, "worker.js"), workerJs, MimeType.TEXT_JAVASCRIPT);
228
229 final WebDriver driver = loadPage2(html);
230 assertTitle(driver, getExpectedAlerts()[0]);
231 }
232
233
234
235
236 @Test
237 @Alerts("TypeError")
238 public void createFromPrototypeAndDefineProperty() throws Exception {
239 final String html = DOCTYPE_HTML
240 + "<html><body><script>\n"
241 + LOG_TITLE_FUNCTION
242 + "var f = function() {};\n"
243 + "f.prototype = Object.create(window.Worker.prototype);\n"
244 + "try {\n"
245 + " f.prototype['onmessage'] = function() {};\n"
246 + " log('no exception');\n"
247 + "} catch(e) { logEx(e); }\n"
248 + "</script></body></html>";
249
250 loadPageVerifyTitle2(html);
251 }
252
253
254
255
256 @Test
257 @Alerts("function")
258 public void onmessageFunction() throws Exception {
259 final String html = DOCTYPE_HTML
260 + "<html><body><script>\n"
261 + LOG_TITLE_FUNCTION
262 + " var myWorker = new Worker('worker.js');\n"
263 + " myWorker.onmessage = function(e) {};\n"
264 + " log(typeof myWorker.onmessage);\n"
265 + "</script></body></html>\n";
266 getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
267
268 loadPageVerifyTitle2(html);
269 }
270
271
272
273
274 @Test
275 @Alerts("null")
276 public void onmessageNumber() throws Exception {
277 final String html = DOCTYPE_HTML
278 + "<html><body><script>\n"
279 + LOG_TITLE_FUNCTION
280 + " var myWorker = new Worker('worker.js');\n"
281 + " try {\n"
282 + " myWorker.onmessage = 17;\n"
283 + " log(myWorker.onmessage);\n"
284 + " } catch(e) { log('exception ' + e.name); }\n"
285 + "</script></body></html>\n";
286 getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
287
288 loadPageVerifyTitle2(html);
289 }
290
291
292
293
294 @Test
295 @Alerts("null")
296 public void onmessageString() throws Exception {
297 final String html = "<html><body><script>\n"
298 + LOG_TITLE_FUNCTION
299 + " var myWorker = new Worker('worker.js');\n"
300 + " try {\n"
301 + " myWorker.onmessage = 'HtmlUnit';\n"
302 + " log(myWorker.onmessage);\n"
303 + " } catch(e) { log('exception ' + e.name); }\n"
304 + "</script></body></html>\n";
305 getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
306
307 loadPageVerifyTitle2(html);
308 }
309
310
311
312
313 @Test
314 @Alerts({"SGVsbG8gV29ybGQh", "Hello\\sWorld!"})
315 public void atob() throws Exception {
316 final String workerJs
317 = " var data = btoa('Hello World!');\n"
318 + " postMessage(data);\n"
319 + " postMessage(atob(data));\n";
320 testJs(workerJs);
321 }
322
323
324
325
326 @Test
327 @Alerts({"exception", "exception"})
328 public void atobUnicode() throws Exception {
329 final String workerJs
330 = " try {\n"
331 + " btoa('I \\u2661 Unicode!');\n"
332 + " } catch(e) {postMessage('exception')}\n"
333 + " try {\n"
334 + " atob('I \\u2661 Unicode!');\n"
335 + " } catch(e) {postMessage('exception')}\n";
336 testJs(workerJs);
337 }
338
339
340
341
342 @Test
343 @Alerts({"M8OuwqY=", "3\u00C3\u00AE\u00C2\u00A6"})
344 public void atobUnicodeOutput() throws Exception {
345 final String workerJs
346 = " var data = btoa('3\u00C3\u00AE\u00C2\u00A6');\n"
347 + " postMessage(data);\n"
348 + " postMessage(atob(data));\n";
349 testJs(workerJs);
350 }
351
352
353
354
355 @Test
356 @Alerts({"CSAe", "\\t\\s\\u001e"})
357 public void atobControlChar() throws Exception {
358 final String workerJs
359 = " var data = btoa('\\t \\u001e');\n"
360 + " postMessage(data);\n"
361 + " postMessage(atob(data));\n";
362 testJs(workerJs);
363 }
364
365
366
367
368 @Test
369 @Alerts({"bnVsbA==", "null"})
370 public void atobNull() throws Exception {
371 final String workerJs
372 = " var data = btoa(null);\n"
373 + " postMessage(data);\n"
374 + " postMessage(atob(data));\n";
375 testJs(workerJs);
376 }
377
378
379
380
381 @Test
382 @Alerts({"dW5kZWZpbmVk", "undefined"})
383 public void atobUndefined() throws Exception {
384 final String workerJs
385 = " var data = btoa(undefined);\n"
386 + " postMessage(data);\n"
387 + " postMessage(atob(data));\n";
388 testJs(workerJs);
389 }
390
391
392
393
394 @Test
395 @Alerts({"object", "true"})
396 public void globalThis() throws Exception {
397 final String workerJs
398 = " try {\n"
399 + " postMessage(typeof globalThis);\n"
400 + " postMessage(self === globalThis);\n"
401 + " } catch(e) { postMessage('globalThis is undefined'); }";
402 testJs(workerJs);
403 }
404
405 private void testJs(final String workerJs) throws Exception {
406 final String html = DOCTYPE_HTML
407 + "<html><body>\n"
408 + "<script async>\n"
409 + LOG_TITLE_FUNCTION_NORMALIZE
410 + "try {\n"
411 + " var myWorker = new Worker('worker.js');\n"
412 + " myWorker.onmessage = function(e) {\n"
413 + " log(e.data);\n"
414 + " };\n"
415 + "} catch(e) { logEx(e); }\n"
416 + "</script></body></html>\n";
417
418 getMockWebConnection().setResponse(new URL(URL_FIRST, "worker.js"), workerJs, MimeType.TEXT_JAVASCRIPT);
419
420 loadPage2(html);
421 verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
422 }
423
424
425
426
427 @Test
428 @Alerts(DEFAULT = "Received:worker loaded",
429 FF = {},
430 FF_ESR = {})
431 public void workerCodeWithWrongMimeType() throws Exception {
432 final String html = DOCTYPE_HTML
433 + "<html><body>\n"
434 + "<script async>\n"
435 + LOG_TITLE_FUNCTION
436 + "try {\n"
437 + " var myWorker = new Worker('worker.js');\n"
438 + " myWorker.onmessage = function(e) {\n"
439 + " log('Received:' + e.data);\n"
440 + " };\n"
441 + "} catch(e) { logEx(e); }\n"
442 + "</script></body></html>\n";
443
444 final String workerJs = "postMessage('worker loaded');\n";
445
446 getMockWebConnection().setResponse(new URL(URL_FIRST, "worker.js"), workerJs, MimeType.TEXT_HTML);
447
448 loadPage2(html);
449 verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
450 }
451 }