|
9 | 9 | SimpleTest.waitForExplicitFinish(); |
10 | 10 | SimpleTest.requestFlakyTimeout("Need to wait to make sure an event does not fire"); |
11 | 11 |
|
12 | | - async function runTest() { |
13 | | - let win = window.open(); |
14 | | - let goneBackAndForwardOnce = new Promise((resolve) => { |
15 | | - let timeoutID; |
16 | | - |
17 | | - // We should only get one load event in win. |
18 | | - let bc = new BroadcastChannel("bug1729662"); |
19 | | - bc.addEventListener("message", () => { |
20 | | - bc.addEventListener("message", () => { |
21 | | - clearTimeout(timeoutID); |
22 | | - resolve(false); |
23 | | - }); |
24 | | - }, { once: true }); |
25 | | - |
26 | | - let goneBack = false, goneForward = false; |
27 | | - win.addEventListener("popstate", ({ state }) => { |
28 | | - // We should only go back and forward once, if we get another |
29 | | - // popstate after that then we should fall through to the |
30 | | - // failure case below. |
31 | | - if (!(goneBack && goneForward)) { |
32 | | - // Check if this is the popstate for the forward (the one for |
33 | | - // back will have state == undefined). |
34 | | - if (state == 1) { |
35 | | - ok(goneBack, "We should have gone back before going forward"); |
36 | | - |
37 | | - goneForward = true; |
38 | | - |
39 | | - // Wait a bit to make sure there are no more popstate events. |
40 | | - // eslint-disable-next-line mozilla/no-arbitrary-setTimeout |
41 | | - timeoutID = setTimeout(resolve, 1000, true); |
42 | | - |
43 | | - return; |
44 | | - } |
| 12 | + function waitForEvent(target, event) { |
| 13 | + return new Promise(resolve => |
| 14 | + target.addEventListener(event, resolve, { once: true })); |
| 15 | + } |
45 | 16 |
|
46 | | - // Check if we've gone back once before, if we get another |
47 | | - // popstate after that then we should fall through to the |
48 | | - // failure case below. |
49 | | - if (!goneBack) { |
50 | | - goneBack = true; |
| 17 | + async function runTest() { |
| 18 | + // Target page needs to be the initial load so that the synchronously |
| 19 | + // available window is reused and we can attach popstate listeners. |
| 20 | + const win = window.open('file_bug1729662.html'); |
| 21 | + |
| 22 | + let timeoutID; |
| 23 | + let loadCount = 0; |
| 24 | + let bc = new BroadcastChannel("bug1729662"); |
| 25 | + bc.onmessage = ({ data }) => { |
| 26 | + if (data != 'load') return; |
| 27 | + if (++loadCount > 1) { |
| 28 | + // We should only get one load event in win |
| 29 | + clearTimeout(timeoutID); |
| 30 | + } |
| 31 | + }; |
51 | 32 |
|
52 | | - return; |
53 | | - } |
54 | | - } |
| 33 | + // We should only go back and forward once |
| 34 | + // The popstate for back will have state == null, see file_bug1729662.html |
| 35 | + const state1 = await waitForEvent(win, 'popstate'); |
| 36 | + is(state1.state, null, 'got expected state for history.back'); |
55 | 37 |
|
56 | | - clearTimeout(timeoutID); |
57 | | - resolve(false); |
58 | | - }); |
59 | | - }); |
| 38 | + const state2 = await waitForEvent(win, 'popstate'); |
| 39 | + is(state2.state, 1, 'got expected state for history.forward'); |
60 | 40 |
|
61 | | - win.location = "file_bug1729662.html"; |
| 41 | + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout |
| 42 | + const timeout = new Promise(resolve => timeoutID = setTimeout(resolve, 1000, 'timeout')); |
| 43 | + const result = await Promise.race([ |
| 44 | + waitForEvent(win, 'popstate'), |
| 45 | + timeout |
| 46 | + ]); |
| 47 | + is(result, 'timeout', 'Got no more popstate'); |
62 | 48 |
|
63 | | - ok(await goneBackAndForwardOnce, "Stopped navigating history"); |
| 49 | + is(loadCount, isXOrigin ? 0 : 1, 'Got exactly one (zero for xorigin) load events in win'); |
64 | 50 |
|
| 51 | + clearTimeout(timeoutID); |
65 | 52 | win.close(); |
66 | 53 |
|
67 | 54 | SimpleTest.finish(); |
|
0 commit comments