1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit;
16
17 import java.net.URL;
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.LinkedList;
21 import java.util.List;
22
23 import org.apache.commons.lang3.mutable.MutableInt;
24 import org.htmlunit.html.HtmlPage;
25 import org.htmlunit.javascript.background.JavaScriptJob;
26 import org.htmlunit.javascript.background.JavaScriptJobManager;
27 import org.htmlunit.junit.annotation.Alerts;
28 import org.junit.jupiter.api.Test;
29
30
31
32
33
34
35
36
37
38 public class TopLevelWindowTest extends SimpleWebTestCase {
39
40
41
42
43
44 @Test
45 public void closeTheOnlyWindow() throws Exception {
46 final WebClient webClient = getWebClient();
47
48 final List<WebWindowEvent> events = new LinkedList<>();
49 webClient.addWebWindowListener(new WebWindowListener() {
50 @Override
51 public void webWindowOpened(final WebWindowEvent event) {
52 events.add(event);
53 }
54
55 @Override
56 public void webWindowContentChanged(final WebWindowEvent event) {
57 events.add(event);
58 }
59
60 @Override
61 public void webWindowClosed(final WebWindowEvent event) {
62 events.add(event);
63 }
64 });
65
66 final WebWindow windowToClose = webClient.getCurrentWindow();
67 ((TopLevelWindow) windowToClose).close();
68
69 assertEquals(2, events.size());
70 assertEquals(new WebWindowEvent(windowToClose, WebWindowEvent.CLOSE, null, null), events.get(0));
71 assertEquals(WebWindowEvent.OPEN, events.get(1).getEventType());
72 assertNull(events.get(1).getOldPage());
73 assertNull(events.get(1).getNewPage());
74
75
76
77 assertNotNull(webClient.getCurrentWindow());
78 assertNotSame(webClient.getCurrentWindow(), windowToClose);
79
80 assertEquals(1, webClient.getWebWindows().size());
81 assertEquals(1, webClient.getTopLevelWindows().size());
82 assertEquals(webClient.getWebWindows().get(0), webClient.getTopLevelWindows().get(0));
83 }
84
85
86
87
88
89 @Test
90 public void useCustomJobManager() throws Exception {
91 final MutableInt jobCount = new MutableInt(0);
92 final JavaScriptJobManager mgr = new JavaScriptJobManager() {
93
94 @Override
95 public int waitForJobsStartingBefore(final long delayMillis) {
96 return jobCount.intValue();
97 }
98
99 @Override
100 public int waitForJobsStartingBefore(final long delayMillis, final long timeoutMillis) {
101 return jobCount.intValue();
102 }
103
104 @Override
105 public int waitForJobsStartingBefore(final long delayMillis, final long timeoutMillis,
106 final JavaScriptJobFilter filter) {
107 return jobCount.intValue();
108 }
109
110 @Override
111 public int waitForJobsStartingBefore(final long delayMillis, final JavaScriptJobFilter filter) {
112 return jobCount.intValue();
113 }
114
115 @Override
116 public int waitForJobs(final long timeoutMillis) {
117 return jobCount.intValue();
118 }
119
120 @Override
121 public void stopJob(final int id) {
122
123 }
124
125 @Override
126 public void shutdown() {
127
128 }
129
130 @Override
131 public void removeJob(final int id) {
132
133 }
134
135 @Override
136 public void removeAllJobs() {
137
138 }
139
140 @Override
141 public int getJobCount() {
142 return jobCount.intValue();
143 }
144
145 @Override
146 public int getJobCount(final JavaScriptJobFilter filter) {
147 return jobCount.intValue();
148 }
149
150 @Override
151 public int addJob(final JavaScriptJob job, final Page page) {
152 jobCount.increment();
153 return jobCount.intValue();
154 }
155
156 @Override
157 public JavaScriptJob getEarliestJob() {
158 return null;
159 }
160
161 @Override
162 public JavaScriptJob getEarliestJob(final JavaScriptJobFilter filter) {
163 return null;
164 }
165
166 @Override
167 public boolean runSingleJob(final JavaScriptJob job) {
168
169 return false;
170 }
171 @Override
172 public String jobStatusDump(final JavaScriptJobFilter filter) {
173 return null;
174 }
175 };
176
177 final WebWindowListener listener = new WebWindowListener() {
178
179 @Override
180 public void webWindowOpened(final WebWindowEvent event) {
181 ((WebWindowImpl) event.getWebWindow()).setJobManager(mgr);
182 }
183
184 @Override
185 public void webWindowContentChanged(final WebWindowEvent event) {
186
187 }
188
189 @Override
190 public void webWindowClosed(final WebWindowEvent event) {
191
192 }
193 };
194
195 final WebClient client = getWebClientWithMockWebConnection();
196 client.addWebWindowListener(listener);
197
198 final TopLevelWindow window = (TopLevelWindow) client.getCurrentWindow();
199 window.setJobManager(mgr);
200
201 final MockWebConnection conn = getMockWebConnection();
202 conn.setDefaultResponse(DOCTYPE_HTML
203 + "<html><body><script>window.setTimeout('', 500);</script></body></html>");
204
205 client.getPage(URL_FIRST);
206 assertEquals(1, jobCount.intValue());
207
208 client.getPage(URL_FIRST);
209 assertEquals(2, jobCount.intValue());
210 }
211
212
213
214
215 @Test
216 public void history() throws Exception {
217 final WebClient client = getWebClientWithMockWebConnection();
218 final TopLevelWindow window = (TopLevelWindow) client.getCurrentWindow();
219 final History history = window.getHistory();
220
221 final MockWebConnection conn = getMockWebConnection();
222 conn.setResponse(URL_FIRST, DOCTYPE_HTML
223 + "<html><body><a name='a' href='" + URL_SECOND + "'>foo</a>\n"
224 + "<a name='b' href='#b'>bar</a></body></html>");
225 conn.setResponse(URL_SECOND, DOCTYPE_HTML
226 + "<html><body><a name='a' href='" + URL_THIRD + "'>foo</a></body></html>");
227 conn.setResponse(URL_THIRD, DOCTYPE_HTML
228 + "<html><body><a name='a' href='" + URL_FIRST + "'>foo</a></body></html>");
229
230 assertEquals(0, history.getLength());
231 assertEquals(-1, history.getIndex());
232
233
234 HtmlPage page = client.getPage(URL_FIRST);
235 assertEquals(1, history.getLength());
236 assertEquals(0, history.getIndex());
237 assertNull(history.getUrl(-1));
238 assertEquals(URL_FIRST, history.getUrl(0));
239 assertEquals(URL_FIRST, window.getEnclosedPage().getUrl());
240 assertNull(history.getUrl(1));
241
242
243 page = page.getAnchorByName("a").click();
244 assertEquals(2, history.getLength());
245 assertEquals(1, history.getIndex());
246 assertNull(history.getUrl(-1));
247 assertEquals(URL_FIRST, history.getUrl(0));
248 assertEquals(URL_SECOND, history.getUrl(1));
249 assertEquals(URL_SECOND, window.getEnclosedPage().getUrl());
250 assertNull(history.getUrl(2));
251
252
253 page = page.getAnchorByName("a").click();
254 assertEquals(3, history.getLength());
255 assertEquals(2, history.getIndex());
256 assertNull(history.getUrl(-1));
257 assertEquals(URL_FIRST, history.getUrl(0));
258 assertEquals(URL_SECOND, history.getUrl(1));
259 assertEquals(URL_THIRD, history.getUrl(2));
260 assertEquals(URL_THIRD, window.getEnclosedPage().getUrl());
261 assertNull(history.getUrl(3));
262
263
264 page = page.getAnchorByName("a").click();
265 assertEquals(4, history.getLength());
266 assertEquals(3, history.getIndex());
267 assertNull(history.getUrl(-1));
268 assertEquals(URL_FIRST, history.getUrl(0));
269 assertEquals(URL_SECOND, history.getUrl(1));
270 assertEquals(URL_THIRD, history.getUrl(2));
271 assertEquals(URL_FIRST, history.getUrl(3));
272 assertEquals(URL_FIRST, window.getEnclosedPage().getUrl());
273 assertNull(history.getUrl(4));
274
275
276 final URL firstUrlWithHash = new URL(URL_FIRST, "#b");
277 page = page.getAnchorByName("b").click();
278 assertEquals(5, history.getLength());
279 assertEquals(4, history.getIndex());
280 assertNull(history.getUrl(-1));
281 assertEquals(URL_FIRST, history.getUrl(0));
282 assertEquals(URL_SECOND, history.getUrl(1));
283 assertEquals(URL_THIRD, history.getUrl(2));
284 assertEquals(URL_FIRST, history.getUrl(3));
285 assertEquals(firstUrlWithHash, history.getUrl(4));
286 assertEquals(firstUrlWithHash, window.getEnclosedPage().getUrl());
287 assertNull(history.getUrl(5));
288
289 history.back().back();
290 assertEquals(5, history.getLength());
291 assertEquals(2, history.getIndex());
292 assertNull(history.getUrl(-1));
293 assertEquals(URL_FIRST, history.getUrl(0));
294 assertEquals(URL_SECOND, history.getUrl(1));
295 assertEquals(URL_THIRD, history.getUrl(2));
296 assertEquals(URL_FIRST, history.getUrl(3));
297 assertEquals(firstUrlWithHash, history.getUrl(4));
298 assertEquals(URL_THIRD, window.getEnclosedPage().getUrl());
299 assertNull(history.getUrl(5));
300
301 history.forward();
302 assertEquals(5, history.getLength());
303 assertEquals(3, history.getIndex());
304 assertNull(history.getUrl(-1));
305 assertEquals(URL_FIRST, history.getUrl(0));
306 assertEquals(URL_SECOND, history.getUrl(1));
307 assertEquals(URL_THIRD, history.getUrl(2));
308 assertEquals(URL_FIRST, history.getUrl(3));
309 assertEquals(firstUrlWithHash, history.getUrl(4));
310 assertEquals(URL_FIRST, window.getEnclosedPage().getUrl());
311 assertNull(history.getUrl(5));
312 }
313
314
315
316
317
318 @Test
319 public void onBeforeUnloadCalledOnClose() throws Exception {
320 final String html = DOCTYPE_HTML + "<html><body onbeforeunload='alert(7)'>abc</body></html>";
321 final List<String> alerts = new ArrayList<>();
322 final HtmlPage page = loadPage(html, alerts);
323 assertTrue(alerts.isEmpty());
324 final TopLevelWindow w = (TopLevelWindow) page.getEnclosingWindow();
325 w.close();
326 assertEquals(Arrays.asList("7"), alerts);
327 }
328
329
330
331
332
333
334
335 @Test
336 @Alerts("closing")
337 public void setTimeoutDuringOnUnload() throws Exception {
338 final String html = DOCTYPE_HTML
339 + "<html><head>\n"
340 + "<script>\n"
341 + "function f() {\n"
342 + " alert('closing');\n"
343 + " setTimeout(function() { alert('started in onunload'); }, 0);\n"
344 + "}\n"
345 + "window.addEventListener('unload', f, true);\n"
346 + "</script></head>\n"
347 + "<body></body></html>";
348 final List<String> alerts = new ArrayList<>();
349 final HtmlPage page = loadPage(html, alerts);
350 assertTrue(alerts.isEmpty());
351 final TopLevelWindow w = (TopLevelWindow) page.getEnclosingWindow();
352 w.close();
353 getWebClient().waitForBackgroundJavaScript(1000);
354 assertEquals(getExpectedAlerts(), alerts);
355 }
356
357 }