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