Fix tests that depend on synchronous scrolling. (bug 1140293, r=mstange,masayuki,kgilbert)

This commit is contained in:
dvander@alliedmods.net 2015-04-07 18:20:43 -07:00
parent 921f82d97a
commit d6e650ec3e
10 changed files with 243 additions and 98 deletions

View File

@ -1033,6 +1033,12 @@ nsDOMWindowUtils::SendWheelEvent(float aX,
widget->DispatchAPZAwareEvent(&wheelEvent);
if (gfxPrefs::AsyncPanZoomEnabled()) {
// Computing overflow deltas is not compatible with APZ, so if APZ is
// enabled, we skip testing it.
return NS_OK;
}
bool failedX = false;
if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_ZERO) &&
wheelEvent.overflowDeltaX != 0) {

View File

@ -20,7 +20,37 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=574663
/** Test for Bug 574663 **/
function sendTouchpadScrollMotion(scrollbox, direction, ctrl, momentum) {
// SimpleTest's paint_listener does not work on other windows, so we inline
// a smaller version here.
function waitForPaint(win, utils, callback) {
win.document.documentElement.getBoundingClientRect();
if (!utils.isMozAfterPaintPending) {
callback();
return;
}
var onpaint = function() {
if (!utils.isMozAfterPaintPending) {
win.removeEventListener("MozAfterPaint", onpaint);
callback();
return;
}
}
win.addEventListener("MozAfterPaint", onpaint);
if (utils.isTestControllingRefreshes) {
utils.advanceTimeAndRefresh(0);
}
}
function forceScrollAndWait(scrollbox, callback) {
let win = scrollbox.ownerDocument.defaultView;
let utils = SpecialPowers.getDOMWindowUtils(win);
utils.advanceTimeAndRefresh(1000);
waitForPaint(win, utils, callback);
}
function sendTouchpadScrollMotion(scrollbox, direction, ctrl, momentum, callback) {
var win = scrollbox.ownerDocument.defaultView;
let event = {
deltaMode: WheelEvent.DOM_DELTA_PIXEL,
@ -29,10 +59,26 @@ function sendTouchpadScrollMotion(scrollbox, direction, ctrl, momentum) {
ctrlKey: ctrl,
isMomentum: momentum
};
let kExtraEvents = 5;
var received = 0;
var onwheel = function() {
if (++received == 1 + kExtraEvents) {
// We have captured all the outstanding wheel events. Wait for the
// animation to add itself to the refresh driver.
scrollbox.removeEventListener("wheel", onwheel);
setTimeout(function() {
forceScrollAndWait(scrollbox, callback);
}, 0);
}
};
scrollbox.addEventListener("wheel", onwheel);
synthesizeWheel(scrollbox, 10, 10, event, win);
// then 5 additional pixel scrolls
event.lineOrPageDeltaY = 0;
for (let i = 0; i < 5; ++i) {
for (let i = 1; i <= kExtraEvents; ++i) {
synthesizeWheel(scrollbox, 10, 10, event, win);
}
}
@ -57,21 +103,11 @@ function runTest() {
winUtils.advanceTimeAndRefresh(1000);
function nextTest() {
if (!outstandingTests.length) {
winUtils.restoreNormalRefresh();
win.close();
SimpleTest.finish();
return;
}
let [ctrlKey, isMomentum] = outstandingTests.shift();
let scrollTopBefore = scrollbox.scrollTop;
let zoomFactorBefore = winUtils.fullZoom;
sendTouchpadScrollMotion(scrollbox, 1, ctrlKey, isMomentum);
winUtils.advanceTimeAndRefresh(1000); // force scrolling to happen
setTimeout(function () {
let check = function() {
if (!ctrlKey) {
let postfix = isMomentum ? ", even after releasing the touchpad" : "";
// Normal scroll: scroll
@ -86,12 +122,21 @@ function runTest() {
isnot(scrollbox.scrollTop, scrollTopBefore, "Momentum scrolling should scroll, even when pressing Ctrl");
}
}
// Revert the effect.
sendTouchpadScrollMotion(scrollbox, -1, ctrlKey, isMomentum);
winUtils.advanceTimeAndRefresh(1000); // force scrolling to happen
setTimeout(nextTest, 20);
}, 20);
if (!outstandingTests.length) {
winUtils.restoreNormalRefresh();
win.close();
SimpleTest.finish();
return;
}
// Revert the effect for the next test.
sendTouchpadScrollMotion(scrollbox, -1, ctrlKey, isMomentum, function() {
setTimeout(nextTest, 0);
});
}
sendTouchpadScrollMotion(scrollbox, 1, ctrlKey, isMomentum, check);
}
nextTest();
}, win);
@ -106,7 +151,6 @@ window.onload = function() {
}
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("untriaged");
</script>
</pre>

View File

@ -4,6 +4,7 @@
<title>Test for default action of WheelEvent</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
@ -68,6 +69,11 @@ function ok()
window.opener.ok.apply(window.opener, arguments);
}
function sendWheelAndWait(aX, aY, aEvent, aCallback)
{
sendWheelAndPaint(gScrollableElement, aX, aY, aEvent, aCallback);
}
function hitEventLoop(aFunc, aTimes)
{
winUtils.advanceTimeAndRefresh(100);
@ -864,9 +870,7 @@ function doTestScroll(aSettings, aCallback)
currentTest.prepare();
}
synthesizeWheel(gScrollableElement, 10, 10, currentTest.event);
hitEventLoop(function () {
sendWheelAndWait(10, 10, currentTest.event, function () {
if (currentTest.expected == kNoScroll) {
is(gScrollableElement.scrollTop, 1000, description + "scrolled vertical");
is(gScrollableElement.scrollLeft, 1000, description + "scrolled horizontal");
@ -1111,7 +1115,6 @@ function doTestZoom(aSettings, aCallback)
var event = currentTest.event;
event.ctrlKey = true;
synthesizeWheel(gScrollableElement, 10, 10, event);
// NOTE: Zooming might change scrollTop and scrollLeft by rounding fraction.
// This test assume that zoom happens synchronously and scrolling
@ -1119,7 +1122,7 @@ function doTestZoom(aSettings, aCallback)
var scrollTop = gScrollableElement.scrollTop;
var scrollLeft = gScrollableElement.scrollLeft;
hitEventLoop(function () {
sendWheelAndWait(10, 10, event, function () {
is(gScrollableElement.scrollTop, scrollTop, description + "scrolled vertical");
is(gScrollableElement.scrollLeft, scrollLeft, description + "scrolled horizontal");
if (!(currentTest.expected & (kNegative | kPositive))) {
@ -1190,11 +1193,15 @@ function doTestZoomedScroll(aCallback)
}
window.addEventListener("MozMousePixelScroll", mousePixelScrollHandler, true);
window.addEventListener("wheel", wheelHandler, true);
synthesizeWheel(gScrollableElement, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_PIXEL,
deltaX: 16.0, deltaY: 16.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 0 });
var event = {
deltaMode: WheelEvent.DOM_DELTA_PIXEL,
deltaX: 16.0,
deltaY: 16.0,
lineOrPageDeltaX: 0,
lineOrPageDeltaY: 0
};
// wait scrolled actually.
hitEventLoop(function () {
sendWheelAndWait(10, 10, event, function () {
var scrolledX = gScrollableElement.scrollLeft;
var scrolledY = gScrollableElement.scrollTop;
ok(scrolledX > 1000,
@ -1208,11 +1215,15 @@ function doTestZoomedScroll(aCallback)
hitEventLoop(function () {
gScrollableElement.scrollTop = 1000;
gScrollableElement.scrollLeft = 1000;
synthesizeWheel(gScrollableElement, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_PIXEL,
deltaX: 16.0, deltaY: 16.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 0 });
var event = {
deltaMode: WheelEvent.DOM_DELTA_PIXEL,
deltaX: 16.0,
deltaY: 16.0,
lineOrPageDeltaX: 0,
lineOrPageDeltaY: 0
};
// wait scrolled actually.
hitEventLoop(function () {
sendWheelAndWait(10, 10, event, function () {
ok(Math.abs(gScrollableElement.scrollLeft - (1000 + (scrolledX - 1000) / 2)) <= 1,
"doTestZoomedScroll: zoomed horizontal scroll amount by pixel wheel event is different from normal, scrollLeft=" +
gScrollableElement.scrollLeft + ", scrolledX=" + scrolledX);
@ -1267,11 +1278,15 @@ function doTestZoomedScroll(aCallback)
}
}
window.addEventListener("MozMousePixelScroll", handler, true);
synthesizeWheel(gScrollableElement, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 });
var event = {
deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0,
deltaY: 1.0,
lineOrPageDeltaX: 1,
lineOrPageDeltaY: 1
};
// wait scrolled actually.
hitEventLoop(function () {
sendWheelAndWait(10, 10, event, function () {
var scrolledX = gScrollableElement.scrollLeft;
var scrolledY = gScrollableElement.scrollTop;
ok(scrolledX > 1000,
@ -1285,11 +1300,15 @@ function doTestZoomedScroll(aCallback)
hitEventLoop(function () {
gScrollableElement.scrollTop = 1000;
gScrollableElement.scrollLeft = 1000;
synthesizeWheel(gScrollableElement, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 });
var event = {
deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0,
deltaY: 1.0,
lineOrPageDeltaX: 1,
lineOrPageDeltaY: 1
};
// wait scrolled actually.
hitEventLoop(function () {
sendWheelAndWait(10, 10, event, function () {
ok(Math.abs(gScrollableElement.scrollLeft - scrolledX) <= 1,
"doTestZoomedScroll: zoomed horizontal scroll amount by line wheel event is different from normal, scrollLeft=" +
gScrollableElement.scrollLeft + ", scrolledX=" + scrolledX);
@ -1549,8 +1568,7 @@ function doTestWholeScroll(aCallback)
if (kTest.prepare) {
kTest.prepare();
}
synthesizeWheel(gScrollableElement, 10, 10, kTest.event);
hitEventLoop(function () {
sendWheelAndWait(10, 10, kTest.event, function () {
is(gScrollableElement.scrollTop, kTest.expectedScrollTop,
"doTestWholeScroll, " + kTest.description + ": unexpected scrollTop");
is(gScrollableElement.scrollLeft, kTest.expectedScrollLeft,
@ -1700,8 +1718,7 @@ function doTestActionOverride(aCallback)
SpecialPowers.setIntPref("mousewheel.default.action.override_x", kTest.override_x);
gScrollableElement.scrollTop = 1000;
gScrollableElement.scrollLeft = 1000;
synthesizeWheel(gScrollableElement, 10, 10, kTest.event);
hitEventLoop(function () {
sendWheelAndWait(10, 10, kTest.event, function () {
if (kTest.expected & kScrollUp) {
ok(gScrollableElement.scrollTop < 1000, description + "not scrolled up, got " + gScrollableElement.scrollTop);
} else if (kTest.expected & kScrollDown) {

View File

@ -128,7 +128,7 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e1
[test_plugin_position.xhtml]
skip-if = e10s
[test_scroll_behavior.html]
skip-if = e10s || buildapp == 'b2g' # Bug 1062609
skip-if = buildapp == 'b2g' # Bug 1062609
[test_selection_expanding.html]
skip-if = buildapp == 'mulet' || buildapp == 'b2g' # b2g(mouse selection not working) b2g-debug(mouse selection not working) b2g-desktop(mouse selection not working)
support-files = selection_expanding_xbl.xml

View File

@ -4,6 +4,7 @@
<title>Test bug 784410</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/paint_listener.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
@ -38,13 +39,16 @@ function doneScroll() {
outer.scrollTop = 0;
break;
case 2:
synthesizeWheel(inner, 4, 4,
{ deltaMode: WheelEvent.DOM_DELTA_LINE, deltaY: 1 });
// Wait for paints to flush, so APZ is notified of the new scroll offset.
sendWheelAndPaint(inner, 4, 4,
{ deltaMode: WheelEvent.DOM_DELTA_LINE, deltaY: 1 },
function() {});
break;
case 3:
is(innerScrollOffset(), innerStartScrollOffset, "Inner element should not have scrolled down");
ok(outer.scrollTop > 0, "Outer element should have scrolled down");
SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
SimpleTest.finish();
break;
}

View File

@ -29,19 +29,28 @@
}
window.addEventListener("load", function(event) {
if (event.target == document) {
SpecialPowers.pushPrefEnv(
{ 'set': [['layout.css.scroll-behavior.enabled', true]] },
function () {
testScrollBehaviorInterruption(function() {
testScrollBehaviorFramerate(function() {
window.scrollTo(0,0);
SimpleTest.finish();
});
});
}
);
if (event.target != document)
return;
// See bug 1062609 - these tests do not work with APZ yet. If APZ is
// enabled, end the tests early.
if (SpecialPowers.getBoolPref("layers.async-pan-zoom.enabled")) {
todo(false, "This test does not yet work with APZ.");
SimpleTest.finish();
return;
}
SpecialPowers.pushPrefEnv(
{ 'set': [['layout.css.scroll-behavior.enabled', true]] },
function () {
testScrollBehaviorInterruption(function() {
testScrollBehaviorFramerate(function() {
window.scrollTo(0,0);
SimpleTest.finish();
});
});
}
);
}, false);

View File

@ -5,6 +5,7 @@
* sendChar
* sendString
* sendKey
* sendWheelAndPaint
* synthesizeMouse
* synthesizeMouseAtCenter
* synthesizePointer
@ -430,6 +431,50 @@ function synthesizeWheel(aTarget, aOffsetX, aOffsetY, aEvent, aWindow)
lineOrPageDeltaX, lineOrPageDeltaY, options);
}
/**
* This is a wrapper around synthesizeWheel that waits for the wheel event
* to be dispatched and for the subsequent layout/paints to be flushed.
*
* This requires including paint_listener.js. Tests must call
* DOMWindowUtils.restoreNormalRefresh() before finishing, if they use this
* function.
*/
function sendWheelAndPaint(aTarget, aOffsetX, aOffsetY, aEvent, aCallback, aWindow) {
aWindow = aWindow || window;
var utils = _getDOMWindowUtils(aWindow);
if (!utils)
return;
if (utils.isMozAfterPaintPending) {
// If a paint is pending, then APZ may be waiting for a scroll acknowledgement
// from the content thread. If we send a wheel event now, it could be ignored
// by APZ (or its scroll offset could be overridden). To avoid problems we
// just wait for the paint to complete.
aWindow.waitForAllPaintsFlushed(function() {
sendWheelAndPaint(aTarget, aOffsetX, aOffsetY, aEvent, aCallback, aWindow);
});
return;
}
var onwheel = function() {
window.removeEventListener("wheel", onwheel);
// Wait one frame since the wheel event has not caused a refresh observer
// to be added yet.
setTimeout(function() {
utils.advanceTimeAndRefresh(1000);
aWindow.waitForAllPaintsFlushed(function() {
utils.restoreNormalRefresh();
aCallback();
});
}, 0);
};
aWindow.addEventListener("wheel", onwheel);
synthesizeWheel(aTarget, aOffsetX, aOffsetY, aEvent, aWindow);
}
function _computeKeyCodeFromChar(aChar)
{
if (aChar.length != 1) {

View File

@ -8,6 +8,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=378028
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<script type="application/javascript" 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">
@ -138,46 +139,47 @@ function testRichListbox(id, andThen)
var winUtils = SpecialPowers.getDOMWindowUtils(window);
winUtils.advanceTimeAndRefresh(100);
function helper()
{
var [aStart, aDelta, aIntDelta, aDeltaMode] = tests[0];
tests.shift();
function nextTest() {
var [aStart, aDelta, aIntDelta, aDeltaMode] = tests.shift();
listbox.scrollToIndex(aStart);
synthesizeWheel(listbox, 10, 10,
{ deltaMode: aDeltaMode, deltaY: aDelta,
lineOrPageDeltaY: aIntDelta });
winUtils.advanceTimeAndRefresh(100);
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 + " lineOrPageDelta " + aIntDelta +
" aDeltaMode " + aDeltaMode);
// Check that horizontal scrolling has no effect
listbox.scrollToIndex(aStart);
synthesizeWheel(listbox, 10, 10,
{ deltaMode: aDeltaMode, deltaX: aDelta,
lineOrPageDeltaX: aIntDelta });
winUtils.advanceTimeAndRefresh(100);
is(listbox.getIndexOfFirstVisibleRow(), aStart,
"testRichListbox(" + id + "): horizontal, starting " + aStart +
" delta " + aDelta + " lineOrPageDelta " + aIntDelta +
let event = {
deltaMode: aDeltaMode,
deltaY: aDelta,
lineOrPageDeltaY: aIntDelta
};
sendWheelAndPaint(listbox, 10, 10, event, function() {
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);
if (tests.length) {
winUtils.advanceTimeAndRefresh(100);
helper();
} else {
winUtils.restoreNormalRefresh();
andThen();
}
// Check that horizontal scrolling has no effect
let event = {
deltaMode: aDeltaMode,
deltaX: aDelta,
lineOrPageDeltaX: aIntDelta
};
listbox.scrollToIndex(aStart);
sendWheelAndPaint(listbox, 10, 10, event, function() {
is(listbox.getIndexOfFirstVisibleRow(), aStart,
"testRichListbox(" + id + "): horizontal, starting " + aStart +
" delta " + aDelta + " lineOrPageDeltaX " + aIntDelta +
" aDeltaMode " + aDeltaMode);
if (!tests.length) {
winUtils.restoreNormalRefresh();
andThen();
return;
}
nextTest();
});
});
}
// richlistbox currently uses native XUL scrolling, so the "line"
@ -190,7 +192,8 @@ function testRichListbox(id, andThen)
tests.push([5, delta, 1, aDeltaMode]);
tests.push([5, delta, 0, aDeltaMode]);
});
helper();
nextTest();
}
function testArrowScrollbox(id)

View File

@ -6,8 +6,12 @@
onunload="onunload();"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/paint_listener.js" />
<body xmlns="http://www.w3.org/1999/xhtml" id="body">
<style type="text/css">
@ -121,6 +125,7 @@ function onunload()
resetTimeoutPrefs();
disableNonTestMouseEvents(false);
gPrefSvc.clearUserPref(kPrefSmoothScroll);
SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
window.opener.wrappedJSObject.SimpleTest.finish();
}
@ -171,7 +176,9 @@ function fireWheelScrollEvent(aForward)
gIgnoreScrollEvent = false;
var event = { deltaY: aForward ? 4.0 : -4.0,
deltaMode: WheelEvent.DOM_DELTA_LINE };
synthesizeWheel(gView, 5, 5, event, window);
sendWheelAndPaint(gView, 5, 5, event, function() {
// No callback - we're just forcing the refresh driver to tick.
}, window);
}
function onScrollView(aEvent)

View File

@ -6,8 +6,12 @@
onunload="onunload();"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/paint_listener.js" />
<body xmlns="http://www.w3.org/1999/xhtml">
<style type="text/css">
@ -113,11 +117,13 @@ var gPrefSvc = Components.classes["@mozilla.org/preferences-service;1"].
const kPrefSmoothScroll = "general.smoothScroll";
const kPrefNameTimeout = "mousewheel.transaction.timeout";
const kPrefNameIgnoreMoveDelay = "mousewheel.transaction.ignoremovedelay";
const kPrefTestEventsAsyncEnabled = "test.events.async.enabled";
const kDefaultTimeout = gPrefSvc.getIntPref(kPrefNameTimeout);
const kDefaultIgnoreMoveDelay = gPrefSvc.getIntPref(kPrefNameIgnoreMoveDelay);
gPrefSvc.setBoolPref(kPrefSmoothScroll, false);
gPrefSvc.setBoolPref(kPrefTestEventsAsyncEnabled, true);
var gTimeout, gIgnoreMoveDelay;
var gEnoughForTimeout, gEnoughForIgnoreMoveDelay;
@ -175,7 +181,9 @@ function onunload()
{
resetTimeoutPrefs();
gPrefSvc.clearUserPref(kPrefSmoothScroll);
gPrefSvc.clearUserPref(kPrefTestEventsAsyncEnabled);
disableNonTestMouseEvents(false);
SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
window.opener.wrappedJSObject.SimpleTest.finish();
}
@ -1095,7 +1103,9 @@ function _fireWheelScrollEvent(aOffset, aIsVertical, aForward, aDelta)
} else {
event.deltaX = aForward ? aDelta : -aDelta;
}
synthesizeWheel(gRootView, aOffset.x, aOffset.y, event, window);
sendWheelAndPaint(gRootView, aOffset.x, aOffset.y, event, function() {
// No callback - we just wanted to force the refresh driver to tick.
}, window);
}
function _canScroll(aElement, aIsVertical, aForward)