navigate-same-document-intercept-reentrant.html (3139B)
1 <!doctype html> 2 <script src="/resources/testharness.js"></script> 3 <script src="/resources/testharnessreport.js"></script> 4 <meta name="variant" content="?no-currententrychange"> 5 <meta name="variant" content="?currententrychange"> 6 7 <script type="module"> 8 import { Recorder, hasVariant } from "./resources/helpers.mjs"; 9 10 promise_test(async t => { 11 // Wait for after the load event so that the navigation doesn't get converted 12 // into a replace navigation. 13 await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0)); 14 15 const from = navigation.currentEntry; 16 let firstNavigate = true; 17 18 const recorder = new Recorder({ 19 skipCurrentChange: !hasVariant("currententrychange"), 20 finalExpectedEvent: "transition.finished fulfilled" 21 }); 22 23 recorder.setUpNavigationAPIListeners(); 24 25 navigation.addEventListener("navigate", e => { 26 e.intercept({ handler() { 27 recorder.record("handler run"); 28 return new Promise(r => t.step_timeout(r, 2)); 29 }}); 30 31 if (firstNavigate) { 32 firstNavigate = false; 33 34 const result2 = navigation.navigate("#2"); 35 recorder.setUpResultListeners(result2, " 2"); 36 } 37 }); 38 39 const result1 = navigation.navigate("#1"); 40 recorder.setUpResultListeners(result1, " 1"); 41 42 Promise.resolve().then(() => recorder.record("promise microtask")); 43 44 await recorder.readyToAssert; 45 46 recorder.assert([ 47 /* event name, location.hash value, navigation.transition properties */ 48 ["navigate", "", null], 49 ["AbortSignal abort", "", null], 50 ["navigateerror", "", null], 51 52 ["navigate", "", null], 53 ["currententrychange", "#2", { from, navigationType: "push" }], 54 ["handler run", "#2", { from, navigationType: "push" }], 55 ["committed fulfilled 2", "#2", { from, navigationType: "push" }], 56 ["transition.committed fulfilled 2", "#2", { from, navigationType: "push" }], 57 ["committed rejected 1", "#2", { from, navigationType: "push" }], 58 ["finished rejected 1", "#2", { from, navigationType: "push" }], 59 // Because of the reentrant nature of this test, 60 // "transition.committed fulfilled 1" and "transition.committed fulfilled 2" 61 // are for the same transition.committed promise: the one for the second 62 // navigation that interrupted the first. The first navigation never 63 // was aborted during navigate event dispatch, so there was never a 64 // transition.committed for it. But by the time 65 // recorder.setUpResultListeners(result1, " 1") runs, the second 66 // navigation's transition.committed had been installed, so we attached a 67 // listener to log it with the "1" label (in addition to the previous 68 // listener to log it with the "2" label). 69 ["transition.committed fulfilled 1", "#2", { from, navigationType: "push" }], 70 ["promise microtask", "#2", { from, navigationType: "push" }], 71 ["navigatesuccess", "#2", { from, navigationType: "push" }], 72 ["finished fulfilled 2", "#2", null], 73 ["transition.finished fulfilled", "#2", null] 74 ]); 75 76 recorder.assertErrorsAreAbortErrors(); 77 }, "event and promise ordering for same-document navigation.navigate() inside the navigate handler"); 78 </script>