interaction-with-paint-before-back.tentative.html (4694B)
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script src="/resources/testdriver.js"></script> 8 <script src="/resources/testdriver-vendor.js"></script> 9 <script src="resources/soft-navigation-test-helper.js"></script> 10 </head> 11 <body> 12 <div id="main"> 13 <div id="almost_soft_nav_div"> 14 A click will almost initiate a soft nav, by (1) mutating the DOM by adding an image; (2) 15 causing the image to be painted. 16 </div> 17 <div id="soft_nav_div"> 18 A click will initiate a soft nav, by (1) mutating the DOM by adding an image; (2) causing 19 the image to be painted; (3) updating the URL via history.back(), but without causing a hard 20 navigation. 21 </div> 22 </div> 23 <script> 24 promise_test( 25 async (t) => { 26 // Setup a click handler for 'almost_soft_nav_div', which adds a 27 // specific, identifiable image 'almost_soft_nav_img' to the document. 28 document.getElementById("almost_soft_nav_div").addEventListener("click", () => { 29 const img = new Image(); 30 img.src = "/images/lcp-133x106.png"; 31 img.elementTiming = "almost_soft_nav_img"; 32 document.getElementById("main").appendChild(img); 33 }); 34 35 // Also set up a click handler for 'soft_nav_div', for adding 36 // another image, but in addition to what we do for the almost soft nav 37 // above, also let the handler change the URL, by invoking 38 // history.back(). We prepare with pushState for the history.back() 39 // invocation, to avoid triggering a hard navigation. 40 const test_origin = new URL(location.href).origin; 41 history.pushState({}, "", "/foo.html"); // We will observe this below. 42 history.pushState({}, "", "/bar.html"); // Prep for history.back(). 43 document.getElementById("soft_nav_div").addEventListener("click", async () => { 44 // URL change triggering the soft nav. Since history.back()'s 45 // effect is potentially asynchronous, we wait for it to complete 46 // before we mutate the DOM. This way we ensure that the paints 47 // arrive only after the URL change. 48 history.back(); 49 await t.step_wait(() => location.href.endsWith("/foo.html")); 50 const img = new Image(); 51 img.src = "/images/lcp-133x106.png"; 52 document.getElementById("main").appendChild(img); 53 }); 54 const helper = new SoftNavigationTestHelper(t); 55 56 // Now, click almost_soft_nav_div, and observe that time image 57 // was rendered but no soft nav was triggered. 58 { 59 const element_timing_promise = 60 helper.getBufferedPerformanceEntriesWithTimeout("element"); 61 if (test_driver) { 62 test_driver.click(almost_soft_nav_div); 63 } 64 // Returns entries of type PerformanceElementTiming, see 65 // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceElementTiming. 66 const entries = await element_timing_promise; 67 assert_equals(entries.length, 1); 68 assert_equals( 69 entries[0].identifier, 70 "almost_soft_nav_img", 71 "Image based on the user interaction was painted.", 72 ); 73 assert_equals(performance.getEntriesByType('soft-navigation').length, 0, "No soft navigation detected."); 74 } 75 76 // Now, click soft_nav_div, and observe the detected soft navigation. 77 { 78 const soft_nav_promise = 79 helper.getBufferedPerformanceEntriesWithTimeout("soft-navigation"); 80 if (test_driver) { 81 test_driver.click(soft_nav_div); 82 } 83 // Returns entries of type SoftNavigationEntry, see 84 // https://github.com/WICG/soft-navigations/ 85 const entries = await soft_nav_promise; 86 assert_equals(performance.getEntriesByType('soft-navigation').length, 1, "Single soft navigation detected"); 87 assert_equals(entries.length, 1, "Performance observer got an entry"); 88 assert_equals(entries[0].name, test_origin + "/foo.html"); 89 } 90 }, 91 "Ensure that soft navigation entry emitted through a synchronous " + 92 "event that modified DOM and committed a same document navigation, " + 93 "and that was preceded by a user interaction that resulted in a " + 94 "contentful paint is properly detected.", 95 ); 96 </script> 97 </body> 98 </html>