1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript;
16
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.List;
20
21 import org.htmlunit.CollectingAlertHandler;
22 import org.htmlunit.MockWebConnection;
23 import org.htmlunit.WebClient;
24 import org.htmlunit.WebTestCase;
25 import org.htmlunit.html.HtmlPage;
26 import org.junit.jupiter.api.Assertions;
27 import org.junit.jupiter.api.RepeatedTest;
28
29
30
31
32
33
34
35
36 public class ThreadTest {
37
38
39
40
41 private void testJavaScriptEngineInMultipleThreads() throws InterruptedException {
42 final TestThread thread1 = new TestThread("thread1");
43 final TestThread thread2 = new TestThread("thread2");
44 final TestThread thread3 = new TestThread("thread3");
45 final TestThread thread4 = new TestThread("thread4");
46
47 thread1.start();
48 thread2.start();
49 thread3.start();
50 thread4.start();
51
52 thread1.join();
53 thread2.join();
54 thread3.join();
55 thread4.join();
56
57 Assertions.assertTrue(thread1.isSuccessful(), "thread1 not successful");
58 Assertions.assertTrue(thread2.isSuccessful(), "thread2 not successful");
59 Assertions.assertTrue(thread3.isSuccessful(), "thread3 not successful");
60 Assertions.assertTrue(thread4.isSuccessful(), "thread4 not successful");
61 }
62
63
64
65
66 @RepeatedTest(value = 99, name = "Multi-threaded JS test repetition {currentRepetition}/{totalRepetitions}")
67 public void repeatedMultiThreadTest() throws InterruptedException {
68 testJavaScriptEngineInMultipleThreads();
69 }
70
71
72 private static class TestThread extends Thread {
73
74 private boolean successful_ = false;
75
76
77
78
79
80 TestThread(final String name) {
81 super(name);
82 }
83
84
85
86
87 @Override
88 public void run() {
89 try {
90 testCallInheritedFunction();
91 successful_ = true;
92 }
93 catch (final Exception e) {
94 System.err.println(">>> Thread " + getName());
95 e.printStackTrace(System.err);
96 successful_ = false;
97 }
98 }
99
100
101
102
103 public boolean isSuccessful() {
104 return successful_;
105 }
106
107
108
109
110
111 public void testCallInheritedFunction() throws Exception {
112 final String html =
113 "<html><head><title>foo</title><script>\n"
114 + "function doTest() {\n"
115 + " document.form1.textfield1.focus();\n"
116 + " alert('past focus');\n"
117 + "}\n"
118 + "</script></head><body onload='doTest()'>\n"
119 + "<p>hello world</p>\n"
120 + "<form name='form1'>\n"
121 + " <input type='text' name='textfield1' id='textfield1' value='foo'>\n"
122 + "</form>\n"
123 + "</body></html>";
124
125 final List<String> collectedAlerts = new ArrayList<>();
126
127 try (WebClient webClient = new WebClient()) {
128 webClient.setAlertHandler(new CollectingAlertHandler(collectedAlerts));
129 final MockWebConnection connection = new MockWebConnection();
130 connection.setDefaultResponse(html);
131 webClient.setWebConnection(connection);
132
133 final HtmlPage page = webClient.getPage(WebTestCase.URL_FIRST);
134
135 Assertions.assertEquals("foo", page.getTitleText());
136 Assertions.assertEquals(
137 page.getFormByName("form1").getInputByName("textfield1"),
138 page.getFocusedElement(),
139 "focus not changed to textfield1");
140 final List<String> expectedAlerts = Collections.singletonList("past focus");
141 Assertions.assertEquals(expectedAlerts, collectedAlerts);
142 }
143 }
144 }
145
146 }