summaryrefslogtreecommitdiffstats
path: root/gfx/layers/apz/test/mochitest/helper_fission_scroll_oopif.html
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/apz/test/mochitest/helper_fission_scroll_oopif.html')
-rw-r--r--gfx/layers/apz/test/mochitest/helper_fission_scroll_oopif.html158
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>