diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /gfx/layers/apz/test/mochitest/helper_fission_scroll_oopif.html | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | gfx/layers/apz/test/mochitest/helper_fission_scroll_oopif.html | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/gfx/layers/apz/test/mochitest/helper_fission_scroll_oopif.html b/gfx/layers/apz/test/mochitest/helper_fission_scroll_oopif.html new file mode 100644 index 0000000000..2911b1eaf0 --- /dev/null +++ b/gfx/layers/apz/test/mochitest/helper_fission_scroll_oopif.html @@ -0,0 +1,158 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for async-scrolling an OOPIF and ensuring hit-testing still works</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/paint_listener.js"></script> + <script src="helper_fission_utils.js"></script> + <script src="apz_test_utils.js"></script> + <script src="apz_test_native_event_utils.js"></script> + <script> + +fission_subtest_init(); + +FissionTestHelper.startTestPromise + .then(waitUntilApzStable) + .then(loadOOPIFrame("testframe", "helper_fission_empty.html")) + .then(waitUntilApzStable) + .then(test) + .then(FissionTestHelper.subtestDone, FissionTestHelper.subtestFailed); + + +let code_for_oopif_to_run = function() { + document.addEventListener("click", function(e) { + dump(`OOPIF got click at ${e.clientX},${e.clientY}\n`); + let result = { x: e.clientX, y: e.clientY }; + FissionTestHelper.fireEventInEmbedder("OOPIF:ClickData", result); + }); + dump("OOPIF registered click listener\n"); + return true; +}; + +async function clickOnIframe(x, y) { + let iframePromise = promiseOneEvent(window, "OOPIF:ClickData", null); + await synthesizeNativeMouseEventWithAPZ( + { type: "click", target: document.body, offsetX: x, offsetY: y }, + () => dump("Finished synthesizing click, waiting for OOPIF message...\n") + ); + let iframeResponse = await iframePromise; + dump("OOPIF response: " + JSON.stringify(iframeResponse.data) + "\n"); + return iframeResponse.data; +} + +let oopif_scroll_pos = function() { + dump(`OOPIF scroll position is y=${window.scrollY}\n`); + let result = { y: window.scrollY }; + FissionTestHelper.fireEventInEmbedder("OOPIF:ScrollPos", result); + return true; +}; + +async function getIframeScrollY() { + let iframeElement = document.getElementById("testframe"); + let iframePromise = promiseOneEvent(window, "OOPIF:ScrollPos", null); + ok(await FissionTestHelper.sendToOopif(iframeElement, `(${oopif_scroll_pos})()`), "Sent scrollY request"); + let iframeResponse = await iframePromise; + dump("OOPIF response for scrollPos: " + JSON.stringify(iframeResponse.data) + "\n"); + return iframeResponse.data.y; +} + +let make_oopif_scrollable = function() { + // ensure the oopif is scrollable, and wait for the paint so that the + // compositor also knows it's scrollable. + document.body.style.height = "200vh"; + promiseApzFlushedRepaints().then(() => { + let result = { y: window.scrollMaxY }; + FissionTestHelper.fireEventInEmbedder("OOPIF:Scrollable", result); + }); + // Also register a scroll listener for when it actually gets scrolled. + window.addEventListener("scroll", function(e) { + dump(`OOPIF got scroll event, now at ${window.scrollY}\n`); + let result = { y: window.scrollY }; + FissionTestHelper.fireEventInEmbedder("OOPIF:Scrolled", result); + }, {once: true}); + return true; +}; + +function failsafe(eventType) { + // Catch and fail faster on the case where the event ends up not going to + // the iframe like it should. Otherwise the test hangs until timeout which + // is more painful. + document.addEventListener(eventType, function(e) { + dump(`${location.href} got ${e.type} at ${e.clientX},${e.clientY}\n`); + ok(false, `The OOPIF hosting page should not have gotten the ${eventType}`); + setTimeout(FissionTestHelper.subtestFailed, 0); + }, {once: true}); +} + +// The actual test + +async function test() { + ok(SpecialPowers.getBoolPref("apz.paint_skipping.enabled"), + "paint-skipping is expected to be enabled for this test to be meaningful"); + + let iframeElement = document.getElementById("testframe"); + + let iframeResponse = await FissionTestHelper.sendToOopif(iframeElement, `(${code_for_oopif_to_run})()`); + dump("OOPIF response: " + JSON.stringify(iframeResponse) + "\n"); + ok(iframeResponse, "code_for_oopif_to_run successfully installed"); + + is(window.scrollY, 0, "window is at 0 scroll position"); + + // hit-test into the iframe before scrolling + let oldClickPoint = await clickOnIframe(50, 250); + + // do an APZ scroll and wait for the main-thread to get the repaint request, + // and queue up a paint-skip scroll notification back to APZ. + await promiseMoveMouseAndScrollWheelOver(document.body, 10, 10); + + // The wheel scroll might have started an APZ animation, so run that to the end + var utils = SpecialPowers.getDOMWindowUtils(window); + for (var i = 0; i < 60; i++) { + utils.advanceTimeAndRefresh(16); + } + utils.restoreNormalRefresh(); + // Let the repaint requests get processed + await promiseOnlyApzControllerFlushed(); + await promiseAllPaintsDone(); + + ok(window.scrollY > 5, "window has scrolled by " + window.scrollY + " pixels"); + + // hit-test into the iframe after scrolling. The coordinates here are the + // same relative to the body as before, but get computed to be different + // relative to the window/screen. + let newClickPoint = await clickOnIframe(50, 250); + + is(newClickPoint.x, oldClickPoint.x, "x-coord of old and new match"); + is(newClickPoint.y, oldClickPoint.y, "y-coord of old and new match"); + + // Also check that we can send scroll events to the OOPIF. Any wheel events + // delivered to this page after this point should result in a failure. + failsafe("wheel"); + + let iframeY = await getIframeScrollY(); + is(iframeY, 0, "scrollY of iframe should be 0 initially"); + + // Ensure the OOPIF is scrollable. + let scrollablePromise = promiseOneEvent(window, "OOPIF:Scrollable", null); + ok(await FissionTestHelper.sendToOopif(iframeElement, `(${make_oopif_scrollable})()`), "Made OOPIF scrollable"); + let oopifScrollMaxY = (await scrollablePromise).data.y; + ok(oopifScrollMaxY > 0, "Confirmed that oopif is scrollable"); + + // Now scroll over the OOP-iframe (we know it must be under the 50,250 point + // because we just checked that above). Note that listening for wheel/scroll + // events is trickier because they will fire in the OOPIF, so we can't just + // use promiseMoveMouseAndScrollWheelOver directly. + let scrolledPromise = promiseOneEvent(window, "OOPIF:Scrolled", null); + await synthesizeNativeWheel(document.body, 50, 250, 0, -10); + iframeY = (await scrolledPromise).data.y; + ok(iframeY > 0, "scrollY of iframe should be >0 after scrolling"); +} + + </script> +</head> +<body onload="failsafe('click')"> +<iframe style="margin-top: 200px" id="testframe"></iframe> +<div style="height: 5000px">tall div to make the page scrollable</div> +</body> +</html> |