| <!doctype html> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <meta name="variant" content="?no-currententrychange"> |
| <meta name="variant" content="?currententrychange"> |
| |
| <script type="module"> |
| import { Recorder, hasVariant } from "./resources/helpers.mjs"; |
| |
| promise_test(async t => { |
| // Wait for after the load event so that the navigation doesn't get converted |
| // into a replace navigation. |
| await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0)); |
| |
| const from = navigation.currentEntry; |
| let firstNavigate = true; |
| |
| const recorder = new Recorder({ |
| skipCurrentChange: !hasVariant("currententrychange"), |
| finalExpectedEvent: "transition.finished fulfilled" |
| }); |
| |
| recorder.setUpNavigationAPIListeners(); |
| |
| navigation.addEventListener("navigate", e => { |
| e.intercept({ handler() { |
| recorder.record("handler run"); |
| return new Promise(r => t.step_timeout(r, 2)); |
| }}); |
| |
| if (firstNavigate) { |
| firstNavigate = false; |
| |
| const result2 = navigation.navigate("#2"); |
| recorder.setUpResultListeners(result2, " 2"); |
| } |
| }); |
| |
| const result1 = navigation.navigate("#1"); |
| recorder.setUpResultListeners(result1, " 1"); |
| |
| Promise.resolve().then(() => recorder.record("promise microtask")); |
| |
| await recorder.readyToAssert; |
| |
| recorder.assert([ |
| /* event name, location.hash value, navigation.transition properties */ |
| ["navigate", "", null], |
| ["AbortSignal abort", "", null], |
| ["navigateerror", "", null], |
| |
| ["navigate", "", null], |
| ["currententrychange", "#2", { from, navigationType: "push" }], |
| ["handler run", "#2", { from, navigationType: "push" }], |
| ["committed fulfilled 2", "#2", { from, navigationType: "push" }], |
| ["transition.committed fulfilled 2", "#2", { from, navigationType: "push" }], |
| ["committed rejected 1", "#2", { from, navigationType: "push" }], |
| ["finished rejected 1", "#2", { from, navigationType: "push" }], |
| // Because of the reentrant nature of this test, |
| // "transition.committed fulfilled 1" and "transition.committed fulfilled 2" |
| // are for the same transition.committed promise: the one for the second |
| // navigation that interrupted the first. The first navigation never |
| // was aborted during navigate event dispatch, so there was never a |
| // transition.committed for it. But by the time |
| // recorder.setUpResultListeners(result1, " 1") runs, the second |
| // navigation's transition.committed had been installed, so we attached a |
| // listener to log it with the "1" label (in addition to the previous |
| // listener to log it with the "2" label). |
| ["transition.committed fulfilled 1", "#2", { from, navigationType: "push" }], |
| ["promise microtask", "#2", { from, navigationType: "push" }], |
| ["navigatesuccess", "#2", { from, navigationType: "push" }], |
| ["finished fulfilled 2", "#2", null], |
| ["transition.finished fulfilled", "#2", null] |
| ]); |
| |
| recorder.assertErrorsAreAbortErrors(); |
| }, "event and promise ordering for same-document navigation.navigate() inside the navigate handler"); |
| </script> |