1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host;
16
17 import static java.nio.charset.StandardCharsets.UTF_16LE;
18
19 import java.io.IOException;
20 import java.nio.ByteBuffer;
21 import java.util.Set;
22 import java.util.concurrent.CopyOnWriteArraySet;
23
24 import org.eclipse.jetty.websocket.api.Session;
25 import org.eclipse.jetty.websocket.api.WebSocketAdapter;
26 import org.eclipse.jetty.websocket.server.WebSocketHandler;
27 import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
28 import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
29 import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
30 import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
31 import org.htmlunit.HttpHeader;
32 import org.htmlunit.WebDriverTestCase;
33 import org.htmlunit.junit.annotation.Alerts;
34 import org.htmlunit.junit.annotation.HtmlUnitNYI;
35 import org.junit.jupiter.api.AfterEach;
36 import org.junit.jupiter.api.Test;
37 import org.openqa.selenium.By;
38 import org.openqa.selenium.WebDriver;
39 import org.openqa.selenium.WebElement;
40
41
42
43
44
45
46
47
48 public class WebSocketTest extends WebDriverTestCase {
49
50
51
52
53 @Test
54 @Alerts({"§§URL§§", "", "blob"})
55 public void initialNoServerAvailable() throws Exception {
56 final String html = DOCTYPE_HTML
57 + "<html>\n"
58 + "<head>\n"
59 + "<script>\n"
60 + LOG_TITLE_FUNCTION
61 + " function test() {\n"
62 + " var location = 'ws://localhost:" + PORT2 + "/';\n"
63 + " var ws = new WebSocket(location);\n"
64 + " log(ws.url);\n"
65 + " log(ws.protocol);\n"
66
67
68
69 + " log(ws.binaryType);\n"
70 + " }\n"
71 + "</script>\n"
72 + "</head>\n"
73 + "<body onload='test()'>\n"
74 + "</body></html>";
75
76 expandExpectedAlertsVariables("ws://localhost:" + PORT2 + "/");
77 final WebDriver driver = loadPage2(html);
78 verifyTitle2(DEFAULT_WAIT_TIME, driver, getExpectedAlerts());
79 }
80
81
82
83
84 @Test
85 @Alerts({"[object WebSocket]", "§§URL§§"})
86 public void earlyConstruction() throws Exception {
87 final String html = DOCTYPE_HTML
88 + "<html><head><script>\n"
89 + LOG_TITLE_FUNCTION
90 + " function test() {\n"
91 + " var location = 'ws://localhost:" + PORT + "/';\n"
92 + " var ws = new WebSocket(location);\n"
93 + " log(ws);\n"
94 + " log(ws.url);\n"
95 + " }\n"
96 + " test();\n"
97 + "</script>\n"
98 + "</head>\n"
99 + "<body>\n"
100 + "</body></html>";
101
102 expandExpectedAlertsVariables("ws://localhost:" + PORT + "/");
103 final WebDriver driver = loadPage2(html);
104 verifyTitle2(DEFAULT_WAIT_TIME, driver, getExpectedAlerts());
105 }
106
107
108
109
110 @Test
111 @Alerts(DEFAULT = {"exception no param", "ws://localhost:22222/undefined", "ws://localhost:22222/null",
112 "ws://localhost:22222/", "ws://localhost:22222/", "exception invalid"},
113 FF = {"exception no param", "ws://localhost:22222/undefined", "ws://localhost:22222/null",
114 "exception empty", "ws://localhost:22222/", "exception invalid"},
115 FF_ESR = {"exception no param", "ws://localhost:22222/undefined", "ws://localhost:22222/null",
116 "exception empty", "ws://localhost:22222/", "exception invalid"})
117 @HtmlUnitNYI(
118 CHROME = {"exception no param", "ws://localhost:22222/undefined", "ws://localhost:22222/null",
119 "ws://localhost:22222/", "ws://localhost:22222/", "ws://localhost:22222/#"},
120 EDGE = {"exception no param", "ws://localhost:22222/undefined", "ws://localhost:22222/null",
121 "ws://localhost:22222/", "ws://localhost:22222/", "ws://localhost:22222/#"},
122 FF = {"exception no param", "ws://localhost:22222/undefined", "ws://localhost:22222/null",
123 "ws://localhost:22222/", "ws://localhost:22222/", "ws://localhost:22222/#"},
124 FF_ESR = {"exception no param", "ws://localhost:22222/undefined", "ws://localhost:22222/null",
125 "ws://localhost:22222/", "ws://localhost:22222/", "ws://localhost:22222/#"})
126 public void initialWithoutUrl() throws Exception {
127 final String html = DOCTYPE_HTML
128 + "<html><head><script>\n"
129 + LOG_TITLE_FUNCTION
130 + " function test() {\n"
131 + " try {\n"
132 + " let ws = new WebSocket();\n"
133 + " log(ws.url);"
134 + " } catch(e) { log('exception no param') }\n"
135
136 + " try {\n"
137 + " let ws = new WebSocket(undefined);\n"
138 + " log(ws.url);"
139 + " } catch(e) { log('exception undefined') }\n"
140
141 + " try {\n"
142 + " let ws = new WebSocket(null);\n"
143 + " log(ws.url);"
144 + " } catch(e) { log('exception null') }\n"
145
146 + " try {\n"
147 + " let ws = new WebSocket('');\n"
148 + " log(ws.url);"
149 + " } catch(e) { log('exception empty') }\n"
150
151 + " try {\n"
152 + " let ws = new WebSocket(' ');\n"
153 + " log(ws.url);"
154 + " } catch(e) { log('exception blank') }\n"
155
156 + " try {\n"
157 + " let ws = new WebSocket('#');\n"
158 + " log(ws.url);"
159 + " } catch(e) { log('exception invalid') }\n"
160 + " }\n"
161 + "</script></head><body onload='test()'>\n"
162 + "</body></html>";
163
164 loadPageVerifyTitle2(html);
165 }
166
167
168
169
170 @Test
171 @Alerts({"blob", "blob", "arraybuffer", "blob", "blob"})
172 public void binaryType() throws Exception {
173 final String html = DOCTYPE_HTML
174 + "<html><head><script>\n"
175 + LOG_TITLE_FUNCTION
176 + " function test() {\n"
177 + " var location = 'ws://localhost:" + PORT + "/';\n"
178 + " var ws = new WebSocket(location);\n"
179 + " log(ws.binaryType);\n"
180
181 + " try {\n"
182 + " ws.binaryType = 'abc';\n"
183 + " log(ws.binaryType);\n"
184 + " } catch(e) { logEx(e) }\n"
185
186 + " try {\n"
187 + " ws.binaryType = 'arraybuffer';\n"
188 + " log(ws.binaryType);\n"
189 + " } catch(e) { logEx(e) }\n"
190
191 + " try {\n"
192 + " ws.binaryType = 'blob';\n"
193 + " log(ws.binaryType);\n"
194 + " } catch(e) { logEx(e) }\n"
195
196 + " try {\n"
197 + " ws.binaryType = '';\n"
198 + " log(ws.binaryType);\n"
199 + " } catch(e) { logEx(e) }\n"
200 + " }\n"
201 + "</script></head><body onload='test()'>\n"
202 + "</body></html>";
203
204 loadPageVerifyTitle2(html);
205 }
206
207
208
209
210
211 @Test
212 public void chat() throws Exception {
213 final String firstResponse = "Browser: has joined!";
214 final String secondResponse = "Browser: Hope you are fine!";
215
216 startWebServer("src/test/resources/org/htmlunit/javascript/host",
217 null, null, new ChatWebSocketHandler());
218 try {
219 final WebDriver driver = getWebDriver();
220 driver.get(URL_FIRST + "WebSocketTest_chat.html");
221
222 driver.findElement(By.id("username")).sendKeys("Browser");
223 driver.findElement(By.id("joinB")).click();
224
225 assertVisible("joined", driver);
226
227 final WebElement chatE = driver.findElement(By.id("chat"));
228 long maxWait = System.currentTimeMillis() + DEFAULT_WAIT_TIME.toMillis();
229
230 do {
231 Thread.sleep(100);
232 }
233 while (chatE.getText().length() <= firstResponse.length() && System.currentTimeMillis() < maxWait);
234
235 assertEquals(firstResponse, chatE.getText());
236
237 driver.findElement(By.id("phrase")).sendKeys("Hope you are fine!");
238 driver.findElement(By.id("sendB")).click();
239
240 maxWait = System.currentTimeMillis() + DEFAULT_WAIT_TIME.toMillis();
241 do {
242 Thread.sleep(100);
243 }
244 while (!chatE.getText().contains(secondResponse) && System.currentTimeMillis() < maxWait);
245
246 assertEquals(firstResponse + "\n" + secondResponse, chatE.getText());
247 }
248 finally {
249 stopWebServers();
250 }
251 }
252
253 private static class ChatWebSocketHandler extends WebSocketHandler {
254
255 private final Set<ChatWebSocket> webSockets_ = new CopyOnWriteArraySet<>();
256
257 ChatWebSocketHandler() {
258 }
259
260 @Override
261 public void configure(final WebSocketServletFactory factory) {
262 factory.register(ChatWebSocket.class);
263 factory.setCreator(new WebSocketCreator() {
264 @Override
265 public Object createWebSocket(final ServletUpgradeRequest servletUpgradeRequest,
266 final ServletUpgradeResponse servletUpgradeResponse) {
267 return new ChatWebSocket();
268 }
269 });
270 }
271
272 private class ChatWebSocket extends WebSocketAdapter {
273 private Session session_;
274
275 ChatWebSocket() {
276 }
277
278 @Override
279 public void onWebSocketConnect(final Session session) {
280 session_ = session;
281 webSockets_.add(this);
282 }
283
284 @Override
285 public void onWebSocketText(final String data) {
286 try {
287 for (final ChatWebSocket webSocket : webSockets_) {
288 webSocket.session_.getRemote().sendString(data);
289 }
290 }
291 catch (final IOException e) {
292 session_.close();
293 }
294 }
295
296 @Override
297 public void onWebSocketClose(final int closeCode, final String message) {
298 webSockets_.remove(this);
299 }
300 }
301 }
302
303
304
305
306 @AfterEach
307 @Override
308 public void releaseResources() {
309 super.releaseResources();
310
311 for (final Thread thread : Thread.getAllStackTraces().keySet()) {
312 if (thread.getName().contains("WebSocket")) {
313 try {
314
315
316 Thread.sleep(400);
317 }
318 catch (final InterruptedException e) {
319 e.printStackTrace();
320 }
321 }
322 }
323
324 String lastFailing = null;
325 for (final java.util.Map.Entry<Thread, StackTraceElement[]> entry : Thread.getAllStackTraces().entrySet()) {
326 final Thread thread = entry.getKey();
327 if (thread.getName().contains("WebSocket")) {
328 lastFailing = thread.getName();
329 System.err.println();
330 System.err.println("WebSocket thread named '" + lastFailing + "' still running");
331 final StackTraceElement[] traces = entry.getValue();
332 for (int i = 0; i < traces.length; i++) {
333 System.err.println(traces[i]);
334 }
335 }
336 }
337
338 assertNull("WebSocket thread named '" + lastFailing + "' still running", lastFailing);
339 }
340
341
342
343
344 @Test
345 @Alerts({": myname=My value!1", ": myname=My value!2"})
346 public void cookies() throws Exception {
347 final String[] expected = getExpectedAlerts();
348
349 startWebServer("src/test/resources/org/htmlunit/javascript/host",
350 null, null, new CookiesWebSocketHandler());
351 try {
352 final WebDriver driver = getWebDriver();
353 driver.get(URL_FIRST + "WebSocketTest_cookies.html");
354
355 driver.findElement(By.id("username")).sendKeys("Browser");
356 driver.findElement(By.id("joinB")).click();
357 final WebElement chatE = driver.findElement(By.id("chat"));
358
359 long maxWait = System.currentTimeMillis() + DEFAULT_WAIT_TIME.toMillis();
360 do {
361 Thread.sleep(100);
362 }
363 while (chatE.getText().length() <= expected[0].length() && System.currentTimeMillis() < maxWait);
364
365 assertEquals(expected[0], chatE.getText());
366
367 driver.findElement(By.id("phrase")).sendKeys("Hope you are fine!");
368 driver.findElement(By.id("sendB")).click();
369
370 maxWait = System.currentTimeMillis() + DEFAULT_WAIT_TIME.toMillis();
371 do {
372 Thread.sleep(100);
373 }
374 while (!chatE.getText().contains(expected[1]) && System.currentTimeMillis() < maxWait);
375
376 assertEquals(expected[0] + "\n" + expected[1], chatE.getText());
377 }
378 finally {
379 stopWebServers();
380 }
381 }
382
383 private static class CookiesWebSocketHandler extends WebSocketHandler {
384
385 private final Set<CookiesWebSocket> webSockets_ = new CopyOnWriteArraySet<>();
386
387 CookiesWebSocketHandler() {
388 }
389
390 @Override
391 public void configure(final WebSocketServletFactory factory) {
392 factory.register(CookiesWebSocket.class);
393 factory.setCreator(new WebSocketCreator() {
394 @Override
395 public Object createWebSocket(final ServletUpgradeRequest servletUpgradeRequest,
396 final ServletUpgradeResponse servletUpgradeResponse) {
397 return new CookiesWebSocket();
398 }
399 });
400 }
401
402 private class CookiesWebSocket extends WebSocketAdapter {
403 private Session session_;
404 private int counter_ = 1;
405
406 CookiesWebSocket() {
407 }
408
409 @Override
410 public void onWebSocketConnect(final Session session) {
411 session_ = session;
412 webSockets_.add(this);
413 }
414
415 @Override
416 public void onWebSocketText(final String data) {
417 try {
418 final String cookie = session_.getUpgradeRequest().getHeaders()
419 .get(HttpHeader.COOKIE).get(0) + counter_++;
420 for (final CookiesWebSocket webSocket : webSockets_) {
421 webSocket.session_.getRemote().sendString(cookie);
422 }
423 }
424 catch (final IOException e) {
425 session_.close();
426 }
427 }
428
429 @Override
430 public void onWebSocketClose(final int closeCode, final String message) {
431 webSockets_.remove(this);
432 }
433 }
434 }
435
436
437
438
439 @Test
440 @Alerts({"onOpenListener",
441 "onOpen", "open", "[object WebSocket]", "[object WebSocket]",
442 "undefined", "undefined", "undefined", "undefined",
443 "onMessageTextListener", "message", "[object WebSocket]", "[object WebSocket]",
444 "server_text", "§§URL§§", "", "null",
445 "onMessageText", "message", "[object WebSocket]", "[object WebSocket]",
446 "server_text", "§§URL§§", "", "null",
447 "onMessageBinaryListener", "message", "[object WebSocket]", "[object WebSocket]",
448 "[object ArrayBuffer]", "§§URL§§", "", "null",
449 "onMessageBinary", "message", "[object WebSocket]", "[object WebSocket]",
450 "[object ArrayBuffer]", "§§URL§§", "", "null",
451 "onCloseListener code: 1000",
452 "onClose code: 1000"})
453 public void events() throws Exception {
454 expandExpectedAlertsVariables("ws://localhost:" + PORT);
455 final String expected = String.join("\n", getExpectedAlerts());
456
457 startWebServer("src/test/resources/org/htmlunit/javascript/host",
458 null, null, new EventsWebSocketHandler());
459 try {
460 final WebDriver driver = getWebDriver();
461 driver.get(URL_FIRST + "WebSocketTest_events.html");
462
463 final WebElement logElement = driver.findElement(By.id("log"));
464 final long maxWait = System.currentTimeMillis() + DEFAULT_WAIT_TIME.toMillis();
465
466 String text;
467 do {
468 Thread.sleep(100);
469
470 text = logElement.getDomProperty("value").trim().replaceAll("\r", "");
471 }
472 while (text.length() <= expected.length() && System.currentTimeMillis() < maxWait);
473
474 assertEquals(expected, text);
475 }
476 finally {
477 stopWebServers();
478 }
479 }
480
481
482
483
484 @Test
485 @Alerts(DEFAULT = {"onOpenListener",
486 "onOpen", "open", "[object WebSocket]", "[object WebSocket]",
487 "undefined", "undefined", "undefined", "undefined",
488 "onMessageTextListener", "message", "[object WebSocket]", "[object WebSocket]",
489 "server_text", "§§URL§§", "", "null",
490 "onMessageText", "message", "[object WebSocket]", "[object WebSocket]",
491 "server_text", "§§URL§§", "", "null",
492 "onMessageBinaryListener", "message", "[object WebSocket]", "[object WebSocket]",
493 "[object ArrayBuffer]", "§§URL§§", "", "null",
494 "onMessageBinary", "message", "[object WebSocket]", "[object WebSocket]",
495 "[object ArrayBuffer]", "§§URL§§", "", "null",
496 "onCloseListener code: 1000 wasClean: true",
497 "onClose code: 1000 wasClean: true"},
498 FF = {"onOpenListener",
499 "onOpen", "open", "[object WebSocket]", "[object WebSocket]",
500 "undefined", "undefined", "undefined", "undefined",
501 "onMessageTextListener", "message", "[object WebSocket]", "[object WebSocket]",
502 "server_text", "§§URL§§", "", "null",
503 "onMessageText", "message", "[object WebSocket]", "[object WebSocket]",
504 "server_text", "§§URL§§", "", "null",
505 "onMessageBinaryListener", "message", "[object WebSocket]", "[object WebSocket]",
506 "[object ArrayBuffer]", "§§URL§§", "", "null",
507 "onMessageBinary", "message", "[object WebSocket]", "[object WebSocket]",
508 "[object ArrayBuffer]", "§§URL§§", "", "null",
509 "onCloseListener code: 1000 wasClean: false",
510 "onClose code: 1000 wasClean: false"},
511 FF_ESR = {"onOpenListener",
512 "onOpen", "open", "[object WebSocket]", "[object WebSocket]",
513 "undefined", "undefined", "undefined", "undefined",
514 "onMessageTextListener", "message", "[object WebSocket]", "[object WebSocket]",
515 "server_text", "§§URL§§", "", "null",
516 "onMessageText", "message", "[object WebSocket]", "[object WebSocket]",
517 "server_text", "§§URL§§", "", "null",
518 "onMessageBinaryListener", "message", "[object WebSocket]", "[object WebSocket]",
519 "[object ArrayBuffer]", "§§URL§§", "", "null",
520 "onMessageBinary", "message", "[object WebSocket]", "[object WebSocket]",
521 "[object ArrayBuffer]", "§§URL§§", "", "null",
522 "onCloseListener code: 1000 wasClean: false",
523 "onClose code: 1000 wasClean: false"})
524 @HtmlUnitNYI(FF = {"onOpenListener",
525 "onOpen", "open", "[object WebSocket]", "[object WebSocket]",
526 "undefined", "undefined", "undefined", "undefined",
527 "onMessageTextListener", "message", "[object WebSocket]", "[object WebSocket]",
528 "server_text", "§§URL§§", "", "null",
529 "onMessageText", "message", "[object WebSocket]", "[object WebSocket]",
530 "server_text", "§§URL§§", "", "null",
531 "onMessageBinaryListener", "message", "[object WebSocket]", "[object WebSocket]",
532 "[object ArrayBuffer]", "§§URL§§", "", "null",
533 "onMessageBinary", "message", "[object WebSocket]", "[object WebSocket]",
534 "[object ArrayBuffer]", "§§URL§§", "", "null",
535 "onCloseListener code: 1000 wasClean: true",
536 "onClose code: 1000 wasClean: true"},
537 FF_ESR = {"onOpenListener",
538 "onOpen", "open", "[object WebSocket]", "[object WebSocket]",
539 "undefined", "undefined", "undefined", "undefined",
540 "onMessageTextListener", "message", "[object WebSocket]", "[object WebSocket]",
541 "server_text", "§§URL§§", "", "null",
542 "onMessageText", "message", "[object WebSocket]", "[object WebSocket]",
543 "server_text", "§§URL§§", "", "null",
544 "onMessageBinaryListener", "message", "[object WebSocket]", "[object WebSocket]",
545 "[object ArrayBuffer]", "§§URL§§", "", "null",
546 "onMessageBinary", "message", "[object WebSocket]", "[object WebSocket]",
547 "[object ArrayBuffer]", "§§URL§§", "", "null",
548 "onCloseListener code: 1000 wasClean: true",
549 "onClose code: 1000 wasClean: true"})
550 public void wasClean() throws Exception {
551 expandExpectedAlertsVariables("ws://localhost:" + PORT);
552 final String expected = String.join("\n", getExpectedAlerts());
553
554 startWebServer("src/test/resources/org/htmlunit/javascript/host",
555 null, null, new EventsWebSocketHandler());
556 try {
557 final WebDriver driver = getWebDriver();
558 driver.get(URL_FIRST + "WebSocketTest_wasClean.html");
559
560 final WebElement logElement = driver.findElement(By.id("log"));
561 final long maxWait = System.currentTimeMillis() + DEFAULT_WAIT_TIME.toMillis();
562
563 String text;
564 do {
565 Thread.sleep(100);
566
567 text = logElement.getDomProperty("value").trim().replaceAll("\r", "");
568 }
569 while (text.length() <= expected.length() && System.currentTimeMillis() < maxWait);
570
571 assertEquals(expected, text);
572 }
573 finally {
574 stopWebServers();
575 }
576 }
577
578
579
580
581 @Test
582 @Alerts({"onError[object Event]",
583 "onCloseListener code: 1006 wasClean: false",
584 "onClose code: 1006 wasClean: false"})
585 public void eventsNoSocketServer() throws Exception {
586 startWebServer("src/test/resources/org/htmlunit/javascript/host", null, null, null);
587 try {
588 final WebDriver driver = getWebDriver();
589 driver.get(URL_FIRST + "WebSocketTest_wasClean.html");
590
591 final WebElement logElement = driver.findElement(By.id("log"));
592 int counter = 0;
593 String text;
594 do {
595 Thread.sleep(DEFAULT_WAIT_TIME.toMillis());
596
597 text = logElement.getDomProperty("value").trim().replaceAll("\r", "");
598 }
599 while (text.length() > 0 && counter++ < 10);
600
601 assertEquals(String.join("\n", getExpectedAlerts()), text);
602 }
603 finally {
604 stopWebServers();
605 }
606 }
607
608 private static void assertVisible(final String domId, final WebDriver driver) throws Exception {
609 final WebElement domE = driver.findElement(By.id(domId));
610 int counter = 0;
611 do {
612 Thread.sleep(100);
613 }
614 while (!domE.isDisplayed() && counter++ < 10);
615
616 assertEquals("Node should be visible, domId: " + domId, true, domE.isDisplayed());
617 }
618
619 private static class EventsWebSocketHandler extends WebSocketHandler {
620
621 EventsWebSocketHandler() {
622 }
623
624 @Override
625 public void configure(final WebSocketServletFactory factory) {
626 factory.register(EventsWebSocket.class);
627 factory.setCreator(new WebSocketCreator() {
628 @Override
629 public EventsWebSocket createWebSocket(final ServletUpgradeRequest servletUpgradeRequest,
630 final ServletUpgradeResponse servletUpgradeResponse) {
631 return new EventsWebSocket();
632 }
633 });
634 }
635
636 private static class EventsWebSocket extends WebSocketAdapter {
637
638 EventsWebSocket() {
639 }
640
641 @Override
642 public void onWebSocketText(final String data) {
643 if ("text".equals(data)) {
644 try {
645 getRemote().sendString("server_text");
646 }
647 catch (final IOException e) {
648 throw new IllegalStateException(e.getMessage(), e);
649 }
650 }
651 else if ("close".equals(data)) {
652 getSession().close();
653 }
654 else {
655 throw new IllegalArgumentException("Unknown request: " + data);
656 }
657 }
658
659 @Override
660 public void onWebSocketBinary(final byte[] payload, final int offset, final int len) {
661 final String data = new String(payload, offset, len, UTF_16LE);
662 if ("binary".equals(data)) {
663 final ByteBuffer response = ByteBuffer.wrap("server_binary".getBytes(UTF_16LE));
664 try {
665 getRemote().sendBytes(response);
666 }
667 catch (final IOException e) {
668 throw new IllegalStateException(e.getMessage(), e);
669 }
670 }
671 else {
672 throw new IllegalArgumentException("Unknown request: " + data);
673 }
674 }
675 }
676 }
677
678
679
680
681 @Test
682 @Alerts("true")
683 public void prototypeUrl() throws Exception {
684 final String html = DOCTYPE_HTML
685 + "<html><head><script>\n"
686 + LOG_TITLE_FUNCTION
687 + " function test() {\n"
688 + " try {\n"
689 + " var u = WebSocket.prototype.url;\n"
690 + " log(u);\n"
691 + " } catch(e) { log(e instanceof TypeError) }\n"
692 + " }\n"
693 + "</script></head><body onload='test()'>\n"
694 + "</body></html>";
695
696 loadPageVerifyTitle2(html);
697 }
698
699
700
701
702 @Test
703 public void socketsGetClosedOnPageReplace() throws Exception {
704 startWebServer("src/test/resources/org/htmlunit/javascript/host",
705 null, null, new ChatWebSocketHandler());
706 try {
707 final WebDriver driver = getWebDriver();
708 driver.get(URL_FIRST + "WebSocketTest_chat.html");
709
710 driver.findElement(By.id("username")).sendKeys("Browser");
711 driver.findElement(By.id("joinB")).click();
712
713 assertVisible("joined", driver);
714
715 driver.get(URL_FIRST + "plain.html");
716 }
717 finally {
718 stopWebServers();
719 }
720 }
721 }