mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 22:32:46 +00:00
f7195cd8ae
Differential Revision: https://phabricator.services.mozilla.com/D86485
1570 lines
64 KiB
HTML
1570 lines
64 KiB
HTML
<?xml version="1.0"?>
|
|
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
|
<window title="Wheel scroll tests"
|
|
width="600" height="600"
|
|
onload="onload();"
|
|
onunload="onunload();"
|
|
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" />
|
|
|
|
<body xmlns="http://www.w3.org/1999/xhtml">
|
|
<style type="text/css">
|
|
#rootview {
|
|
overflow: auto;
|
|
width: 400px;
|
|
height: 400px;
|
|
border: 1px solid;
|
|
}
|
|
#container {
|
|
overflow: auto;
|
|
width: 600px;
|
|
height: 600px;
|
|
}
|
|
#rootview pre {
|
|
margin: 20px 0 20px 20px;
|
|
padding: 0;
|
|
overflow: auto;
|
|
display: block;
|
|
width: 100px;
|
|
height: 100.5px;
|
|
font-size: 16px;
|
|
}
|
|
</style>
|
|
<div id="rootview" onscroll="onScrollView(event);">
|
|
<div id="container">
|
|
<pre id="subview1" onscroll="onScrollView(event);">
|
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
|
</pre>
|
|
<pre id="subview2" onscroll="onScrollView(event);">
|
|
Text.
|
|
Text.
|
|
Text.
|
|
Text.
|
|
Text.
|
|
Text.
|
|
Text.
|
|
Text.
|
|
Text.
|
|
Text.
|
|
</pre>
|
|
<pre id="subview3" onscroll="onScrollView(event);">
|
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div id="content" style="display: none">
|
|
</div>
|
|
<pre id="test">
|
|
</pre>
|
|
</body>
|
|
|
|
<script class="testbody" type="application/javascript">
|
|
<![CDATA[
|
|
|
|
function ok(aCondition, aMessage)
|
|
{
|
|
window.arguments[0].SimpleTest.ok(aCondition, aMessage);
|
|
}
|
|
|
|
function is(aLeft, aRight, aMessage)
|
|
{
|
|
window.arguments[0].SimpleTest.is(aLeft, aRight, aMessage);
|
|
}
|
|
|
|
function isnot(aLeft, aRight, aMessage)
|
|
{
|
|
window.arguments[0].SimpleTest.isnot(aLeft, aRight, aMessage);
|
|
}
|
|
|
|
var gCurrentTestListStatus = { nextListIndex: 0 };
|
|
var gCurrentTest;
|
|
|
|
const kListenEvent_None = 0;
|
|
const kListenEvent_OnScroll = 1;
|
|
const kListenEvent_OnScrollFailed = 2;
|
|
const kListenEvent_OnTransactionTimeout = 4;
|
|
const kListenEvent_All = kListenEvent_OnScroll |
|
|
kListenEvent_OnScrollFailed |
|
|
kListenEvent_OnTransactionTimeout;
|
|
var gLitesnEvents = kListenEvent_None;
|
|
|
|
/**
|
|
* At unexpected transaction timeout, we need to stop *all* timers. But it is
|
|
* difficult and it can be create more complex testing code. So, we should use
|
|
* only one timer at one time. For that, we must store the timer id to this
|
|
* variable. And the functions which may be called via a timer must clear the
|
|
* current timer by |_clearTimer| function.
|
|
*/
|
|
var gTimer;
|
|
|
|
var gPrefSvc = SpecialPowers.Services.prefs;
|
|
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;
|
|
|
|
function setTimeoutPrefs(aTimeout, aIgnoreMoveDelay)
|
|
{
|
|
gPrefSvc.setIntPref(kPrefNameTimeout, aTimeout);
|
|
gPrefSvc.setIntPref(kPrefNameIgnoreMoveDelay, aIgnoreMoveDelay);
|
|
gTimeout = aTimeout;
|
|
gIgnoreMoveDelay = aIgnoreMoveDelay;
|
|
gEnoughForTimeout = gTimeout * 2;
|
|
gEnoughForIgnoreMoveDelay = gIgnoreMoveDelay * 1.2;
|
|
}
|
|
|
|
function resetTimeoutPrefs()
|
|
{
|
|
if (gTimeout == kDefaultTimeout)
|
|
return;
|
|
setTimeoutPrefs(kDefaultTimeout, kDefaultIgnoreMoveDelay);
|
|
initTestList();
|
|
}
|
|
|
|
function growUpTimeoutPrefs()
|
|
{
|
|
if (gTimeout != kDefaultTimeout)
|
|
return;
|
|
setTimeoutPrefs(5000, 1000);
|
|
initTestList();
|
|
}
|
|
|
|
// setting enough time for testing.
|
|
gPrefSvc.setIntPref(kPrefNameTimeout, gTimeout);
|
|
gPrefSvc.setIntPref(kPrefNameIgnoreMoveDelay, gIgnoreMoveDelay);
|
|
|
|
var gRootView = document.getElementById("rootview");
|
|
var gSubView1 = document.getElementById("subview1");
|
|
var gSubView2 = document.getElementById("subview2");
|
|
var gSubView3 = document.getElementById("subview3");
|
|
|
|
gRootView.addEventListener("MozMouseScrollFailed", onMouseScrollFailed);
|
|
gRootView.addEventListener("MozMouseScrollTransactionTimeout",
|
|
onTransactionTimeout);
|
|
|
|
function finish()
|
|
{
|
|
window.close();
|
|
}
|
|
|
|
async function onload()
|
|
{
|
|
// Before actually running tests, we disable auto-dir scrolling, becasue the
|
|
// tests in this file are meant to test scrolling transactions, not 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]]});
|
|
|
|
runNextTestList();
|
|
}
|
|
|
|
function onunload()
|
|
{
|
|
resetTimeoutPrefs();
|
|
gPrefSvc.clearUserPref(kPrefSmoothScroll);
|
|
gPrefSvc.clearUserPref(kPrefTestEventsAsyncEnabled);
|
|
disableNonTestMouseEvents(false);
|
|
SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
|
|
window.arguments[0].SimpleTest.finish();
|
|
}
|
|
|
|
function offsetForRootView()
|
|
{
|
|
let rootViewRect = gRootView.getBoundingClientRect();
|
|
let subView1Rect = gSubView1.getBoundingClientRect();
|
|
return {
|
|
x: (subView1Rect.left - rootViewRect.left) / 2,
|
|
y: (subView1Rect.top - rootViewRect.top) / 2,
|
|
}
|
|
}
|
|
|
|
function _offsetFor(aSubView)
|
|
{
|
|
let rootViewRect = gRootView.getBoundingClientRect();
|
|
let subViewRect = aSubView.getBoundingClientRect();
|
|
return {
|
|
x: subViewRect.left - rootViewRect.left + subViewRect.width / 2,
|
|
y: subViewRect.top - rootViewRect.top + subViewRect.height / 2,
|
|
}
|
|
}
|
|
|
|
function offsetForSubView1()
|
|
{
|
|
return _offsetFor(gSubView1);
|
|
}
|
|
|
|
function offsetForSubView2()
|
|
{
|
|
return _offsetFor(gSubView2);
|
|
}
|
|
|
|
function offsetForSubView3()
|
|
{
|
|
return _offsetFor(gSubView3);
|
|
}
|
|
|
|
/**
|
|
* Define the tests here:
|
|
* Scrolls are processed async always. Therefore, we need to call all tests
|
|
* by timer. gTestLists is array of testing lists. In other words, an item
|
|
* of gTestList is a group of one or more testing. Each items has following
|
|
* properties:
|
|
*
|
|
* - retryWhenTransactionTimeout
|
|
* The testing of wheel transaction might be fialed randomly by
|
|
* timeout. Then, automatically the failed test list will be retested
|
|
* automatically only this number of times.
|
|
*
|
|
* - steps
|
|
* This property is array of testing. Each steps must have following
|
|
* properties at least.
|
|
*
|
|
* - func
|
|
* This property means function which will be called via
|
|
* |setTimeout|. The function cannot have params. If you need
|
|
* some additional parameters, you can specify some original
|
|
* properties for the test function. If you do so, you should
|
|
* document it in the testing function.
|
|
* - delay
|
|
* This property means delay time until the function to be called.
|
|
* I.e., the value used for the second param of |setTimeout|.
|
|
*
|
|
* And also you need one more property when you call a testing function.
|
|
*
|
|
* - description
|
|
* This property is description of the test. This is used for
|
|
* logging.
|
|
*
|
|
* At testing, you can access to current step via |gCurrentTest|.
|
|
*/
|
|
|
|
var gTestLists;
|
|
function initTestList()
|
|
{
|
|
gTestLists = [
|
|
/**************************************************************************
|
|
* Continuous scrolling test for |gRootView|
|
|
* |gRootView| has both scrollbars and it has three children which are
|
|
* |gSubView1|, |gSubView2| and |gSubView3|. They have scrollbars. If
|
|
* the current transaction targets |gRootView|, other children should not
|
|
* be scrolled even if the wheel events are fired on them.
|
|
**************************************************************************/
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Vertical case
|
|
{ func: initElements, delay: 0, forVertical: true,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Vertical wheel events should scroll |gRootView| even if the position
|
|
// of wheel events in a child view which has scrollbar.
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
description: "Continuous scrolling test for root view (vertical/forward)" },
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: false, isVertical: true, expectedView: gRootView,
|
|
description: "Continuous scrolling test for root view (vertical/backward)" }
|
|
]
|
|
},
|
|
|
|
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Horizontal case
|
|
{ func: initElements, delay: 0, forVertical: false,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Horizontal wheel events should scroll |gRootView| even if the
|
|
// position of wheel events in a child view which has scrollbar.
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: true, isVertical: false, expectedView: gRootView,
|
|
description: "Continuous scrolling test for root view (horizontal/forward)" },
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: false, isVertical: false, expectedView: gRootView,
|
|
description: "Continuous scrolling test for root view (horizontal/backward)" }
|
|
]
|
|
},
|
|
|
|
|
|
/**************************************************************************
|
|
* Continuous scrolling test for |gSubView1|
|
|
* |gSubView1| has both scrollbars.
|
|
**************************************************************************/
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Vertical case
|
|
{ func: initElements, delay: 0, forVertical: true,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Vertical wheel events should scroll |gSubView1|.
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gSubView1,
|
|
description: "Continuous scrolling test for sub view 1 (vertical/forward)" },
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: false, isVertical: true, expectedView: gSubView1,
|
|
description: "Continuous scrolling test for sub view 1 (vertical/backward)" }
|
|
]
|
|
},
|
|
|
|
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Horizontal case
|
|
{ func: initElements, delay: 0, forVertical: false,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Horitontal wheel events should scroll |gSubView1|.
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: gSubView1,
|
|
description: "Continuous scrolling test for sub view 1 (horizontal/forward)" },
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: false, isVertical: false, expectedView: gSubView1,
|
|
description: "Continuous scrolling test for sub view 1 (horizontal/backward)" }
|
|
]
|
|
},
|
|
|
|
|
|
/**************************************************************************
|
|
* Continuous scrolling test for |gSubView2|
|
|
* |gSubView2| has only vertical scrollbar.
|
|
**************************************************************************/
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Vertical case
|
|
{ func: initElements, delay: 0, forVertical: true,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Vertical wheel events should scroll |gSubView2|.
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForSubView2,
|
|
isForward: true, isVertical: true, expectedView: gSubView2,
|
|
description: "Continuous scrolling test for sub view 2 (vertical/forward)" },
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForSubView2,
|
|
isForward: false, isVertical: true, expectedView: gSubView2,
|
|
description: "Continuous scrolling test for sub view 2 (vertical/backward)" }
|
|
]
|
|
},
|
|
|
|
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Horizontal case
|
|
{ func: initElements, delay: 0, forVertical: false,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Horizontal wheel events should scroll its nearest scrollable ancestor
|
|
// view, i.e., it is |gRootView|.
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForSubView2,
|
|
isForward: true, isVertical: false, expectedView: gRootView,
|
|
description: "Continuous scrolling test for sub view 2 (horizontal/forward)" },
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForSubView2,
|
|
isForward: false, isVertical: false, expectedView: gRootView,
|
|
description: "Continuous scrolling test for sub view 2 (horizontal/backward)" }
|
|
]
|
|
},
|
|
|
|
|
|
/**************************************************************************
|
|
* Continuous scrolling test for |gSubView3|
|
|
* |gSubView3| has only horizontal scrollbar.
|
|
**************************************************************************/
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Vertical case
|
|
{ func: initElements, delay: 0, forVertical: true,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Vertical wheel events should scroll its nearest scrollable ancestor
|
|
// view, i.e., it is |gRootView|.
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForSubView3,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
description: "Continuous scrolling test for sub view 3 (vertical/forward)" },
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForSubView3,
|
|
isForward: false, isVertical: true, expectedView: gRootView,
|
|
description: "Continuous scrolling test for sub view 3 (vertical/backward)" }
|
|
]
|
|
},
|
|
|
|
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Horizontal case
|
|
{ func: initElements, delay: 0, forVertical: false,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Horitontal wheel events should scroll |gSubView3|.
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForSubView3,
|
|
isForward: true, isVertical: false, expectedView: gSubView3,
|
|
description: "Continuous scrolling test for sub view 3 (horizontal/forward)" },
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForSubView3,
|
|
isForward: false, isVertical: false, expectedView: gSubView3,
|
|
description: "Continuous scrolling test for sub view 3 (horizontal/backward)" }
|
|
]
|
|
},
|
|
|
|
|
|
/**************************************************************************
|
|
* Don't reset transaction by a different direction wheel event
|
|
* Even if a wheel event doesn't same direction as last wheel event, the
|
|
* current transaction should not be reset.
|
|
**************************************************************************/
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Vertical -> Horizontal
|
|
{ func: initElements, delay: 0, forVertical: true,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Create a transaction which targets |gRootView| by a vertical wheel
|
|
// event.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
description: "Don't reset transaction by a different direction wheel event (1-1)" },
|
|
// Scroll back to top-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: false, isVertical: true, expectedView: gRootView,
|
|
description: "Don't reset transaction by a different direction wheel event (1-2)" },
|
|
// Send a horizontal wheel event over |gSubView1| but |gRootView| should
|
|
// be scrolled.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Don't reset transaction by a different direction wheel event (1-3)" }
|
|
]
|
|
},
|
|
|
|
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Horizontal -> Vertical
|
|
{ func: initElements, delay: 0, forVertical: false,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Create a transaction which targets |gRootView| by a horizontal wheel
|
|
// event.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: true, isVertical: false, expectedView: gRootView,
|
|
description: "Don't reset transaction by a different direction wheel event (2-1)" },
|
|
// Scroll back to left-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: false, isVertical: false, expectedView: gRootView,
|
|
description: "Don't reset transaction by a different direction wheel event (2-2)" },
|
|
// Send a vertical wheel event over |gSubView1| but |gRootView| should
|
|
// be scrolled.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Don't reset transaction by a different direction wheel event (2-3)" }
|
|
]
|
|
},
|
|
|
|
|
|
/**************************************************************************
|
|
* Don't reset transaction even if a wheel event cannot scroll
|
|
* Even if a wheel event cannot scroll to specified direction in the
|
|
* current target view, the transaction should not be reset. E.g., there
|
|
* are some devices which can scroll obliquely. If so, probably, users
|
|
* cannot input only intended direction.
|
|
**************************************************************************/
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// A view only has vertical scrollbar case.
|
|
{ func: initElements, delay: 0, forVertical: true,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Create a transaction which targets |gSubView2|.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView2,
|
|
isForward: true, isVertical: true, expectedView: gSubView2,
|
|
description: "Don't reset transaction even if a wheel event cannot scroll (1-1)" },
|
|
// |gSubView2| doesn't have horizontal scrollbar but should not scroll
|
|
// any views.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView2,
|
|
isForward: true, isVertical: false, expectedView: null,
|
|
description: "Don't reset transaction even if a wheel event cannot scroll (1-2)" }
|
|
]
|
|
},
|
|
|
|
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// A view only has horizontal scrollbar case.
|
|
{ func: initElements, delay: 0, forVertical: true,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Create a transaction which targets |gSubView3|.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView3,
|
|
isForward: true, isVertical: false, expectedView: gSubView3,
|
|
description: "Don't reset transaction even if a wheel event cannot scroll (2-1)" },
|
|
// |gSubView3| doesn't have vertical scrollbar but should not scroll any
|
|
// views.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView3,
|
|
isForward: true, isVertical: true, expectedView: null,
|
|
description: "Don't reset transaction even if a wheel event cannot scroll (2-2)" }
|
|
]
|
|
},
|
|
|
|
|
|
/**************************************************************************
|
|
* Reset transaction by mouse down/mouse up events
|
|
* Mouse down and mouse up events should cause resetting the current
|
|
* transaction.
|
|
**************************************************************************/
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Vertical case
|
|
{ func: initElements, delay: 0, forVertical: true,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Create a transaction which targets |gRootView|.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
description: "Reset transaction by mouse down/mouse up events (v-1)" },
|
|
// Scroll back to top-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: false, isVertical: true, expectedView: gRootView,
|
|
description: "Reset transaction by mouse down/mouse up events (v-2)" },
|
|
// Send mouse button events which should reset the current transaction.
|
|
// So, the next wheel event should scroll |gSubView1|.
|
|
{ func: sendMouseButtonEvents, delay: 0,
|
|
description: "sendMouseButtonEvents" },
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gSubView1,
|
|
description: "Reset transaction by mouse down/mouse up events (v-3)" }
|
|
]
|
|
},
|
|
|
|
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Horizontal case
|
|
{ func: initElements, delay: 0, forVertical: false,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Create a transaction which targets |gRootView|.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: true, isVertical: false, expectedView: gRootView,
|
|
description: "Reset transaction by mouse down/mouse up events (h-1)" },
|
|
// Scroll back to left-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: false, isVertical: false, expectedView: gRootView,
|
|
description: "Reset transaction by mouse down/mouse up events (h-2)" },
|
|
// Send mouse button events which should reset the current transaction.
|
|
// So, the next wheel event should scroll |gSubView1|.
|
|
{ func: sendMouseButtonEvents, delay: 0,
|
|
description: "sendMouseButtonEvents" },
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: gSubView1,
|
|
description: "Reset transaction by mouse down/mouse up events (h-3)" }
|
|
]
|
|
},
|
|
|
|
|
|
/**************************************************************************
|
|
* Reset transaction by a key event
|
|
* A key event should cause resetting the current transaction.
|
|
**************************************************************************/
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Vertical case
|
|
{ func: initElements, delay: 0, forVertical: true,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Create a transaction which targets |gRootView|.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
description: "Reset transaction by a key event (v-1)" },
|
|
// Scroll back to top-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: false, isVertical: true, expectedView: gRootView,
|
|
description: "Reset transaction by a key event (v-2)" },
|
|
// Send a key event which should reset the current transaction. So, the
|
|
// next wheel event should scroll |gSubView1|.
|
|
{ func: sendKeyEvents, delay: 0, key: "a",
|
|
description: "sendKeyEvents" },
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gSubView1,
|
|
description: "Reset transaction by a key event (v-3)" }
|
|
]
|
|
},
|
|
|
|
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Horizontal case
|
|
{ func: initElements, delay: 0, forVertical: false,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Create a transaction which targets |gRootView|.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: true, isVertical: false, expectedView: gRootView,
|
|
description: "Reset transaction by a key event (h-1)" },
|
|
// Scroll back to left-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: false, isVertical: false, expectedView: gRootView,
|
|
description: "Reset transaction by a key event (h-2)" },
|
|
// Send a key event which should reset the current transaction. So, the
|
|
// next wheel event should scroll |gSubView1|.
|
|
{ func: sendKeyEvents, delay: 0, key: "a",
|
|
description: "sendKeyEvents" },
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: gSubView1,
|
|
description: "Reset transaction by a key event (h-3)" }
|
|
]
|
|
},
|
|
|
|
|
|
/**************************************************************************
|
|
* Reset transaction by a mouse move event
|
|
* A mouse move event can cause reseting the current transaction even if
|
|
* mouse cursor is inside the target view of current transaction. Only
|
|
* when a wheel event is fired after |gIgnoreMoveDelay| milliseconds since
|
|
* the first mouse move event from last wheel event, the transaction
|
|
* should be reset.
|
|
**************************************************************************/
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Vertical case
|
|
{ func: initElements, delay: 0, forVertical: true,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Create a transaction which targets |gRootView|.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
description: "Reset transaction by a mouse move event (v-1)" },
|
|
// Scroll back to top-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: false, isVertical: true, expectedView: gRootView,
|
|
description: "Reset transaction by a mouse move event (v-2)" },
|
|
// Send a mouse move event immediately after last wheel event, then,
|
|
// current transaction should be kept.
|
|
{ func: sendMouseMoveEvent, delay: 0, offset: offsetForSubView1,
|
|
description: "sendMouseMoveEvent" },
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Reset transaction by a mouse move event (v-3)" },
|
|
// Scroll back to top-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: false, isVertical: true, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Reset transaction by a mouse move event (v-4)" },
|
|
// Send a mouse move event after |gIgnoreMoveDelay| milliseconds since
|
|
// last wheel event, then, current transaction should be kept.
|
|
{ func: sendMouseMoveEvent, delay: gEnoughForIgnoreMoveDelay,
|
|
offset: offsetForSubView1,
|
|
description: "sendMouseMoveEvent" },
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Reset transaction by a mouse move event (v-5)" },
|
|
// Scroll back to top-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: false, isVertical: true, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Reset transaction by a mouse move event (v-6)" },
|
|
// Send a wheel event after |gIgnoreMoveDelay| milliseconds since last
|
|
// mouse move event but it is fired immediately after the last wheel
|
|
// event, then, current transaction should be kept.
|
|
{ func: sendMouseMoveEvent, delay: 0, offset: offsetForSubView1,
|
|
description: "sendMouseMoveEvent" },
|
|
{ func: testOneTimeScroll, delay: gEnoughForIgnoreMoveDelay,
|
|
offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Reset transaction by a mouse move event (v-7)" },
|
|
// Scroll back to top-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: false, isVertical: true, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Reset transaction by a mouse move event (v-8)" },
|
|
// Send a wheel event after |gIgnoreMoveDelay| milliseconds have passed
|
|
// since last mouse move event which is fired after |gIgnoreMoveDelay|
|
|
// milliseconds since last wheel event, then, current transaction should
|
|
// be reset.
|
|
{ func: sendMouseMoveEvent, delay: gEnoughForIgnoreMoveDelay,
|
|
offset: offsetForSubView1,
|
|
description: "sendMouseMoveEvent" },
|
|
{ func: testOneTimeScroll, delay: gEnoughForIgnoreMoveDelay,
|
|
offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gSubView1,
|
|
canFailRandomly: { possibleView: gRootView },
|
|
description: "Reset transaction by a mouse move event (v-9)" }
|
|
]
|
|
},
|
|
|
|
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Horizontal case
|
|
{ func: initElements, delay: 0, forVertical: false,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Create a transaction which targets |gRootView|.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: true, isVertical: false, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Reset transaction by a mouse move event (h-1)" },
|
|
// Scroll back to top-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: false, isVertical: false, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Reset transaction by a mouse move event (h-2)" },
|
|
// Send a mouse move event immediately after last wheel event, then,
|
|
// current transaction should be kept.
|
|
{ func: sendMouseMoveEvent, delay: 0, offset: offsetForSubView1,
|
|
description: "sendMouseMoveEvent" },
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Reset transaction by a mouse move event (h-3)" },
|
|
// Scroll back to top-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: false, isVertical: false, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Reset transaction by a mouse move event (h-4)" },
|
|
// Send a mouse move event after |gIgnoreMoveDelay| milliseconds since
|
|
// last wheel event, then, current transaction should be kept.
|
|
{ func: sendMouseMoveEvent, delay: gEnoughForIgnoreMoveDelay,
|
|
offset: offsetForSubView1,
|
|
description: "sendMouseMoveEvent" },
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Reset transaction by a mouse move event (h-5)" },
|
|
// Scroll back to top-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: false, isVertical: false, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Reset transaction by a mouse move event (h-6)" },
|
|
// Send a wheel event after |gIgnoreMoveDelay| milliseconds since last
|
|
// mouse move event but it is fired immediately after the last wheel
|
|
// event, then, current transaction should be kept.
|
|
{ func: sendMouseMoveEvent, delay: 0, offset: offsetForSubView1,
|
|
description: "sendMouseMoveEvent" },
|
|
{ func: testOneTimeScroll, delay: gEnoughForIgnoreMoveDelay,
|
|
offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Reset transaction by a mouse move event (h-7)" },
|
|
// Scroll back to top-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: false, isVertical: false, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Reset transaction by a mouse move event (h-8)" },
|
|
// Send a wheel event after |gIgnoreMoveDelay| milliseconds have passed
|
|
// since last mouse move event which is fired after |gIgnoreMoveDelay|
|
|
// milliseconds since last wheel event, then, current transaction should
|
|
// be reset.
|
|
{ func: sendMouseMoveEvent, delay: gEnoughForIgnoreMoveDelay,
|
|
offset: offsetForSubView1,
|
|
description: "sendMouseMoveEvent" },
|
|
{ func: testOneTimeScroll, delay: gEnoughForIgnoreMoveDelay,
|
|
offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: gSubView1,
|
|
canFailRandomly: { possibleView: gRootView },
|
|
description: "Reset transaction by a mouse move event (h-9)" }
|
|
]
|
|
},
|
|
|
|
|
|
/**************************************************************************
|
|
* Reset transaction by a mouse move event on outside of view
|
|
* When mouse cursor is moved to outside of the current target view, the
|
|
* transaction should be reset immediately.
|
|
**************************************************************************/
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Vertical case
|
|
{ func: initElements, delay: 0, forVertical: true,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Create a transaction which targets |gSubView1|.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gSubView1,
|
|
description: "Reset transaction by a mouse move event on outside of view (v-1)" },
|
|
// Send mouse move event over |gRootView|.
|
|
{ func: sendMouseMoveEvent, delay: 0, offset: offsetForRootView,
|
|
description: "sendMouseMoveEvent" },
|
|
// Send Wheel event over |gRootView| which should be scrolled.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
description: "Reset transaction by a mouse move event on outside of view (v-2)" }
|
|
]
|
|
},
|
|
|
|
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Horizontal case
|
|
{ func: initElements, delay: 0, forVertical: false,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Create a transaction which targets |gSubView1|.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gSubView1,
|
|
description: "Reset transaction by a mouse move event on outside of view (h-1)" },
|
|
// Send mouse move event over |gRootView|.
|
|
{ func: sendMouseMoveEvent, delay: 0, offset: offsetForRootView,
|
|
description: "sendMouseMoveEvent" },
|
|
// Send Wheel event over |gRootView| which should be scrolled.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
description: "Reset transaction by a mouse move event on outside of view (h-2)" }
|
|
]
|
|
},
|
|
|
|
|
|
/**************************************************************************
|
|
* Timeout test
|
|
* A view should not be scrolled during another to be transaction for
|
|
* another view scrolling. However, a wheel event which is sent after
|
|
* timeout, a view which is under the mouse cursor should be scrolled.
|
|
**************************************************************************/
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Vertical case
|
|
{ func: initElements, delay: 0, forVertical: true,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// First, create a transaction which should target the |gRootView|.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
description: "Timeout test (v-1)" },
|
|
// Scroll back to top-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: false, isVertical: true, expectedView: gRootView,
|
|
description: "Timeout test (v-2)" },
|
|
// A wheel event over |gSubView1| should not scroll it during current
|
|
// transaction.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Timeout test (v-3)" },
|
|
// Scroll back to top-most again.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: false, isVertical: true, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Timeout test (v-4)" },
|
|
// A wheel event over |gSubView1| after timeout should scroll
|
|
// |gSubView1|.
|
|
{ func: testOneTimeScroll, delay: gEnoughForTimeout,
|
|
offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gSubView1,
|
|
isTimeoutTesting: true,
|
|
description: "Timeout test (v-5)" }
|
|
]
|
|
},
|
|
|
|
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Horizontal case
|
|
{ func: initElements, delay: 0, forVertical: false,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// First, create a transaction which should target the |gRootView|.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: true, isVertical: false, expectedView: gRootView,
|
|
description: "Timeout test (h-1)" },
|
|
// Scroll back to left-most for easy cursor position specifying.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForRootView,
|
|
isForward: false, isVertical: false, expectedView: gRootView,
|
|
description: "Timeout test (h-2)" },
|
|
// A wheel event over |gSubView1| should not scroll it during current
|
|
// transaction.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Timeout test (h-3)" },
|
|
// Scroll back to left-most again.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: false, isVertical: false, expectedView: gRootView,
|
|
canFailRandomly: { possibleView: gSubView1 },
|
|
description: "Timeout test (h-4)" },
|
|
// A wheel event over |gSubView1| after timeout should scroll
|
|
// |gSubView1|.
|
|
{ func: testOneTimeScroll, delay: gEnoughForTimeout,
|
|
offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: gSubView1,
|
|
isTimeoutTesting: true,
|
|
description: "Timeout test (h-5)" }
|
|
]
|
|
},
|
|
|
|
|
|
/**************************************************************************
|
|
* Timeout test even with many wheel events
|
|
* This tests whether timeout is occurred event if wheel events are sent.
|
|
* The transaction should not be updated by non-scrollable wheel events.
|
|
**************************************************************************/
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Vertical case
|
|
{ func: initElements, delay: 0, forVertical: true,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Scroll |gSubView1| to bottom-most.
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gSubView1,
|
|
description: "Timeout test even with many wheel events (v-1)" },
|
|
// Don't scroll any views before timeout.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: null,
|
|
canFailRandomly: { possibleView: gRootView },
|
|
description: "Timeout test even with many wheel events (v-2)" },
|
|
// Recreate a transaction which is scrolling |gRootView| after time out.
|
|
{ func: testRestartScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gRootView,
|
|
description: "Timeout test even with many wheel events (v-3)" }
|
|
]
|
|
},
|
|
|
|
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
// Horizontal case
|
|
{ func: initElements, delay: 0, forVertical: false,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
// Scroll |gSubView1| to right-most.
|
|
{ func: testContinuousScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: gSubView1,
|
|
description: "Timeout test even with many wheel events (h-1)" },
|
|
// Don't scroll any views before timeout.
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: null,
|
|
canFailRandomly: { possibleView: gRootView },
|
|
description: "Timeout test even with many wheel events (h-2)" },
|
|
// Recreate a transaction which is scrolling |gRootView| after time out.
|
|
{ func: testRestartScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: gRootView,
|
|
description: "Timeout test even with many wheel events (h-3)" }
|
|
]
|
|
},
|
|
|
|
|
|
/**************************************************************************
|
|
* Very large scrolling wheel event
|
|
* If the delta value is larger than the scrolling page size, it should be
|
|
* scrolled only one page instead of the delta value.
|
|
**************************************************************************/
|
|
{ retryWhenTransactionTimeout: 5,
|
|
steps: [
|
|
{ func: initElements, delay: 0, forVertical: true,
|
|
description: "initElements" },
|
|
{ func: clearWheelTransaction, delay: 0,
|
|
description: "clearWheelTransaction" },
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gSubView1,
|
|
delta: 5000,
|
|
description: "Very large delta scrolling (v-1)" },
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: true, expectedView: gSubView1,
|
|
delta: 5000,
|
|
description: "Very large delta scrolling (v-2)" },
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: gSubView1,
|
|
delta: 5000,
|
|
description: "Very large delta scrolling (h-1)" },
|
|
{ func: testOneTimeScroll, delay: 0, offset: offsetForSubView1,
|
|
isForward: true, isVertical: false, expectedView: gSubView1,
|
|
delta: 5000,
|
|
description: "Very large delta scrolling (h-2)" }
|
|
]
|
|
}
|
|
];
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Actions for preparing tests
|
|
******************************************************************************/
|
|
|
|
function initElements()
|
|
{
|
|
_clearTimer();
|
|
|
|
function resetScrollPosition(aElement)
|
|
{
|
|
aElement.scrollTop = 0;
|
|
aElement.scrollLeft = 0;
|
|
}
|
|
|
|
const kDisplay = gCurrentTest.forVertical ? "block" : "inline-block";
|
|
gSubView1.style.display = kDisplay;
|
|
gSubView2.style.display = kDisplay;
|
|
gSubView3.style.display = kDisplay;
|
|
|
|
resetScrollPosition(gRootView);
|
|
resetScrollPosition(gSubView1);
|
|
resetScrollPosition(gSubView2);
|
|
resetScrollPosition(gSubView3);
|
|
_getDOMWindowUtils(window).advanceTimeAndRefresh(0);
|
|
|
|
runNextTestStep();
|
|
}
|
|
|
|
function clearWheelTransaction()
|
|
{
|
|
_clearTimer();
|
|
_clearTransaction();
|
|
runNextTestStep();
|
|
}
|
|
|
|
function sendKeyEvents()
|
|
{
|
|
_clearTimer();
|
|
synthesizeKey(gCurrentTest.key, {}, window);
|
|
runNextTestStep();
|
|
}
|
|
|
|
function sendMouseButtonEvents()
|
|
{
|
|
_clearTimer();
|
|
synthesizeMouse(gRootView, -1, -1, { type:"mousedown" }, window);
|
|
synthesizeMouse(gRootView, -1, -1, { type:"mouseup" }, window);
|
|
runNextTestStep();
|
|
}
|
|
|
|
function sendMouseMoveEvent()
|
|
{
|
|
_clearTimer();
|
|
_fireMouseMoveEvent(gCurrentTest.offset());
|
|
runNextTestStep();
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Utilities for testing functions
|
|
******************************************************************************/
|
|
|
|
function _clearTransaction()
|
|
{
|
|
synthesizeMouse(gRootView, -1, -1, { type:"mousedown" }, window);
|
|
synthesizeMouse(gRootView, -1, -1, { type:"mouseup" }, window);
|
|
}
|
|
|
|
function _saveScrollPositions()
|
|
{
|
|
function save(aElement)
|
|
{
|
|
aElement.prevTop = aElement.scrollTop;
|
|
aElement.prevLeft = aElement.scrollLeft;
|
|
}
|
|
save(gRootView);
|
|
save(gSubView1);
|
|
save(gSubView2);
|
|
save(gSubView3);
|
|
}
|
|
|
|
function _fireMouseMoveEvent(aOffset)
|
|
{
|
|
synthesizeMouse(gRootView, aOffset.x, aOffset.y, { type:"mousemove" }, window);
|
|
}
|
|
|
|
function _fireWheelScrollEvent(aOffset, aIsVertical, aForward, aDelta)
|
|
{
|
|
var event = { deltaMode: WheelEvent.DOM_DELTA_LINE };
|
|
if (aIsVertical) {
|
|
event.deltaY = aForward ? aDelta : -aDelta;
|
|
} else {
|
|
event.deltaX = aForward ? aDelta : -aDelta;
|
|
}
|
|
sendWheelAndPaint(gRootView, aOffset.x, aOffset.y, event, null, window);
|
|
}
|
|
|
|
function _canScroll(aElement, aIsVertical, aForward)
|
|
{
|
|
if (aIsVertical) {
|
|
if (!aForward)
|
|
return aElement.scrollTop > 0;
|
|
return aElement.scrollHeight > aElement.scrollTop + aElement.clientHeight;
|
|
}
|
|
if (!aForward)
|
|
return aElement.scrollLeft > 0;
|
|
return aElement.scrollWidth > aElement.scrollLeft + aElement.clientWidth;
|
|
}
|
|
|
|
const kNotScrolled = 0;
|
|
const kScrolledToTop = 1;
|
|
const kScrolledToBottom = 2;
|
|
const kScrolledToLeft = 4;
|
|
const kScrolledToRight = 8;
|
|
|
|
const kScrolledVertical = kScrolledToTop | kScrolledToBottom;
|
|
const kScrolledHorizontal = kScrolledToLeft | kScrolledToRight;
|
|
|
|
function _getScrolledState(aElement)
|
|
{
|
|
var ret = kNotScrolled;
|
|
if (aElement.scrollTop != aElement.prevTop) {
|
|
ret |= aElement.scrollTop < aElement.prevTop ? kScrolledToTop :
|
|
kScrolledToBottom;
|
|
}
|
|
if (aElement.scrollLeft != aElement.prevLeft) {
|
|
ret |= aElement.scrollLeft < aElement.prevLeft ? kScrolledToLeft :
|
|
kScrolledToRight;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
function _getExpectedScrolledState()
|
|
{
|
|
// eslint-disable-next-line no-nested-ternary
|
|
return gCurrentTest.isVertical ?
|
|
gCurrentTest.isForward ? kScrolledToBottom : kScrolledToTop :
|
|
gCurrentTest.isForward ? kScrolledToRight : kScrolledToLeft;
|
|
}
|
|
|
|
function _getScrolledStateText(aScrolledState)
|
|
{
|
|
if (aScrolledState == kNotScrolled)
|
|
return "Not scrolled";
|
|
|
|
var s = "scrolled to ";
|
|
if (aScrolledState & kScrolledVertical) {
|
|
s += aScrolledState & kScrolledToTop ? "backward" : "forward";
|
|
s += " (vertical)"
|
|
if (aScrolledState & kScrolledHorizontal)
|
|
s += " and to ";
|
|
}
|
|
if (aScrolledState & kScrolledHorizontal) {
|
|
s += aScrolledState & kScrolledToLeft ? "backward" : "forward";
|
|
s += " (horizontal)"
|
|
}
|
|
return s;
|
|
}
|
|
|
|
function _getCurrentTestList()
|
|
{
|
|
return gTestLists[gCurrentTestListStatus.nextListIndex - 1];
|
|
}
|
|
|
|
function _clearTimer()
|
|
{
|
|
clearTimeout(gTimer);
|
|
gTimer = 0;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Testing functions
|
|
******************************************************************************/
|
|
|
|
/**
|
|
* Note that testing functions must set following variables:
|
|
*
|
|
* gCurrentTest.repeatTest: See comment in |continueTest|.
|
|
* gCurrentTest.autoRepeatDelay: See comment in |continueTest|.
|
|
* gListenScrollEvent: When this is not true, the event handlers ignores the
|
|
* events.
|
|
*/
|
|
|
|
function testContinuousScroll()
|
|
{
|
|
/**
|
|
* Testing continuous scrolling. This function synthesizes a wheel event. If
|
|
* the test was success, this function will be recalled automatically.
|
|
* And when a generating wheel event cannot scroll the expected view, this
|
|
* function fires the wheel event only one time.
|
|
*
|
|
* @param gCurrentTest.offset
|
|
* A function to compute the cursor position of firing wheel event.
|
|
* The values are offset from |gRootView|.
|
|
* @param gCurrentTest.isVertical
|
|
* Whether the wheel event is for virtical scrolling or horizontal.
|
|
* @param gCurrentTest.isForward
|
|
* Whether the wheel event is to forward or to backward.
|
|
* @param gCurrentTest.expectedView
|
|
* The expected view which will be scrolled by wheel event. This
|
|
* value must not be null.
|
|
*/
|
|
|
|
_clearTimer();
|
|
_saveScrollPositions();
|
|
if (!gCurrentTest.expectedView) {
|
|
runNextTestStep();
|
|
return;
|
|
}
|
|
|
|
gLitesnEvents = kListenEvent_All;
|
|
gCurrentTest.repeatTest = true;
|
|
gCurrentTest.autoRepeatDelay = 0;
|
|
|
|
if (!_canScroll(gCurrentTest.expectedView,
|
|
gCurrentTest.isVertical, gCurrentTest.isForward)) {
|
|
gCurrentTest.expectedView = null;
|
|
}
|
|
var delta = gCurrentTest.delta ? gCurrentTest.delta : 4;
|
|
_fireWheelScrollEvent(gCurrentTest.offset(),
|
|
gCurrentTest.isVertical, gCurrentTest.isForward, delta);
|
|
}
|
|
|
|
function testOneTimeScroll()
|
|
{
|
|
/**
|
|
* Testing one wheel event. |runNextTestStep| will be called immediately
|
|
* after this function by |onScrollView| or |onTimeout|.
|
|
*
|
|
* @param gCurrentTest.offset
|
|
* A function to compute the cursor position of firing wheel event.
|
|
* The values are offset from |gRootView|.
|
|
* @param gCurrentTest.isVertical
|
|
* Whether the wheel event is for virtical scrolling or horizontal.
|
|
* @param gCurrentTest.isForward
|
|
* Whether the wheel event is to forward or to backward.
|
|
* @param gCurrentTest.expectedView
|
|
* The expected view which will be scrolled by wheel event. This
|
|
* value can be null. It means any views should not be scrolled.
|
|
*/
|
|
|
|
_clearTimer();
|
|
_saveScrollPositions();
|
|
|
|
gLitesnEvents = kListenEvent_All;
|
|
gCurrentTest.repeatTest = false;
|
|
gCurrentTest.autoRepeatDelay = 0;
|
|
|
|
var delta = gCurrentTest.delta ? gCurrentTest.delta : 4;
|
|
_fireWheelScrollEvent(gCurrentTest.offset(),
|
|
gCurrentTest.isVertical, gCurrentTest.isForward, delta);
|
|
}
|
|
|
|
function testRestartScroll()
|
|
{
|
|
/**
|
|
* Testing restart to scroll in expected view after timeout from the current
|
|
* transaction. This function recall this itself until to success this test
|
|
* or timeout from this test.
|
|
*
|
|
* @param gCurrentTest.offset
|
|
* A function to compute the cursor position of firing wheel event.
|
|
* The values are offset from |gRootView|.
|
|
* @param gCurrentTest.isVertical
|
|
* Whether the wheel event is for virtical scrolling or horizontal.
|
|
* @param gCurrentTest.isForward
|
|
* Whether the wheel event is to forward or to backward.
|
|
* @param gCurrentTest.expectedView
|
|
* The expected view which will be scrolled by wheel event. This
|
|
* value must not be null.
|
|
*/
|
|
|
|
_clearTimer();
|
|
_saveScrollPositions();
|
|
|
|
if (!gCurrentTest.wasTransactionTimeout) {
|
|
gCurrentTest.repeatTest = true;
|
|
gCurrentTest.autoRepeatDelay = gTimeout / 3;
|
|
gLitesnEvents = kListenEvent_All;
|
|
gCurrentTest.isTimeoutTesting = true;
|
|
if (gCurrentTest.expectedView) {
|
|
gCurrentTest.expectedViewAfterTimeout = gCurrentTest.expectedView;
|
|
gCurrentTest.expectedView = null;
|
|
}
|
|
} else {
|
|
gCurrentTest.repeatTest = false;
|
|
gCurrentTest.autoRepeatDelay = 0;
|
|
gLitesnEvents = kListenEvent_All;
|
|
gCurrentTest.isTimeoutTesting = false;
|
|
gCurrentTest.expectedView = gCurrentTest.expectedViewAfterTimeout;
|
|
}
|
|
|
|
var delta = gCurrentTest.delta ? gCurrentTest.delta : 4;
|
|
_fireWheelScrollEvent(gCurrentTest.offset(),
|
|
gCurrentTest.isVertical, gCurrentTest.isForward, delta);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Event handlers
|
|
******************************************************************************/
|
|
|
|
function onScrollView(aEvent)
|
|
{
|
|
/**
|
|
* Scroll event handler of |gRootView|, |gSubView1|, |gSubView2| and
|
|
* |gSubView3|. If testing is failed, this function cancels all left tests.
|
|
* For checking the event is expected, the event firer must call
|
|
* |_saveScrollPositions|.
|
|
*
|
|
* @param gCurrentTest.expectedView
|
|
* The expected view which should be scrolled by the wheel event.
|
|
* This value can be null. It means any views should not be
|
|
* scrolled.
|
|
* @param gCurrentTest.isVertical
|
|
* The expected view should be scrolled vertical or horizontal.
|
|
* @param gCurrentTest.isForward
|
|
* The expected view should be scrolled to forward or backward.
|
|
* @param gCurrentTest.canFailRandomly
|
|
* If this is not undefined, this test can fail by unexpected view
|
|
* scrolling which is caused by unexpected timeout. If this is
|
|
* defined, |gCurrentTest.possibleView| must be set. If the view is
|
|
* same as the event target, the failure can be random. At this
|
|
* time, we should retry the current test list.
|
|
*/
|
|
|
|
if (!(gLitesnEvents & kListenEvent_OnScroll))
|
|
return;
|
|
|
|
// Now testing a timeout, but a view is scrolled before timeout.
|
|
if (gCurrentTest.isTimeoutTesting && !gCurrentTest.wasTransactionTimeout) {
|
|
is(aEvent.target.id, "",
|
|
"The view scrolled before timeout (the expected view after timeout is " +
|
|
gCurrentTest.expectedView ? gCurrentTest.expectedView.id : "null" +
|
|
"): " + gCurrentTest.description);
|
|
runNextTestList();
|
|
return;
|
|
}
|
|
|
|
// Check whether the scrolled event should be fired or not.
|
|
if (!gCurrentTest.expectedView) {
|
|
is(aEvent.target.id, "",
|
|
"no views should be scrolled (" +
|
|
_getScrolledStateText(_getScrolledState(aEvent.target)) + "): " +
|
|
gCurrentTest.description);
|
|
runNextTestList();
|
|
return;
|
|
}
|
|
|
|
// Check whether the scrolled view is expected or not.
|
|
if (aEvent.target != gCurrentTest.expectedView) {
|
|
// If current test can fail randomly and the possible view is same as the
|
|
// event target, this failure may be caused by unexpected timeout.
|
|
// At this time, we should retry the current tests with slower settings.
|
|
if (gCurrentTest.canFailRandomly &&
|
|
gCurrentTest.canFailRandomly.possibleView == aEvent.target &&
|
|
gCurrentTestListStatus.retryWhenTransactionTimeout > 0) {
|
|
gCurrentTestListStatus.retryWhenTransactionTimeout--;
|
|
retryCurrentTestList();
|
|
return;
|
|
}
|
|
is(aEvent.target.id, gCurrentTest.expectedView.id,
|
|
"wrong view was scrolled: " + gCurrentTest.description);
|
|
runNextTestList();
|
|
return;
|
|
}
|
|
|
|
// Check whether the scrolling direction is expected or not.
|
|
var expectedState = _getExpectedScrolledState();
|
|
var currentState = _getScrolledState(aEvent.target);
|
|
if (expectedState != currentState) {
|
|
is(_getScrolledStateText(currentState),
|
|
_getScrolledStateText(expectedState),
|
|
"scrolled to wrong direction: " + gCurrentTest.description);
|
|
runNextTestList();
|
|
return;
|
|
}
|
|
|
|
ok(true, "passed: " + gCurrentTest.description);
|
|
continueTest();
|
|
}
|
|
|
|
function onMouseScrollFailed()
|
|
{
|
|
/**
|
|
* Scroll failed event handler. If testing is failed, this function cancels
|
|
* all remains of current test-list, and go to next test-list.
|
|
*
|
|
* NOTE: This event is fired immediately after |_fireWheelScrollEvent|.
|
|
*
|
|
* @param gCurrentTest.expectedView
|
|
* The expected view which should be scrolled by the wheel event.
|
|
* This value can be null. It means any views should not be
|
|
* scrolled. When this is not null, this event means the test may
|
|
* be failed.
|
|
*/
|
|
|
|
if (!(gLitesnEvents & kListenEvent_OnScrollFailed))
|
|
return;
|
|
|
|
ok(!gCurrentTest.expectedView,
|
|
"failed to scroll on current target: " + gCurrentTest.description);
|
|
if (gCurrentTest.expectedView) {
|
|
runNextTestList();
|
|
return;
|
|
}
|
|
|
|
continueTest();
|
|
}
|
|
|
|
function onTransactionTimeout()
|
|
{
|
|
/**
|
|
* Scroll transaction timeout event handler. If the timeout is unexpected,
|
|
* i.e., |gCurrentTest.isTimeoutTesting| is not true, this function retry
|
|
* the current test-list. However, if the current test-list failed by timeout
|
|
* |gCurrentTestListStatus.retryWhenTransactionTimeout| times already, marking
|
|
* to failed the current test-list, and go to next test-list.
|
|
*
|
|
* @param gCurrentTest.expectedView
|
|
* The expected view which should be scrolled by the wheel event.
|
|
* This value can be null. It means any views should not be
|
|
* scrolled. When this is not null, this event means the testing may
|
|
* be failed.
|
|
* @param gCurrentTest.isTimeoutTesting
|
|
* If this value is true, the current testing have waited this
|
|
* event. Otherwise, the testing may be failed.
|
|
* @param gCurrentTestListStatus.retryWhenTransactionTimeout
|
|
* If |gCurrentTest.isTimeoutTesting| is not true but this event is
|
|
* fired, the failure may be randomly. Then, this event handler
|
|
* retry to test the current test-list until this cound will be zero.
|
|
*/
|
|
|
|
if (!gCurrentTest.isTimeoutTesting &&
|
|
gCurrentTestListStatus.retryWhenTransactionTimeout > 0) {
|
|
gCurrentTestListStatus.retryWhenTransactionTimeout--;
|
|
// retry current test list
|
|
retryCurrentTestList();
|
|
return;
|
|
}
|
|
|
|
gCurrentTest.wasTransactionTimeout = true;
|
|
|
|
if (!(gLitesnEvents & kListenEvent_OnTransactionTimeout))
|
|
return;
|
|
|
|
ok(gCurrentTest.isTimeoutTesting,
|
|
"transaction timeout: " + gCurrentTest.description);
|
|
if (!gCurrentTest.isTimeoutTesting) {
|
|
runNextTestList();
|
|
return;
|
|
}
|
|
|
|
continueTest();
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Main function for this tests
|
|
******************************************************************************/
|
|
|
|
function runNextTestStep()
|
|
{
|
|
// When this is first time or the current test list is finised, load next
|
|
// test-list.
|
|
_clearTimer();
|
|
if (!gCurrentTest)
|
|
runNextTestList();
|
|
else
|
|
runTestStepAt(gCurrentTestListStatus.nextStepIndex);
|
|
}
|
|
|
|
function runNextTestList()
|
|
{
|
|
_clearTimer();
|
|
|
|
gLitesnEvents = kListenEvent_None;
|
|
_clearTransaction();
|
|
resetTimeoutPrefs();
|
|
if (gCurrentTestListStatus.nextListIndex >= gTestLists.length) {
|
|
finish();
|
|
return;
|
|
}
|
|
|
|
gCurrentTestListStatus.nextListIndex++;
|
|
gCurrentTestListStatus.retryWhenTransactionTimeout =
|
|
_getCurrentTestList().retryWhenTransactionTimeout;
|
|
runTestStepAt(0);
|
|
}
|
|
|
|
function runTestStepAt(aStepIndex)
|
|
{
|
|
_clearTimer();
|
|
|
|
disableNonTestMouseEvents(true);
|
|
|
|
// load a step of testing.
|
|
gCurrentTestListStatus.nextStepIndex = aStepIndex;
|
|
gCurrentTest =
|
|
_getCurrentTestList().steps[gCurrentTestListStatus.nextStepIndex++];
|
|
if (gCurrentTest) {
|
|
gCurrentTest.wasTransactionTimeout = false;
|
|
gTimer = setTimeout(gCurrentTest.func, gCurrentTest.delay);
|
|
} else {
|
|
// If current test-list doesn't have more testing, go to next test-list
|
|
// after cleaning up the current transaction.
|
|
_clearTransaction();
|
|
runNextTestList();
|
|
}
|
|
}
|
|
|
|
function retryCurrentTestList()
|
|
{
|
|
_clearTimer();
|
|
|
|
gLitesnEvents = kListenEvent_None;
|
|
_clearTransaction();
|
|
ok(true, "WARNING: retry current test-list...");
|
|
growUpTimeoutPrefs(); // retry the test with longer timeout settings.
|
|
runTestStepAt(0);
|
|
}
|
|
|
|
function continueTest()
|
|
{
|
|
/**
|
|
* This function is called from an event handler when a test succeeded.
|
|
*
|
|
* @param gCurrentTest.repeatTest
|
|
* When this is true, onScrollView calls |gCurrentTest.func|. So,
|
|
* same test can repeat. Otherwise, this calls |runNextTestStep|.
|
|
* @param gCurrentTest.autoRepeatDelay
|
|
* The delay value in milliseconds, this is used to call
|
|
* |gCurrentTest.func| via |setTimeout|.
|
|
*/
|
|
|
|
_clearTimer();
|
|
gLitesnEvents = kListenEvent_OnTransactionTimeout;
|
|
|
|
// We should call each functions via setTimeout. Because sometimes this test
|
|
// is broken by stack overflow.
|
|
if (gCurrentTest.repeatTest) {
|
|
gTimer = setTimeout(gCurrentTest.func, gCurrentTest.autoRepeatDelay);
|
|
} else {
|
|
gTimer = setTimeout(runNextTestStep, 0);
|
|
}
|
|
}
|
|
|
|
]]>
|
|
</script>
|
|
|
|
</window>
|