diff options
Diffstat (limited to 'gfx/layers/apz/test/mochitest/helper_visual_scrollbars_pagescroll.html')
-rw-r--r-- | gfx/layers/apz/test/mochitest/helper_visual_scrollbars_pagescroll.html | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/gfx/layers/apz/test/mochitest/helper_visual_scrollbars_pagescroll.html b/gfx/layers/apz/test/mochitest/helper_visual_scrollbars_pagescroll.html new file mode 100644 index 0000000000..ae3025930f --- /dev/null +++ b/gfx/layers/apz/test/mochitest/helper_visual_scrollbars_pagescroll.html @@ -0,0 +1,119 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width"> + <title>Clicking on the scrollbar track in quick succession should scroll the right amount</title> + <script type="application/javascript" src="apz_test_native_event_utils.js"></script> + <script type="application/javascript" src="apz_test_utils.js"></script> + <script src="/tests/SimpleTest/paint_listener.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + + <script type="application/javascript"> + +// A helper to synthesize a native mouse click on a scrollbar track, +// and wait long enough such that subsequent ticking of the refresh +// driver will progress any resulting scroll animation. +// In particular, just `await promiseNativeMouseEventWithApz(...)` +// is not enough, it waits for the synthesization messages to arrive +// in the parent process, but the native events may still be in the +// OS event queue. Instead, we need to wait for a synthesized event +// to arrive at content. While we're synthesizing a "click", if the +// target is a scrollbar the window only gets the "mousedown" and +// "mouseup", not a "click". Waiting for the "mousedown" is not enough +// (the "mouseup" can still be stuck in the event queue), so we wait +// for "mouseup". +async function promiseNativeMouseClickOnScrollbarTrack(anchor, xOffset, yOffset) { + await promiseNativeMouseEventWithAPZAndWaitForEvent({ + type: "click", + target: anchor, + offsetX: xOffset, + offsetY: yOffset, + eventTypeToWait: "mouseup" + }); +} + +async function test() { + var scroller = document.documentElement; + var verticalScrollbarWidth = window.innerWidth - scroller.clientWidth; + + if (verticalScrollbarWidth == 0) { + ok(true, "Scrollbar width is zero on this platform, test is useless here"); + return; + } + + // The anchor is the fixed-pos div that we use to calculate coordinates to + // click on the scrollbar. That way we don't have to recompute coordinates + // as the page scrolls. The anchor is at the bottom-right corner of the + // content area. + var anchor = document.getElementById('anchor'); + + var xoffset = (verticalScrollbarWidth / 2); + // Get a y-coord near the bottom of the vertical scrollbar track. Assume the + // vertical thumb is near the top of the scrollback track (since scroll + // position starts off at zero) and won't get in the way. Also assume the + // down arrow button, if there is one, is square. + var yoffset = 0 - verticalScrollbarWidth - 5; + + // Take control of the refresh driver + let utils = SpecialPowers.getDOMWindowUtils(window); + utils.advanceTimeAndRefresh(0); + + // Click at the bottom of the scrollbar track to trigger a page-down kind of + // scroll. This should use "desktop zooming" scrollbar code which should + // trigger an APZ scroll animation. + await promiseNativeMouseClickOnScrollbarTrack(anchor, xoffset, yoffset); + + // Run 1000 frames, that should be enough to let the scroll animation start + // and run to completion. We check that it scrolled at least half the visible + // height, since we expect about a full screen height minus a few lines. + for (let i = 0; i < 1000; i++) { + utils.advanceTimeAndRefresh(16); + } + await promiseOnlyApzControllerFlushed(); + + let pageScrollAmount = scroller.scrollTop; + ok(pageScrollAmount > scroller.clientHeight / 2, + `Scroll offset is ${pageScrollAmount}, should be near clientHeight ${scroller.clientHeight}`); + + // Now we do two clicks in quick succession, but with a few frames in between + // to verify the scroll animation from the first click is active before the + // second click happens. + await promiseNativeMouseClickOnScrollbarTrack(anchor, xoffset, yoffset); + for (let i = 0; i < 5; i++) { + utils.advanceTimeAndRefresh(16); + } + await promiseOnlyApzControllerFlushed(); + let curPos = scroller.scrollTop; + ok(curPos > pageScrollAmount, `Scroll offset has increased to ${curPos}`); + ok(curPos < pageScrollAmount * 2, "Second page-scroll is not yet complete"); + await promiseNativeMouseClickOnScrollbarTrack(anchor, xoffset, yoffset); + + // Run to completion and check that we are around 3x pageScrollAmount, with + // some allowance for fractional rounding. + for (let i = 0; i < 1000; i++) { + utils.advanceTimeAndRefresh(16); + } + await promiseOnlyApzControllerFlushed(); + curPos = scroller.scrollTop; + ok(Math.abs(curPos - (pageScrollAmount * 3)) < 3, + `Final scroll offset ${curPos} is close to 3x${pageScrollAmount}`); + + utils.restoreNormalRefresh(); +} + +waitUntilApzStable() +.then(test) +.then(subtestDone, subtestFailed); + + </script> +</head> +<body> + <div style="position:fixed; bottom: 0; right: 0; width: 1px; height: 1px" id="anchor"></div> + <div style="height: 300vh; margin-bottom: 10000px; background-image: linear-gradient(red,blue)"></div> + The above div is sized to 3x screen height so the linear gradient is more steep in terms of + color/pixel. We only scroll a few pages worth so we don't need the gradient all the way down. + And then we use a bottom-margin to make the page really big so the scrollthumb is + relatively small, giving us lots of space to click on the scrolltrack. +</body> +</html> |