summaryrefslogtreecommitdiffstats
path: root/toolkit/content/tests/chrome/test_mousescroll.xhtml
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/content/tests/chrome/test_mousescroll.xhtml')
-rw-r--r--toolkit/content/tests/chrome/test_mousescroll.xhtml291
1 files changed, 291 insertions, 0 deletions
diff --git a/toolkit/content/tests/chrome/test_mousescroll.xhtml b/toolkit/content/tests/chrome/test_mousescroll.xhtml
new file mode 100644
index 0000000000..875ca4ac98
--- /dev/null
+++ b/toolkit/content/tests/chrome/test_mousescroll.xhtml
@@ -0,0 +1,291 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=378028
+-->
+<window title="Mozilla Bug 378028"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+ <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
+ <script src="chrome://mochikit/content/tests/SimpleTest/paint_listener.js"/>
+
+ <!-- test results are displayed in the html:body -->
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=378028"
+ target="_blank">Mozilla Bug 378028</a>
+ </body>
+
+ <!-- richlistbox currently has no way of giving us a defined number of
+ rows, so we just choose an arbitrary height limit that should give
+ us plenty of vertical scrollability -->
+ <richlistbox id="richlistbox" style="height:50px;">
+ <richlistitem id="richlistbox_item0" hidden="true"><label value="Item 0"/></richlistitem>
+ <richlistitem id="richlistbox_item1"><label value="Item 1"/></richlistitem>
+ <richlistitem id="richlistbox_item2"><label value="Item 2"/></richlistitem>
+ <richlistitem id="richlistbox_item3"><label value="Item 3"/></richlistitem>
+ <richlistitem id="richlistbox_item4"><label value="Item 4"/></richlistitem>
+ <richlistitem id="richlistbox_item5"><label value="Item 5"/></richlistitem>
+ <richlistitem id="richlistbox_item6"><label value="Item 6"/></richlistitem>
+ <richlistitem id="richlistbox_item7"><label value="Item 7"/></richlistitem>
+ <richlistitem id="richlistbox_item8"><label value="Item 8"/></richlistitem>
+ </richlistbox>
+
+ <box orient="horizontal">
+ <arrowscrollbox id="hscrollbox" clicktoscroll="true" orient="horizontal"
+ smoothscroll="false" style="max-width:80px;" flex="1">
+ <hbox style="min-width:40px; min-height:20px; background:black;" hidden="true"/>
+ <hbox style="min-width:40px; min-height:20px; background:white;"/>
+ <hbox style="min-width:40px; min-height:20px; background:black;"/>
+ <hbox style="min-width:40px; min-height:20px; background:white;"/>
+ <hbox style="min-width:40px; min-height:20px; background:black;"/>
+ <hbox style="min-width:40px; min-height:20px; background:white;"/>
+ <hbox style="min-width:40px; min-height:20px; background:black;"/>
+ <hbox style="min-width:40px; min-height:20px; background:white;"/>
+ <hbox style="min-width:40px; min-height:20px; background:black;"/>
+ </arrowscrollbox>
+ </box>
+
+ <arrowscrollbox id="vscrollbox" clicktoscroll="true" orient="vertical"
+ smoothscroll="false" style="max-height:80px;" flex="1">
+ <vbox style="min-width:100px; min-height:40px; background:black;" hidden="true"/>
+ <vbox style="min-width:100px; min-height:40px; background:white;"/>
+ <vbox style="min-width:100px; min-height:40px; background:black;"/>
+ <vbox style="min-width:100px; min-height:40px; background:white;"/>
+ <vbox style="min-width:100px; min-height:40px; background:black;"/>
+ <vbox style="min-width:100px; min-height:40px; background:white;"/>
+ <vbox style="min-width:100px; min-height:40px; background:black;"/>
+ <vbox style="min-width:100px; min-height:40px; background:white;"/>
+ <vbox style="min-width:100px; min-height:40px; background:black;"/>
+ <vbox style="min-width:100px; min-height:40px; background:white;"/>
+ <vbox style="min-width:100px; min-height:40px; background:black;"/>
+ </arrowscrollbox>
+
+ <!-- test code goes here -->
+ <script type="application/javascript"><![CDATA[
+
+/** Test for Bug 378028 **/
+/* and for Bug 350471 **/
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(prepareRunningTests);
+
+// Some tests need to wait until stopping scroll completely. At this time,
+// setTimeout() will retry to check up to MAX_RETRY_COUNT times.
+const MAX_RETRY_COUNT = 5;
+
+const deltaModes = [
+ WheelEvent.DOM_DELTA_PIXEL, // 0
+ WheelEvent.DOM_DELTA_LINE, // 1
+ WheelEvent.DOM_DELTA_PAGE // 2
+];
+
+function sendWheelAndWait(aScrollTaget, aX, aY, aEvent, aChecker)
+{
+ function continueTestsIfScrolledAsExpected() {
+ if (!aChecker())
+ SimpleTest.executeSoon(()=>{ continueTestsIfScrolledAsExpected(aChecker) });
+ else
+ runTests();
+ }
+
+ sendWheelAndPaint(aScrollTaget, aX, aY, aEvent, ()=>{
+ // sendWheelAndPaint may wait not enough for <scrollbox>.
+ // Let's check the position before using is() for avoiding random orange.
+ // So, this test may detect regressions with timeout.
+ continueTestsIfScrolledAsExpected(aChecker);
+ });
+}
+
+function* testRichListbox(id)
+{
+ var listbox = document.getElementById(id);
+
+ function* helper(aStart, aDelta, aIntDelta, aDeltaMode) {
+ listbox.ensureElementIsVisible(listbox.getItemAtIndex(aStart),true);
+
+ let event = {
+ deltaMode: aDeltaMode,
+ deltaY: aDelta,
+ lineOrPageDeltaY: aIntDelta
+ };
+ // We don't need to wait for finishing the scroll in this test.
+ yield sendWheelAndWait(listbox, 10, 10, event, ()=>{ return true; });
+ var change = listbox.getIndexOfFirstVisibleRow() - aStart;
+ var direction = (change > 0) - (change < 0);
+ var expected = (aDelta > 0) - (aDelta < 0);
+ is(direction, expected,
+ "testRichListbox(" + id + "): vertical, starting " + aStart +
+ " delta " + aDelta + " lineOrPageDeltaY " + aIntDelta +
+ " aDeltaMode " + aDeltaMode);
+
+ // Check that horizontal scrolling has no effect
+ event = {
+ deltaMode: aDeltaMode,
+ deltaX: aDelta,
+ lineOrPageDeltaX: aIntDelta
+ };
+
+ listbox.ensureElementIsVisible(listbox.getItemAtIndex(aStart),true);
+ yield sendWheelAndWait(listbox, 10, 10, event, ()=>{ return true; });
+ is(listbox.getIndexOfFirstVisibleRow(), aStart,
+ "testRichListbox(" + id + "): horizontal, starting " + aStart +
+ " delta " + aDelta + " lineOrPageDeltaX " + aIntDelta +
+ " aDeltaMode " + aDeltaMode);
+ }
+
+ // richlistbox currently uses native XUL scrolling, so the "line"
+ // amounts don't necessarily correspond 1-to-1 with listbox items. So
+ // we just check that scrolling up/down scrolls in the right direction.
+ for (let i = 0; i < deltaModes.length; i++) {
+ let delta = (deltaModes[i] == WheelEvent.DOM_DELTA_PIXEL) ? 32.0 : 2.0;
+ yield* helper(5, -delta, -1, deltaModes[i]);
+ yield* helper(5, -delta, 0, deltaModes[i]);
+ yield* helper(5, delta, 1, deltaModes[i]);
+ yield* helper(5, delta, 0, deltaModes[i]);
+ }
+}
+
+function* testArrowScrollbox(id)
+{
+ var arrowscrollbox = document.getElementById(id);
+ var scrollbox = arrowscrollbox.scrollbox;
+ var orient = scrollbox.getAttribute("orient");
+ var orientIsHorizontal = (orient == "horizontal");
+
+ function* helper(aStart, aDelta, aDeltaMode, aExpected)
+ {
+ var lineOrPageDelta = (aDeltaMode == WheelEvent.DOM_DELTA_PIXEL) ? aDelta / 10 : aDelta;
+
+ scrollbox.scrollTo(aStart, aStart);
+ for (let i = orientIsHorizontal ? 2 : 0; i >= 0; i--) {
+ // Note, vertical mouse scrolling is allowed to scroll horizontal
+ // arrowscrollboxes, because many users have no horizontal mouse scroll
+ // capability
+ let expected = !i ? aExpected : aStart;
+ let getPos = ()=>{
+ return orientIsHorizontal ? scrollbox.scrollLeft :
+ scrollbox.scrollTop;
+ };
+ let oldPos = -1;
+ let retry = 0;
+ yield sendWheelAndWait(scrollbox, 5, 5,
+ { deltaMode: aDeltaMode, deltaY: aDelta,
+ lineOrPageDeltaY: lineOrPageDelta },
+ ()=>{
+ if (getPos() == expected) {
+ return true;
+ }
+ if (oldPos == getPos()) {
+ // If scroll stopped completely, let's continue the test.
+ return ++retry == MAX_RETRY_COUNT;
+ }
+ oldPos = getPos();
+ retry = 0;
+ return false;
+ });
+ is(getPos(), expected,
+ "testArrowScrollbox(" + id + "): vertical, starting " + aStart +
+ " delta " + aDelta + " lineOrPageDelta " + lineOrPageDelta +
+ " aDeltaMode " + aDeltaMode);
+ }
+
+ scrollbox.scrollTo(aStart, aStart);
+ for (let i = orientIsHorizontal ? 2 : 0; i >= 0; i--) {
+ // horizontal mouse scrolling is never allowed to scroll vertical
+ // arrowscrollboxes
+ let expected = (!i && orientIsHorizontal) ? aExpected : aStart;
+ let getPos = ()=>{
+ return orientIsHorizontal ? scrollbox.scrollLeft :
+ scrollbox.scrollTop;
+ };
+ let oldPos = -1;
+ let retry = 0;
+ yield sendWheelAndWait(scrollbox, 5, 5,
+ { deltaMode: aDeltaMode, deltaX: aDelta,
+ lineOrPageDeltaX: lineOrPageDelta },
+ ()=>{
+ if (getPos() == expected) {
+ return true;
+ }
+ if (oldPos == getPos()) {
+ // If scroll stopped completely, let's continue the test.
+ return ++retry == MAX_RETRY_COUNT;
+ }
+ oldPos = getPos();
+ retry = 0;
+ return false;
+ });
+ is(getPos(), expected,
+ "testArrowScrollbox(" + id + "): horizontal, starting " + aStart +
+ " delta " + aDelta + " lineOrPageDelta " + lineOrPageDelta +
+ " aDeltaMode " + aDeltaMode);
+ }
+ }
+
+ var line = arrowscrollbox.lineScrollAmount;
+ var scrolledWidth = scrollbox.scrollWidth;
+ var scrolledHeight = scrollbox.scrollHeight;
+ var scrollMaxX = scrolledWidth - scrollbox.getBoundingClientRect().width;
+ var scrollMaxY = scrolledHeight - scrollbox.getBoundingClientRect().height;
+ var scrollMax = orientIsHorizontal ? scrollMaxX : scrollMaxY;
+
+ for (let deltaMode of deltaModes) {
+ const start = 50;
+ const delta = 1000;
+ let expectedNegative = 0;
+ let expectedPositive = scrollMax;
+ if (deltaMode == WheelEvent.DOM_DELTA_LINE) {
+ let maxDelta = Math.floor(Math.max(1, arrowscrollbox.scrollClientSize / line)) * line;
+ expectedNegative = Math.max(0, start - maxDelta);
+ expectedPositive = Math.min(scrollMax, start + maxDelta);
+ }
+ yield* helper(start, -delta, deltaMode, expectedNegative);
+ yield* helper(start, delta, deltaMode, expectedPositive);
+ }
+}
+
+var gTestContinuation = null;
+
+function runTests()
+{
+ if (!gTestContinuation) {
+ gTestContinuation = testBody();
+ }
+ var ret = gTestContinuation.next();
+ if (ret.done) {
+ var winUtils = SpecialPowers.getDOMWindowUtils(window);
+ winUtils.restoreNormalRefresh();
+ SimpleTest.finish();
+ }
+}
+
+async function prepareRunningTests()
+{
+ // Before actually running tests, we disable auto-dir scrolling, becasue the
+ // horizontal scrolling tests in this file are mostly meant to ensure that the
+ // tested controls in the default style should only have one scrollbar and it
+ // must always be in the block-flow direction so they are not really meant to
+ // test default actions for wheel events, so we simply disabled auto-dir
+ // scrolling, which are well tested in
+ // dom/events/test/window_wheel_default_action.html.
+ await SpecialPowers.pushPrefEnv({"set": [["mousewheel.autodir.enabled",
+ false]]});
+
+ runTests();
+}
+
+function* testBody()
+{
+ yield* testRichListbox("richlistbox");
+
+ // Perform a mousedown to ensure the wheel transaction from the previous test
+ // does not impact the next test.
+ synthesizeMouse(document.scrollingElement, 0, 0, {type: "mousedown"}, window);
+ yield* testArrowScrollbox("hscrollbox");
+
+ synthesizeMouse(document.scrollingElement, -1, -1, {type: "mousedown"}, window);
+ yield* testArrowScrollbox("vscrollbox");
+}
+
+ ]]></script>
+</window>