1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/tests/window_wheeltransaction.xul Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1551 @@ 1.4 +<?xml version="1.0"?> 1.5 +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> 1.6 +<window title="Wheel scroll tests" 1.7 + width="600" height="600" 1.8 + onload="onload();" 1.9 + onunload="onunload();" 1.10 + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 1.11 + 1.12 + <script type="application/javascript" 1.13 + src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js" /> 1.14 + 1.15 +<body xmlns="http://www.w3.org/1999/xhtml"> 1.16 +<style type="text/css"> 1.17 + #rootview { 1.18 + overflow: auto; 1.19 + width: 400px; 1.20 + height: 400px; 1.21 + border: 1px solid; 1.22 + } 1.23 + #container { 1.24 + overflow: auto; 1.25 + width: 600px; 1.26 + height: 600px; 1.27 + } 1.28 + #rootview pre { 1.29 + margin: 20px 0 20px 20px; 1.30 + padding: 0; 1.31 + overflow: auto; 1.32 + display: block; 1.33 + width: 100px; 1.34 + height: 100.5px; 1.35 + font-size: 16px; 1.36 + } 1.37 +</style> 1.38 +<div id="rootview" onscroll="onScrollView(event);"> 1.39 + <div id="container"> 1.40 + <pre id="subview1" onscroll="onScrollView(event);"> 1.41 +Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. 1.42 +Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. 1.43 +Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. 1.44 +Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. 1.45 +Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. 1.46 +Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. 1.47 +Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. 1.48 +Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. 1.49 +Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. 1.50 +Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. 1.51 + </pre> 1.52 + <pre id="subview2" onscroll="onScrollView(event);"> 1.53 +Text. 1.54 +Text. 1.55 +Text. 1.56 +Text. 1.57 +Text. 1.58 +Text. 1.59 +Text. 1.60 +Text. 1.61 +Text. 1.62 +Text. 1.63 + </pre> 1.64 + <pre id="subview3" onscroll="onScrollView(event);"> 1.65 +Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. 1.66 + </pre> 1.67 + </div> 1.68 +</div> 1.69 +<div id="content" style="display: none"> 1.70 +</div> 1.71 +<pre id="test"> 1.72 +</pre> 1.73 +</body> 1.74 + 1.75 +<script class="testbody" type="application/javascript"> 1.76 +<![CDATA[ 1.77 + 1.78 +function ok(aCondition, aMessage) 1.79 +{ 1.80 + window.opener.wrappedJSObject.SimpleTest.ok(aCondition, aMessage); 1.81 +} 1.82 + 1.83 +function is(aLeft, aRight, aMessage) 1.84 +{ 1.85 + window.opener.wrappedJSObject.SimpleTest.is(aLeft, aRight, aMessage); 1.86 +} 1.87 + 1.88 +function isnot(aLeft, aRight, aMessage) 1.89 +{ 1.90 + window.opener.wrappedJSObject.SimpleTest.isnot(aLeft, aRight, aMessage); 1.91 +} 1.92 + 1.93 +var gCurrentTestListStatus = { nextListIndex: 0 }; 1.94 +var gCurrentTest; 1.95 + 1.96 +const kListenEvent_None = 0; 1.97 +const kListenEvent_OnScroll = 1; 1.98 +const kListenEvent_OnScrollFailed = 2; 1.99 +const kListenEvent_OnTransactionTimeout = 4; 1.100 +const kListenEvent_All = kListenEvent_OnScroll | 1.101 + kListenEvent_OnScrollFailed | 1.102 + kListenEvent_OnTransactionTimeout; 1.103 +var gLitesnEvents = kListenEvent_None; 1.104 + 1.105 +/** 1.106 + * At unexpected transaction timeout, we need to stop *all* timers. But it is 1.107 + * difficult and it can be create more complex testing code. So, we should use 1.108 + * only one timer at one time. For that, we must store the timer id to this 1.109 + * variable. And the functions which may be called via a timer must clear the 1.110 + * current timer by |_clearTimer| function. 1.111 + */ 1.112 +var gTimer; 1.113 + 1.114 +var gPrefSvc = Components.classes["@mozilla.org/preferences-service;1"]. 1.115 + getService(Components.interfaces.nsIPrefBranch); 1.116 +const kPrefSmoothScroll = "general.smoothScroll"; 1.117 +const kPrefNameTimeout = "mousewheel.transaction.timeout"; 1.118 +const kPrefNameIgnoreMoveDelay = "mousewheel.transaction.ignoremovedelay"; 1.119 + 1.120 +const kDefaultTimeout = gPrefSvc.getIntPref(kPrefNameTimeout); 1.121 +const kDefaultIgnoreMoveDelay = gPrefSvc.getIntPref(kPrefNameIgnoreMoveDelay); 1.122 + 1.123 +gPrefSvc.setBoolPref(kPrefSmoothScroll, false); 1.124 + 1.125 +var gTimeout, gIgnoreMoveDelay; 1.126 +var gEnoughForTimeout, gEnoughForIgnoreMoveDelay; 1.127 + 1.128 +function setTimeoutPrefs(aTimeout, aIgnoreMoveDelay) 1.129 +{ 1.130 + gPrefSvc.setIntPref(kPrefNameTimeout, aTimeout); 1.131 + gPrefSvc.setIntPref(kPrefNameIgnoreMoveDelay, aIgnoreMoveDelay); 1.132 + gTimeout = aTimeout; 1.133 + gIgnoreMoveDelay = aIgnoreMoveDelay; 1.134 + gEnoughForTimeout = gTimeout * 2; 1.135 + gEnoughForIgnoreMoveDelay = gIgnoreMoveDelay * 1.2; 1.136 +} 1.137 + 1.138 +function resetTimeoutPrefs() 1.139 +{ 1.140 + if (gTimeout == kDefaultTimeout) 1.141 + return; 1.142 + setTimeoutPrefs(kDefaultTimeout, kDefaultIgnoreMoveDelay); 1.143 + initTestList(); 1.144 +} 1.145 + 1.146 +function growUpTimeoutPrefs() 1.147 +{ 1.148 + if (gTimeout != kDefaultTimeout) 1.149 + return; 1.150 + setTimeoutPrefs(5000, 1000); 1.151 + initTestList(); 1.152 +} 1.153 + 1.154 +// setting enough time for testing. 1.155 +gPrefSvc.setIntPref(kPrefNameTimeout, gTimeout); 1.156 +gPrefSvc.setIntPref(kPrefNameIgnoreMoveDelay, gIgnoreMoveDelay); 1.157 + 1.158 +var gRootView = document.getElementById("rootview"); 1.159 +var gSubView1 = document.getElementById("subview1"); 1.160 +var gSubView2 = document.getElementById("subview2"); 1.161 +var gSubView3 = document.getElementById("subview3"); 1.162 + 1.163 +gRootView.addEventListener("MozMouseScrollFailed", onMouseScrollFailed, false); 1.164 +gRootView.addEventListener("MozMouseScrollTransactionTimeout", 1.165 + onTransactionTimeout, false); 1.166 + 1.167 +function finish() 1.168 +{ 1.169 + window.close(); 1.170 +} 1.171 + 1.172 +function onload() 1.173 +{ 1.174 + runNextTestList(); 1.175 +} 1.176 + 1.177 +function onunload() 1.178 +{ 1.179 + resetTimeoutPrefs(); 1.180 + gPrefSvc.clearUserPref(kPrefSmoothScroll); 1.181 + disableNonTestMouseEvents(false); 1.182 + window.opener.wrappedJSObject.SimpleTest.finish(); 1.183 +} 1.184 + 1.185 +const kSubView1Offset = { x: 20, y: 20 }; 1.186 +const kSubView2Offset = { x: 20, y: 20 + 100 + 20 }; 1.187 +const kSubView3Offset = { x: 20, y: 20 + (100 + 20) * 2 }; 1.188 + 1.189 +function _getSubViewTestPtForV(aPt) 1.190 +{ 1.191 + return { x: aPt.x + 10, y: aPt.y + 10 }; 1.192 +} 1.193 + 1.194 +const kPtInRootViewForV = { x: kSubView1Offset.x + 10, 1.195 + y: kSubView1Offset.y - 10 }; 1.196 +const kPtInSubView1ForV = _getSubViewTestPtForV(kSubView1Offset); 1.197 +const kPtInSubView2ForV = _getSubViewTestPtForV(kSubView2Offset); 1.198 +const kPtInSubView3ForV = _getSubViewTestPtForV(kSubView3Offset); 1.199 + 1.200 +function _convertTestPtForH(aPt) 1.201 +{ 1.202 + return { x: aPt.y, y: aPt.x }; 1.203 +} 1.204 + 1.205 +const kPtInRootViewForH = _convertTestPtForH(kPtInRootViewForV); 1.206 +const kPtInSubView1ForH = _convertTestPtForH(kPtInSubView1ForV); 1.207 +const kPtInSubView2ForH = _convertTestPtForH(kPtInSubView2ForV); 1.208 +const kPtInSubView3ForH = _convertTestPtForH(kPtInSubView3ForV); 1.209 + 1.210 +/** 1.211 + * Define the tests here: 1.212 + * Scrolls are processed async always. Therefore, we need to call all tests 1.213 + * by timer. gTestLists is array of testing lists. In other words, an item 1.214 + * of gTestList is a group of one or more testing. Each items has following 1.215 + * properties: 1.216 + * 1.217 + * - retryWhenTransactionTimeout 1.218 + * The testing of wheel transaction might be fialed randomly by 1.219 + * timeout. Then, automatically the failed test list will be retested 1.220 + * automatically only this number of times. 1.221 + * 1.222 + * - steps 1.223 + * This property is array of testing. Each steps must have following 1.224 + * properties at least. 1.225 + * 1.226 + * - func 1.227 + * This property means function which will be called via 1.228 + * |setTimeout|. The function cannot have params. If you need 1.229 + * some additional parameters, you can specify some original 1.230 + * properties for the test function. If you do so, you should 1.231 + * document it in the testing function. 1.232 + * - delay 1.233 + * This property means delay time until the function to be called. 1.234 + * I.e., the value used for the second param of |setTimeout|. 1.235 + * 1.236 + * And also you need one more property when you call a testing function. 1.237 + * 1.238 + * - description 1.239 + * This property is description of the test. This is used for 1.240 + * logging. 1.241 + * 1.242 + * At testing, you can access to current step via |gCurrentTest|. 1.243 + */ 1.244 + 1.245 +var gTestLists; 1.246 +function initTestList() 1.247 +{ 1.248 + gTestLists = [ 1.249 + /************************************************************************** 1.250 + * Continuous scrolling test for |gRootView| 1.251 + * |gRootView| has both scrollbars and it has three children which are 1.252 + * |gSubView1|, |gSubView2| and |gSubView3|. They have scrollbars. If 1.253 + * the current transaction targets |gRootView|, other children should not 1.254 + * be scrolled even if the wheel events are fired on them. 1.255 + **************************************************************************/ 1.256 + { retryWhenTransactionTimeout: 5, 1.257 + steps: [ 1.258 + // Vertical case 1.259 + { func: initElements, delay: 0, forVertical: true, 1.260 + description: "initElements" }, 1.261 + { func: clearWheelTransaction, delay: 0, 1.262 + description: "clearWheelTransaction" }, 1.263 + // Vertical wheel events should scroll |gRootView| even if the position 1.264 + // of wheel events in a child view which has scrollbar. 1.265 + { func: testContinuousScroll, delay: 0, offset: kPtInRootViewForV, 1.266 + isForward: true, isVertical: true, expectedView: gRootView, 1.267 + description: "Continuous scrolling test for root view (vertical/forward)" }, 1.268 + { func: testContinuousScroll, delay: 0, offset: kPtInRootViewForV, 1.269 + isForward: false, isVertical: true, expectedView: gRootView, 1.270 + description: "Continuous scrolling test for root view (vertical/backward)" } 1.271 + ] 1.272 + }, 1.273 + 1.274 + 1.275 + { retryWhenTransactionTimeout: 5, 1.276 + steps: [ 1.277 + // Horizontal case 1.278 + { func: initElements, delay: 0, forVertical: false, 1.279 + description: "initElements" }, 1.280 + { func: clearWheelTransaction, delay: 0, 1.281 + description: "clearWheelTransaction" }, 1.282 + // Horizontal wheel events should scroll |gRootView| even if the 1.283 + // position of wheel events in a child view which has scrollbar. 1.284 + { func: testContinuousScroll, delay: 0, offset: kPtInRootViewForH, 1.285 + isForward: true, isVertical: false, expectedView: gRootView, 1.286 + description: "Continuous scrolling test for root view (horizontal/forward)" }, 1.287 + { func: testContinuousScroll, delay: 0, offset: kPtInRootViewForH, 1.288 + isForward: false, isVertical: false, expectedView: gRootView, 1.289 + description: "Continuous scrolling test for root view (horizontal/backward)" } 1.290 + ] 1.291 + }, 1.292 + 1.293 + 1.294 + /************************************************************************** 1.295 + * Continuous scrolling test for |gSubView1| 1.296 + * |gSubView1| has both scrollbars. 1.297 + **************************************************************************/ 1.298 + { retryWhenTransactionTimeout: 5, 1.299 + steps: [ 1.300 + // Vertical case 1.301 + { func: initElements, delay: 0, forVertical: true, 1.302 + description: "initElements" }, 1.303 + { func: clearWheelTransaction, delay: 0, 1.304 + description: "clearWheelTransaction" }, 1.305 + // Vertical wheel events should scroll |gSubView1|. 1.306 + { func: testContinuousScroll, delay: 0, offset: kPtInSubView1ForV, 1.307 + isForward: true, isVertical: true, expectedView: gSubView1, 1.308 + description: "Continuous scrolling test for sub view 1 (vertical/forward)" }, 1.309 + { func: testContinuousScroll, delay: 0, offset: kPtInSubView1ForV, 1.310 + isForward: false, isVertical: true, expectedView: gSubView1, 1.311 + description: "Continuous scrolling test for sub view 1 (vertical/backward)" } 1.312 + ] 1.313 + }, 1.314 + 1.315 + 1.316 + { retryWhenTransactionTimeout: 5, 1.317 + steps: [ 1.318 + // Horizontal case 1.319 + { func: initElements, delay: 0, forVertical: false, 1.320 + description: "initElements" }, 1.321 + { func: clearWheelTransaction, delay: 0, 1.322 + description: "clearWheelTransaction" }, 1.323 + // Horitontal wheel events should scroll |gSubView1|. 1.324 + { func: testContinuousScroll, delay: 0, offset: kPtInSubView1ForH, 1.325 + isForward: true, isVertical: false, expectedView: gSubView1, 1.326 + description: "Continuous scrolling test for sub view 1 (horizontal/forward)" }, 1.327 + { func: testContinuousScroll, delay: 0, offset: kPtInSubView1ForH, 1.328 + isForward: false, isVertical: false, expectedView: gSubView1, 1.329 + description: "Continuous scrolling test for sub view 1 (horizontal/backward)" } 1.330 + ] 1.331 + }, 1.332 + 1.333 + 1.334 + /************************************************************************** 1.335 + * Continuous scrolling test for |gSubView2| 1.336 + * |gSubView2| has only vertical scrollbar. 1.337 + **************************************************************************/ 1.338 + { retryWhenTransactionTimeout: 5, 1.339 + steps: [ 1.340 + // Vertical case 1.341 + { func: initElements, delay: 0, forVertical: true, 1.342 + description: "initElements" }, 1.343 + { func: clearWheelTransaction, delay: 0, 1.344 + description: "clearWheelTransaction" }, 1.345 + // Vertical wheel events should scroll |gSubView2|. 1.346 + { func: testContinuousScroll, delay: 0, offset: kPtInSubView2ForV, 1.347 + isForward: true, isVertical: true, expectedView: gSubView2, 1.348 + description: "Continuous scrolling test for sub view 2 (vertical/forward)" }, 1.349 + { func: testContinuousScroll, delay: 0, offset: kPtInSubView2ForV, 1.350 + isForward: false, isVertical: true, expectedView: gSubView2, 1.351 + description: "Continuous scrolling test for sub view 2 (vertical/backward)" } 1.352 + ] 1.353 + }, 1.354 + 1.355 + 1.356 + { retryWhenTransactionTimeout: 5, 1.357 + steps: [ 1.358 + // Horizontal case 1.359 + { func: initElements, delay: 0, forVertical: false, 1.360 + description: "initElements" }, 1.361 + { func: clearWheelTransaction, delay: 0, 1.362 + description: "clearWheelTransaction" }, 1.363 + // Horizontal wheel events should scroll its nearest scrollable ancestor 1.364 + // view, i.e., it is |gRootView|. 1.365 + { func: testContinuousScroll, delay: 0, offset: kPtInSubView2ForH, 1.366 + isForward: true, isVertical: false, expectedView: gRootView, 1.367 + description: "Continuous scrolling test for sub view 2 (horizontal/forward)" }, 1.368 + { func: testContinuousScroll, delay: 0, offset: kPtInSubView2ForH, 1.369 + isForward: false, isVertical: false, expectedView: gRootView, 1.370 + description: "Continuous scrolling test for sub view 2 (horizontal/backward)" } 1.371 + ] 1.372 + }, 1.373 + 1.374 + 1.375 + /************************************************************************** 1.376 + * Continuous scrolling test for |gSubView3| 1.377 + * |gSubView3| has only horizontal scrollbar. 1.378 + **************************************************************************/ 1.379 + { retryWhenTransactionTimeout: 5, 1.380 + steps: [ 1.381 + // Vertical case 1.382 + { func: initElements, delay: 0, forVertical: true, 1.383 + description: "initElements" }, 1.384 + { func: clearWheelTransaction, delay: 0, 1.385 + description: "clearWheelTransaction" }, 1.386 + // Vertical wheel events should scroll its nearest scrollable ancestor 1.387 + // view, i.e., it is |gRootView|. 1.388 + { func: testContinuousScroll, delay: 0, offset: kPtInSubView3ForV, 1.389 + isForward: true, isVertical: true, expectedView: gRootView, 1.390 + description: "Continuous scrolling test for sub view 3 (vertical/forward)" }, 1.391 + { func: testContinuousScroll, delay: 0, offset: kPtInSubView3ForV, 1.392 + isForward: false, isVertical: true, expectedView: gRootView, 1.393 + description: "Continuous scrolling test for sub view 3 (vertical/backward)" } 1.394 + ] 1.395 + }, 1.396 + 1.397 + 1.398 + { retryWhenTransactionTimeout: 5, 1.399 + steps: [ 1.400 + // Horizontal case 1.401 + { func: initElements, delay: 0, forVertical: false, 1.402 + description: "initElements" }, 1.403 + { func: clearWheelTransaction, delay: 0, 1.404 + description: "clearWheelTransaction" }, 1.405 + // Horitontal wheel events should scroll |gSubView3|. 1.406 + { func: testContinuousScroll, delay: 0, offset: kPtInSubView3ForH, 1.407 + isForward: true, isVertical: false, expectedView: gSubView3, 1.408 + description: "Continuous scrolling test for sub view 3 (horizontal/forward)" }, 1.409 + { func: testContinuousScroll, delay: 0, offset: kPtInSubView3ForH, 1.410 + isForward: false, isVertical: false, expectedView: gSubView3, 1.411 + description: "Continuous scrolling test for sub view 3 (horizontal/backward)" } 1.412 + ] 1.413 + }, 1.414 + 1.415 + 1.416 + /************************************************************************** 1.417 + * Don't reset transaction by a different direction wheel event 1.418 + * Even if a wheel event doesn't same direction as last wheel event, the 1.419 + * current transaction should not be reset. 1.420 + **************************************************************************/ 1.421 + { retryWhenTransactionTimeout: 5, 1.422 + steps: [ 1.423 + // Vertical -> Horizontal 1.424 + { func: initElements, delay: 0, forVertical: true, 1.425 + description: "initElements" }, 1.426 + { func: clearWheelTransaction, delay: 0, 1.427 + description: "clearWheelTransaction" }, 1.428 + // Create a transaction which targets |gRootView| by a vertical wheel 1.429 + // event. 1.430 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForV, 1.431 + isForward: true, isVertical: true, expectedView: gRootView, 1.432 + description: "Don't reset transaction by a different direction wheel event (1-1)" }, 1.433 + // Scroll back to top-most for easy cursor position specifying. 1.434 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForV, 1.435 + isForward: false, isVertical: true, expectedView: gRootView, 1.436 + description: "Don't reset transaction by a different direction wheel event (1-2)" }, 1.437 + // Send a horizontal wheel event over |gSubView1| but |gRootView| should 1.438 + // be scrolled. 1.439 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.440 + isForward: true, isVertical: false, expectedView: gRootView, 1.441 + canFailRandomly: { possibleView: gSubView1 }, 1.442 + description: "Don't reset transaction by a different direction wheel event (1-3)" } 1.443 + ] 1.444 + }, 1.445 + 1.446 + 1.447 + { retryWhenTransactionTimeout: 5, 1.448 + steps: [ 1.449 + // Horizontal -> Vertical 1.450 + { func: initElements, delay: 0, forVertical: false, 1.451 + description: "initElements" }, 1.452 + { func: clearWheelTransaction, delay: 0, 1.453 + description: "clearWheelTransaction" }, 1.454 + // Create a transaction which targets |gRootView| by a horizontal wheel 1.455 + // event. 1.456 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForH, 1.457 + isForward: true, isVertical: false, expectedView: gRootView, 1.458 + description: "Don't reset transaction by a different direction wheel event (2-1)" }, 1.459 + // Scroll back to left-most for easy cursor position specifying. 1.460 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForH, 1.461 + isForward: false, isVertical: false, expectedView: gRootView, 1.462 + description: "Don't reset transaction by a different direction wheel event (2-2)" }, 1.463 + // Send a vertical wheel event over |gSubView1| but |gRootView| should 1.464 + // be scrolled. 1.465 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForH, 1.466 + isForward: true, isVertical: true, expectedView: gRootView, 1.467 + canFailRandomly: { possibleView: gSubView1 }, 1.468 + description: "Don't reset transaction by a different direction wheel event (2-3)" } 1.469 + ] 1.470 + }, 1.471 + 1.472 + 1.473 + /************************************************************************** 1.474 + * Don't reset transaction even if a wheel event cannot scroll 1.475 + * Even if a wheel event cannot scroll to specified direction in the 1.476 + * current target view, the transaction should not be reset. E.g., there 1.477 + * are some devices which can scroll obliquely. If so, probably, users 1.478 + * cannot input only intended direction. 1.479 + **************************************************************************/ 1.480 + { retryWhenTransactionTimeout: 5, 1.481 + steps: [ 1.482 + // A view only has vertical scrollbar case. 1.483 + { func: initElements, delay: 0, forVertical: true, 1.484 + description: "initElements" }, 1.485 + { func: clearWheelTransaction, delay: 0, 1.486 + description: "clearWheelTransaction" }, 1.487 + // Create a transaction which targets |gSubView2|. 1.488 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView2ForV, 1.489 + isForward: true, isVertical: true, expectedView: gSubView2, 1.490 + description: "Don't reset transaction even if a wheel event cannot scroll (1-1)" }, 1.491 + // |gSubView2| doesn't have horizontal scrollbar but should not scroll 1.492 + // any views. 1.493 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView2ForV, 1.494 + isForward: true, isVertical: false, expectedView: null, 1.495 + description: "Don't reset transaction even if a wheel event cannot scroll (1-2)" } 1.496 + ] 1.497 + }, 1.498 + 1.499 + 1.500 + { retryWhenTransactionTimeout: 5, 1.501 + steps: [ 1.502 + // A view only has horizontal scrollbar case. 1.503 + { func: initElements, delay: 0, forVertical: true, 1.504 + description: "initElements" }, 1.505 + { func: clearWheelTransaction, delay: 0, 1.506 + description: "clearWheelTransaction" }, 1.507 + // Create a transaction which targets |gSubView3|. 1.508 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView3ForV, 1.509 + isForward: true, isVertical: false, expectedView: gSubView3, 1.510 + description: "Don't reset transaction even if a wheel event cannot scroll (2-1)" }, 1.511 + // |gSubView3| doesn't have vertical scrollbar but should not scroll any 1.512 + // views. 1.513 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView3ForV, 1.514 + isForward: true, isVertical: true, expectedView: null, 1.515 + description: "Don't reset transaction even if a wheel event cannot scroll (2-2)" } 1.516 + ] 1.517 + }, 1.518 + 1.519 + 1.520 + /************************************************************************** 1.521 + * Reset transaction by mouse down/mouse up events 1.522 + * Mouse down and mouse up events should cause resetting the current 1.523 + * transaction. 1.524 + **************************************************************************/ 1.525 + { retryWhenTransactionTimeout: 5, 1.526 + steps: [ 1.527 + // Vertical case 1.528 + { func: initElements, delay: 0, forVertical: true, 1.529 + description: "initElements" }, 1.530 + { func: clearWheelTransaction, delay: 0, 1.531 + description: "clearWheelTransaction" }, 1.532 + // Create a transaction which targets |gRootView|. 1.533 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForV, 1.534 + isForward: true, isVertical: true, expectedView: gRootView, 1.535 + description: "Reset transaction by mouse down/mouse up events (v-1)" }, 1.536 + // Scroll back to top-most for easy cursor position specifying. 1.537 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForV, 1.538 + isForward: false, isVertical: true, expectedView: gRootView, 1.539 + description: "Reset transaction by mouse down/mouse up events (v-2)" }, 1.540 + // Send mouse button events which should reset the current transaction. 1.541 + // So, the next wheel event should scroll |gSubView1|. 1.542 + { func: sendMouseButtonEvents, delay: 0, 1.543 + description: "sendMouseButtonEvents" }, 1.544 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.545 + isForward: true, isVertical: true, expectedView: gSubView1, 1.546 + description: "Reset transaction by mouse down/mouse up events (v-3)" } 1.547 + ] 1.548 + }, 1.549 + 1.550 + 1.551 + { retryWhenTransactionTimeout: 5, 1.552 + steps: [ 1.553 + // Horizontal case 1.554 + { func: initElements, delay: 0, forVertical: false, 1.555 + description: "initElements" }, 1.556 + { func: clearWheelTransaction, delay: 0, 1.557 + description: "clearWheelTransaction" }, 1.558 + // Create a transaction which targets |gRootView|. 1.559 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForH, 1.560 + isForward: true, isVertical: false, expectedView: gRootView, 1.561 + description: "Reset transaction by mouse down/mouse up events (h-1)" }, 1.562 + // Scroll back to left-most for easy cursor position specifying. 1.563 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForH, 1.564 + isForward: false, isVertical: false, expectedView: gRootView, 1.565 + description: "Reset transaction by mouse down/mouse up events (h-2)" }, 1.566 + // Send mouse button events which should reset the current transaction. 1.567 + // So, the next wheel event should scroll |gSubView1|. 1.568 + { func: sendMouseButtonEvents, delay: 0, 1.569 + description: "sendMouseButtonEvents" }, 1.570 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForH, 1.571 + isForward: true, isVertical: false, expectedView: gSubView1, 1.572 + description: "Reset transaction by mouse down/mouse up events (h-3)" } 1.573 + ] 1.574 + }, 1.575 + 1.576 + 1.577 + /************************************************************************** 1.578 + * Reset transaction by a key event 1.579 + * A key event should cause resetting the current transaction. 1.580 + **************************************************************************/ 1.581 + { retryWhenTransactionTimeout: 5, 1.582 + steps: [ 1.583 + // Vertical case 1.584 + { func: initElements, delay: 0, forVertical: true, 1.585 + description: "initElements" }, 1.586 + { func: clearWheelTransaction, delay: 0, 1.587 + description: "clearWheelTransaction" }, 1.588 + // Create a transaction which targets |gRootView|. 1.589 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForV, 1.590 + isForward: true, isVertical: true, expectedView: gRootView, 1.591 + description: "Reset transaction by a key event (v-1)" }, 1.592 + // Scroll back to top-most for easy cursor position specifying. 1.593 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForV, 1.594 + isForward: false, isVertical: true, expectedView: gRootView, 1.595 + description: "Reset transaction by a key event (v-2)" }, 1.596 + // Send a key event which should reset the current transaction. So, the 1.597 + // next wheel event should scroll |gSubView1|. 1.598 + { func: sendKeyEvents, delay: 0, key: "a", 1.599 + description: "sendKeyEvents" }, 1.600 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.601 + isForward: true, isVertical: true, expectedView: gSubView1, 1.602 + description: "Reset transaction by a key event (v-3)" } 1.603 + ] 1.604 + }, 1.605 + 1.606 + 1.607 + { retryWhenTransactionTimeout: 5, 1.608 + steps: [ 1.609 + // Horizontal case 1.610 + { func: initElements, delay: 0, forVertical: false, 1.611 + description: "initElements" }, 1.612 + { func: clearWheelTransaction, delay: 0, 1.613 + description: "clearWheelTransaction" }, 1.614 + // Create a transaction which targets |gRootView|. 1.615 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForH, 1.616 + isForward: true, isVertical: false, expectedView: gRootView, 1.617 + description: "Reset transaction by a key event (h-1)" }, 1.618 + // Scroll back to left-most for easy cursor position specifying. 1.619 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForH, 1.620 + isForward: false, isVertical: false, expectedView: gRootView, 1.621 + description: "Reset transaction by a key event (h-2)" }, 1.622 + // Send a key event which should reset the current transaction. So, the 1.623 + // next wheel event should scroll |gSubView1|. 1.624 + { func: sendKeyEvents, delay: 0, key: "a", 1.625 + description: "sendKeyEvents" }, 1.626 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForH, 1.627 + isForward: true, isVertical: false, expectedView: gSubView1, 1.628 + description: "Reset transaction by a key event (h-3)" } 1.629 + ] 1.630 + }, 1.631 + 1.632 + 1.633 + /************************************************************************** 1.634 + * Reset transaction by a mouse move event 1.635 + * A mouse move event can cause reseting the current transaction even if 1.636 + * mouse cursor is inside the target view of current transaction. Only 1.637 + * when a wheel event is fired after |gIgnoreMoveDelay| milliseconds since 1.638 + * the first mouse move event from last wheel event, the transaction 1.639 + * should be reset. 1.640 + **************************************************************************/ 1.641 + { retryWhenTransactionTimeout: 5, 1.642 + steps: [ 1.643 + // Vertical case 1.644 + { func: initElements, delay: 0, forVertical: true, 1.645 + description: "initElements" }, 1.646 + { func: clearWheelTransaction, delay: 0, 1.647 + description: "clearWheelTransaction" }, 1.648 + // Create a transaction which targets |gRootView|. 1.649 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForV, 1.650 + isForward: true, isVertical: true, expectedView: gRootView, 1.651 + description: "Reset transaction by a mouse move event (v-1)" }, 1.652 + // Scroll back to top-most for easy cursor position specifying. 1.653 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForV, 1.654 + isForward: false, isVertical: true, expectedView: gRootView, 1.655 + description: "Reset transaction by a mouse move event (v-2)" }, 1.656 + // Send a mouse move event immediately after last wheel event, then, 1.657 + // current transaction should be kept. 1.658 + { func: sendMouseMoveEvent, delay: 0, offset: kPtInSubView1ForV, 1.659 + description: "sendMouseMoveEvent" }, 1.660 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.661 + isForward: true, isVertical: true, expectedView: gRootView, 1.662 + canFailRandomly: { possibleView: gSubView1 }, 1.663 + description: "Reset transaction by a mouse move event (v-3)" }, 1.664 + // Scroll back to top-most for easy cursor position specifying. 1.665 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.666 + isForward: false, isVertical: true, expectedView: gRootView, 1.667 + canFailRandomly: { possibleView: gSubView1 }, 1.668 + description: "Reset transaction by a mouse move event (v-4)" }, 1.669 + // Send a mouse move event after |gIgnoreMoveDelay| milliseconds since 1.670 + // last wheel event, then, current transaction should be kept. 1.671 + { func: sendMouseMoveEvent, delay: gEnoughForIgnoreMoveDelay, 1.672 + offset: kPtInSubView1ForV, 1.673 + description: "sendMouseMoveEvent" }, 1.674 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.675 + isForward: true, isVertical: true, expectedView: gRootView, 1.676 + canFailRandomly: { possibleView: gSubView1 }, 1.677 + description: "Reset transaction by a mouse move event (v-5)" }, 1.678 + // Scroll back to top-most for easy cursor position specifying. 1.679 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.680 + isForward: false, isVertical: true, expectedView: gRootView, 1.681 + canFailRandomly: { possibleView: gSubView1 }, 1.682 + description: "Reset transaction by a mouse move event (v-6)" }, 1.683 + // Send a wheel event after |gIgnoreMoveDelay| milliseconds since last 1.684 + // mouse move event but it is fired immediately after the last wheel 1.685 + // event, then, current transaction should be kept. 1.686 + { func: sendMouseMoveEvent, delay: 0, offset: kPtInSubView1ForV, 1.687 + description: "sendMouseMoveEvent" }, 1.688 + { func: testOneTimeScroll, delay: gEnoughForIgnoreMoveDelay, 1.689 + offset: kPtInSubView1ForV, 1.690 + isForward: true, isVertical: true, expectedView: gRootView, 1.691 + canFailRandomly: { possibleView: gSubView1 }, 1.692 + description: "Reset transaction by a mouse move event (v-7)" }, 1.693 + // Scroll back to top-most for easy cursor position specifying. 1.694 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.695 + isForward: false, isVertical: true, expectedView: gRootView, 1.696 + canFailRandomly: { possibleView: gSubView1 }, 1.697 + description: "Reset transaction by a mouse move event (v-8)" }, 1.698 + // Send a wheel event after |gIgnoreMoveDelay| milliseconds have passed 1.699 + // since last mouse move event which is fired after |gIgnoreMoveDelay| 1.700 + // milliseconds since last wheel event, then, current transaction should 1.701 + // be reset. 1.702 + { func: sendMouseMoveEvent, delay: gEnoughForIgnoreMoveDelay, 1.703 + offset: kPtInSubView1ForV, 1.704 + description: "sendMouseMoveEvent" }, 1.705 + { func: testOneTimeScroll, delay: gEnoughForIgnoreMoveDelay, 1.706 + offset: kPtInSubView1ForV, 1.707 + isForward: true, isVertical: true, expectedView: gSubView1, 1.708 + canFailRandomly: { possibleView: gRootView }, 1.709 + description: "Reset transaction by a mouse move event (v-9)" } 1.710 + ] 1.711 + }, 1.712 + 1.713 + 1.714 + { retryWhenTransactionTimeout: 5, 1.715 + steps: [ 1.716 + // Horizontal case 1.717 + { func: initElements, delay: 0, forVertical: false, 1.718 + description: "initElements" }, 1.719 + { func: clearWheelTransaction, delay: 0, 1.720 + description: "clearWheelTransaction" }, 1.721 + // Create a transaction which targets |gRootView|. 1.722 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForH, 1.723 + isForward: true, isVertical: false, expectedView: gRootView, 1.724 + canFailRandomly: { possibleView: gSubView1 }, 1.725 + description: "Reset transaction by a mouse move event (h-1)" }, 1.726 + // Scroll back to top-most for easy cursor position specifying. 1.727 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForH, 1.728 + isForward: false, isVertical: false, expectedView: gRootView, 1.729 + canFailRandomly: { possibleView: gSubView1 }, 1.730 + description: "Reset transaction by a mouse move event (h-2)" }, 1.731 + // Send a mouse move event immediately after last wheel event, then, 1.732 + // current transaction should be kept. 1.733 + { func: sendMouseMoveEvent, delay: 0, offset: kPtInSubView1ForH, 1.734 + description: "sendMouseMoveEvent" }, 1.735 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForH, 1.736 + isForward: true, isVertical: false, expectedView: gRootView, 1.737 + canFailRandomly: { possibleView: gSubView1 }, 1.738 + description: "Reset transaction by a mouse move event (h-3)" }, 1.739 + // Scroll back to top-most for easy cursor position specifying. 1.740 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForH, 1.741 + isForward: false, isVertical: false, expectedView: gRootView, 1.742 + canFailRandomly: { possibleView: gSubView1 }, 1.743 + description: "Reset transaction by a mouse move event (h-4)" }, 1.744 + // Send a mouse move event after |gIgnoreMoveDelay| milliseconds since 1.745 + // last wheel event, then, current transaction should be kept. 1.746 + { func: sendMouseMoveEvent, delay: gEnoughForIgnoreMoveDelay, 1.747 + offset: kPtInSubView1ForH, 1.748 + description: "sendMouseMoveEvent" }, 1.749 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForH, 1.750 + isForward: true, isVertical: false, expectedView: gRootView, 1.751 + canFailRandomly: { possibleView: gSubView1 }, 1.752 + description: "Reset transaction by a mouse move event (h-5)" }, 1.753 + // Scroll back to top-most for easy cursor position specifying. 1.754 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForH, 1.755 + isForward: false, isVertical: false, expectedView: gRootView, 1.756 + canFailRandomly: { possibleView: gSubView1 }, 1.757 + description: "Reset transaction by a mouse move event (h-6)" }, 1.758 + // Send a wheel event after |gIgnoreMoveDelay| milliseconds since last 1.759 + // mouse move event but it is fired immediately after the last wheel 1.760 + // event, then, current transaction should be kept. 1.761 + { func: sendMouseMoveEvent, delay: 0, offset: kPtInSubView1ForH, 1.762 + description: "sendMouseMoveEvent" }, 1.763 + { func: testOneTimeScroll, delay: gEnoughForIgnoreMoveDelay, 1.764 + offset: kPtInSubView1ForH, 1.765 + isForward: true, isVertical: false, expectedView: gRootView, 1.766 + canFailRandomly: { possibleView: gSubView1 }, 1.767 + description: "Reset transaction by a mouse move event (h-7)" }, 1.768 + // Scroll back to top-most for easy cursor position specifying. 1.769 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForH, 1.770 + isForward: false, isVertical: false, expectedView: gRootView, 1.771 + canFailRandomly: { possibleView: gSubView1 }, 1.772 + description: "Reset transaction by a mouse move event (h-8)" }, 1.773 + // Send a wheel event after |gIgnoreMoveDelay| milliseconds have passed 1.774 + // since last mouse move event which is fired after |gIgnoreMoveDelay| 1.775 + // milliseconds since last wheel event, then, current transaction should 1.776 + // be reset. 1.777 + { func: sendMouseMoveEvent, delay: gEnoughForIgnoreMoveDelay, 1.778 + offset: kPtInSubView1ForH, 1.779 + description: "sendMouseMoveEvent" }, 1.780 + { func: testOneTimeScroll, delay: gEnoughForIgnoreMoveDelay, 1.781 + offset: kPtInSubView1ForH, 1.782 + isForward: true, isVertical: false, expectedView: gSubView1, 1.783 + canFailRandomly: { possibleView: gRootView }, 1.784 + description: "Reset transaction by a mouse move event (h-9)" } 1.785 + ] 1.786 + }, 1.787 + 1.788 + 1.789 + /************************************************************************** 1.790 + * Reset transaction by a mouse move event on outside of view 1.791 + * When mouse cursor is moved to outside of the current target view, the 1.792 + * transaction should be reset immediately. 1.793 + **************************************************************************/ 1.794 + { retryWhenTransactionTimeout: 5, 1.795 + steps: [ 1.796 + // Vertical case 1.797 + { func: initElements, delay: 0, forVertical: true, 1.798 + description: "initElements" }, 1.799 + { func: clearWheelTransaction, delay: 0, 1.800 + description: "clearWheelTransaction" }, 1.801 + // Create a transaction which targets |gSubView1|. 1.802 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.803 + isForward: true, isVertical: true, expectedView: gSubView1, 1.804 + description: "Reset transaction by a mouse move event on outside of view (v-1)" }, 1.805 + // Send mouse move event over |gRootView|. 1.806 + { func: sendMouseMoveEvent, delay: 0, offset: kPtInRootViewForV, 1.807 + description: "sendMouseMoveEvent" }, 1.808 + // Send Wheel event over |gRootView| which should be scrolled. 1.809 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForV, 1.810 + isForward: true, isVertical: true, expectedView: gRootView, 1.811 + description: "Reset transaction by a mouse move event on outside of view (v-2)" } 1.812 + ] 1.813 + }, 1.814 + 1.815 + 1.816 + { retryWhenTransactionTimeout: 5, 1.817 + steps: [ 1.818 + // Horizontal case 1.819 + { func: initElements, delay: 0, forVertical: false, 1.820 + description: "initElements" }, 1.821 + { func: clearWheelTransaction, delay: 0, 1.822 + description: "clearWheelTransaction" }, 1.823 + // Create a transaction which targets |gSubView1|. 1.824 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForH, 1.825 + isForward: true, isVertical: true, expectedView: gSubView1, 1.826 + description: "Reset transaction by a mouse move event on outside of view (h-1)" }, 1.827 + // Send mouse move event over |gRootView|. 1.828 + { func: sendMouseMoveEvent, delay: 0, offset: kPtInRootViewForH, 1.829 + description: "sendMouseMoveEvent" }, 1.830 + // Send Wheel event over |gRootView| which should be scrolled. 1.831 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForH, 1.832 + isForward: true, isVertical: true, expectedView: gRootView, 1.833 + description: "Reset transaction by a mouse move event on outside of view (h-2)" } 1.834 + ] 1.835 + }, 1.836 + 1.837 + 1.838 + /************************************************************************** 1.839 + * Timeout test 1.840 + * A view should not be scrolled during another to be transaction for 1.841 + * another view scrolling. However, a wheel event which is sent after 1.842 + * timeout, a view which is under the mouse cursor should be scrolled. 1.843 + **************************************************************************/ 1.844 + { retryWhenTransactionTimeout: 5, 1.845 + steps: [ 1.846 + // Vertical case 1.847 + { func: initElements, delay: 0, forVertical: true, 1.848 + description: "initElements" }, 1.849 + { func: clearWheelTransaction, delay: 0, 1.850 + description: "clearWheelTransaction" }, 1.851 + // First, create a transaction which should target the |gRootView|. 1.852 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForV, 1.853 + isForward: true, isVertical: true, expectedView: gRootView, 1.854 + description: "Timeout test (v-1)" }, 1.855 + // Scroll back to top-most for easy cursor position specifying. 1.856 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForV, 1.857 + isForward: false, isVertical: true, expectedView: gRootView, 1.858 + description: "Timeout test (v-2)" }, 1.859 + // A wheel event over |gSubView1| should not scroll it during current 1.860 + // transaction. 1.861 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.862 + isForward: true, isVertical: true, expectedView: gRootView, 1.863 + canFailRandomly: { possibleView: gSubView1 }, 1.864 + description: "Timeout test (v-3)" }, 1.865 + // Scroll back to top-most again. 1.866 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.867 + isForward: false, isVertical: true, expectedView: gRootView, 1.868 + canFailRandomly: { possibleView: gSubView1 }, 1.869 + description: "Timeout test (v-4)" }, 1.870 + // A wheel event over |gSubView1| after timeout should scroll 1.871 + // |gSubView1|. 1.872 + { func: testOneTimeScroll, delay: gEnoughForTimeout, 1.873 + offset: kPtInSubView1ForV, 1.874 + isForward: true, isVertical: true, expectedView: gSubView1, 1.875 + isTimeoutTesting: true, 1.876 + description: "Timeout test (v-5)" } 1.877 + ] 1.878 + }, 1.879 + 1.880 + 1.881 + { retryWhenTransactionTimeout: 5, 1.882 + steps: [ 1.883 + // Horizontal case 1.884 + { func: initElements, delay: 0, forVertical: false, 1.885 + description: "initElements" }, 1.886 + { func: clearWheelTransaction, delay: 0, 1.887 + description: "clearWheelTransaction" }, 1.888 + // First, create a transaction which should target the |gRootView|. 1.889 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForH, 1.890 + isForward: true, isVertical: false, expectedView: gRootView, 1.891 + description: "Timeout test (h-1)" }, 1.892 + // Scroll back to left-most for easy cursor position specifying. 1.893 + { func: testOneTimeScroll, delay: 0, offset: kPtInRootViewForH, 1.894 + isForward: false, isVertical: false, expectedView: gRootView, 1.895 + description: "Timeout test (h-2)" }, 1.896 + // A wheel event over |gSubView1| should not scroll it during current 1.897 + // transaction. 1.898 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForH, 1.899 + isForward: true, isVertical: false, expectedView: gRootView, 1.900 + canFailRandomly: { possibleView: gSubView1 }, 1.901 + description: "Timeout test (h-3)" }, 1.902 + // Scroll back to left-most again. 1.903 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForH, 1.904 + isForward: false, isVertical: false, expectedView: gRootView, 1.905 + canFailRandomly: { possibleView: gSubView1 }, 1.906 + description: "Timeout test (h-4)" }, 1.907 + // A wheel event over |gSubView1| after timeout should scroll 1.908 + // |gSubView1|. 1.909 + { func: testOneTimeScroll, delay: gEnoughForTimeout, 1.910 + offset: kPtInSubView1ForH, 1.911 + isForward: true, isVertical: false, expectedView: gSubView1, 1.912 + isTimeoutTesting: true, 1.913 + description: "Timeout test (h-5)" } 1.914 + ] 1.915 + }, 1.916 + 1.917 + 1.918 + /************************************************************************** 1.919 + * Timeout test even with many wheel events 1.920 + * This tests whether timeout is occurred event if wheel events are sent. 1.921 + * The transaction should not be updated by non-scrollable wheel events. 1.922 + **************************************************************************/ 1.923 + { retryWhenTransactionTimeout: 5, 1.924 + steps: [ 1.925 + // Vertical case 1.926 + { func: initElements, delay: 0, forVertical: true, 1.927 + description: "initElements" }, 1.928 + { func: clearWheelTransaction, delay: 0, 1.929 + description: "clearWheelTransaction" }, 1.930 + // Scroll |gSubView1| to bottom-most. 1.931 + { func: testContinuousScroll, delay: 0, offset: kPtInSubView1ForV, 1.932 + isForward: true, isVertical: true, expectedView: gSubView1, 1.933 + description: "Timeout test even with many wheel events (v-1)" }, 1.934 + // Don't scroll any views before timeout. 1.935 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.936 + isForward: true, isVertical: true, expectedView: null, 1.937 + canFailRandomly: { possibleView: gRootView }, 1.938 + description: "Timeout test even with many wheel events (v-2)" }, 1.939 + // Recreate a transaction which is scrolling |gRootView| after time out. 1.940 + { func: testRestartScroll, delay: 0, offset: kPtInSubView1ForV, 1.941 + isForward: true, isVertical: true, expectedView: gRootView, 1.942 + description: "Timeout test even with many wheel events (v-3)" } 1.943 + ] 1.944 + }, 1.945 + 1.946 + 1.947 + { retryWhenTransactionTimeout: 5, 1.948 + steps: [ 1.949 + // Horizontal case 1.950 + { func: initElements, delay: 0, forVertical: false, 1.951 + description: "initElements" }, 1.952 + { func: clearWheelTransaction, delay: 0, 1.953 + description: "clearWheelTransaction" }, 1.954 + // Scroll |gSubView1| to right-most. 1.955 + { func: testContinuousScroll, delay: 0, offset: kPtInSubView1ForH, 1.956 + isForward: true, isVertical: false, expectedView: gSubView1, 1.957 + description: "Timeout test even with many wheel events (h-1)" }, 1.958 + // Don't scroll any views before timeout. 1.959 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForH, 1.960 + isForward: true, isVertical: false, expectedView: null, 1.961 + canFailRandomly: { possibleView: gRootView }, 1.962 + description: "Timeout test even with many wheel events (h-2)" }, 1.963 + // Recreate a transaction which is scrolling |gRootView| after time out. 1.964 + { func: testRestartScroll, delay: 0, offset: kPtInSubView1ForH, 1.965 + isForward: true, isVertical: false, expectedView: gRootView, 1.966 + description: "Timeout test even with many wheel events (h-3)" } 1.967 + ] 1.968 + }, 1.969 + 1.970 + 1.971 + /************************************************************************** 1.972 + * Very large scrolling wheel event 1.973 + * If the delta value is larger than the scrolling page size, it should be 1.974 + * scrolled only one page instead of the delta value. 1.975 + **************************************************************************/ 1.976 + { retryWhenTransactionTimeout: 5, 1.977 + steps: [ 1.978 + { func: initElements, delay: 0, forVertical: true, 1.979 + description: "initElements" }, 1.980 + { func: clearWheelTransaction, delay: 0, 1.981 + description: "clearWheelTransaction" }, 1.982 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.983 + isForward: true, isVertical: true, expectedView: gSubView1, 1.984 + delta: 5000, 1.985 + description: "Very large delta scrolling (v-1)" }, 1.986 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.987 + isForward: true, isVertical: true, expectedView: gSubView1, 1.988 + delta: 5000, 1.989 + description: "Very large delta scrolling (v-2)" }, 1.990 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.991 + isForward: true, isVertical: false, expectedView: gSubView1, 1.992 + delta: 5000, 1.993 + description: "Very large delta scrolling (h-1)" }, 1.994 + { func: testOneTimeScroll, delay: 0, offset: kPtInSubView1ForV, 1.995 + isForward: true, isVertical: false, expectedView: gSubView1, 1.996 + delta: 5000, 1.997 + description: "Very large delta scrolling (h-2)" } 1.998 + ] 1.999 + } 1.1000 + ]; 1.1001 +} 1.1002 + 1.1003 +/****************************************************************************** 1.1004 + * Actions for preparing tests 1.1005 + ******************************************************************************/ 1.1006 + 1.1007 +function initElements() 1.1008 +{ 1.1009 + _clearTimer(); 1.1010 + 1.1011 + function resetScrollPosition(aElement) 1.1012 + { 1.1013 + aElement.scrollTop = 0; 1.1014 + aElement.scrollLeft = 0; 1.1015 + } 1.1016 + 1.1017 + function initInRootView(aElement, aPt) 1.1018 + { 1.1019 + aElement.offset = 1.1020 + gCurrentTest.forVertical ? aPt : { x: aPt.y, y: aPt.x }; 1.1021 + } 1.1022 + 1.1023 + const kDisplay = gCurrentTest.forVertical ? "block" : "inline-block"; 1.1024 + gSubView1.style.display = kDisplay; 1.1025 + gSubView2.style.display = kDisplay; 1.1026 + gSubView3.style.display = kDisplay; 1.1027 + 1.1028 + resetScrollPosition(gRootView); 1.1029 + resetScrollPosition(gSubView1); 1.1030 + resetScrollPosition(gSubView2); 1.1031 + resetScrollPosition(gSubView3); 1.1032 + 1.1033 + runNextTestStep(); 1.1034 +} 1.1035 + 1.1036 +function clearWheelTransaction() 1.1037 +{ 1.1038 + _clearTimer(); 1.1039 + _clearTransaction(); 1.1040 + runNextTestStep(); 1.1041 +} 1.1042 + 1.1043 +function sendKeyEvents() 1.1044 +{ 1.1045 + _clearTimer(); 1.1046 + synthesizeKey(gCurrentTest.key, {}, window); 1.1047 + runNextTestStep(); 1.1048 +} 1.1049 + 1.1050 +function sendMouseButtonEvents() 1.1051 +{ 1.1052 + _clearTimer(); 1.1053 + synthesizeMouse(gRootView, -1, -1, { type:"mousedown" }, window); 1.1054 + synthesizeMouse(gRootView, -1, -1, { type:"mouseup" }, window); 1.1055 + runNextTestStep(); 1.1056 +} 1.1057 + 1.1058 +function sendMouseMoveEvent() 1.1059 +{ 1.1060 + _clearTimer(); 1.1061 + _fireMouseMoveEvent(gCurrentTest.offset); 1.1062 + runNextTestStep(); 1.1063 +} 1.1064 + 1.1065 +/****************************************************************************** 1.1066 + * Utilities for testing functions 1.1067 + ******************************************************************************/ 1.1068 + 1.1069 +function _clearTransaction() 1.1070 +{ 1.1071 + synthesizeMouse(gRootView, -1, -1, { type:"mousedown" }, window); 1.1072 + synthesizeMouse(gRootView, -1, -1, { type:"mouseup" }, window); 1.1073 +} 1.1074 + 1.1075 +function _saveScrollPositions() 1.1076 +{ 1.1077 + function save(aElement) 1.1078 + { 1.1079 + aElement.prevTop = aElement.scrollTop; 1.1080 + aElement.prevLeft = aElement.scrollLeft; 1.1081 + } 1.1082 + save(gRootView); 1.1083 + save(gSubView1); 1.1084 + save(gSubView2); 1.1085 + save(gSubView3); 1.1086 +} 1.1087 + 1.1088 +function _fireMouseMoveEvent(aOffset) 1.1089 +{ 1.1090 + synthesizeMouse(gRootView, aOffset.x, aOffset.y, { type:"mousemove" }, window); 1.1091 +} 1.1092 + 1.1093 +function _fireWheelScrollEvent(aOffset, aIsVertical, aForward, aDelta) 1.1094 +{ 1.1095 + var event = { deltaMode: WheelEvent.DOM_DELTA_LINE }; 1.1096 + if (aIsVertical) { 1.1097 + event.deltaY = aForward ? aDelta : -aDelta; 1.1098 + } else { 1.1099 + event.deltaX = aForward ? aDelta : -aDelta; 1.1100 + } 1.1101 + synthesizeWheel(gRootView, aOffset.x, aOffset.y, event, window); 1.1102 +} 1.1103 + 1.1104 +function _canScroll(aElement, aIsVertical, aForward) 1.1105 +{ 1.1106 + if (aIsVertical) { 1.1107 + if (!aForward) 1.1108 + return aElement.scrollTop > 0; 1.1109 + return aElement.scrollHeight > aElement.scrollTop + aElement.clientHeight; 1.1110 + } 1.1111 + if (!aForward) 1.1112 + return aElement.scrollLeft > 0; 1.1113 + return aElement.scrollWidth > aElement.scrollLeft + aElement.clientWidth; 1.1114 +} 1.1115 + 1.1116 +const kNotScrolled = 0; 1.1117 +const kScrolledToTop = 1; 1.1118 +const kScrolledToBottom = 2; 1.1119 +const kScrolledToLeft = 4; 1.1120 +const kScrolledToRight = 8; 1.1121 + 1.1122 +const kScrolledVertical = kScrolledToTop | kScrolledToBottom; 1.1123 +const kScrolledHorizontal = kScrolledToLeft | kScrolledToRight; 1.1124 + 1.1125 +function _getScrolledState(aElement) 1.1126 +{ 1.1127 + var ret = kNotScrolled; 1.1128 + if (aElement.scrollTop != aElement.prevTop) { 1.1129 + ret |= aElement.scrollTop < aElement.prevTop ? kScrolledToTop : 1.1130 + kScrolledToBottom; 1.1131 + } 1.1132 + if (aElement.scrollLeft != aElement.prevLeft) { 1.1133 + ret |= aElement.scrollLeft < aElement.prevLeft ? kScrolledToLeft : 1.1134 + kScrolledToRight; 1.1135 + } 1.1136 + return ret; 1.1137 +} 1.1138 + 1.1139 +function _getExpectedScrolledState() 1.1140 +{ 1.1141 + return gCurrentTest.isVertical ? 1.1142 + gCurrentTest.isForward ? kScrolledToBottom : kScrolledToTop : 1.1143 + gCurrentTest.isForward ? kScrolledToRight : kScrolledToLeft; 1.1144 +} 1.1145 + 1.1146 +function _getScrolledStateText(aScrolledState) 1.1147 +{ 1.1148 + if (aScrolledState == kNotScrolled) 1.1149 + return "Not scrolled"; 1.1150 + 1.1151 + var s = "scrolled to "; 1.1152 + if (aScrolledState & kScrolledVertical) { 1.1153 + s += aScrolledState & kScrolledToTop ? "backward" : "forward"; 1.1154 + s += " (vertical)" 1.1155 + if (aScrolledState & kScrolledHorizontal) 1.1156 + s += " and to "; 1.1157 + } 1.1158 + if (aScrolledState & kScrolledHorizontal) { 1.1159 + s += aScrolledState & kScrolledToLeft ? "backward" : "forward"; 1.1160 + s += " (horizontal)" 1.1161 + } 1.1162 + return s; 1.1163 +} 1.1164 + 1.1165 +function _getCurrentTestList() 1.1166 +{ 1.1167 + return gTestLists[gCurrentTestListStatus.nextListIndex - 1]; 1.1168 +} 1.1169 + 1.1170 +function _clearTimer() 1.1171 +{ 1.1172 + clearTimeout(gTimer); 1.1173 + gTimer = 0; 1.1174 +} 1.1175 + 1.1176 +/****************************************************************************** 1.1177 + * Testing functions 1.1178 + ******************************************************************************/ 1.1179 + 1.1180 +/** 1.1181 + * Note that testing functions must set following variables: 1.1182 + * 1.1183 + * gCurrentTest.repeatTest: See comment in |continueTest|. 1.1184 + * gCurrentTest.autoRepeatDelay: See comment in |continueTest|. 1.1185 + * gListenScrollEvent: When this is not true, the event handlers ignores the 1.1186 + * events. 1.1187 + */ 1.1188 + 1.1189 +function testContinuousScroll() 1.1190 +{ 1.1191 + /** 1.1192 + * Testing continuous scrolling. This function synthesizes a wheel event. If 1.1193 + * the test was success, this function will be recalled automatically. 1.1194 + * And when a generating wheel event cannot scroll the expected view, this 1.1195 + * function fires the wheel event only one time. 1.1196 + * 1.1197 + * @param gCurrentTest.offset 1.1198 + * The cursor position of firing wheel event. The values are offset 1.1199 + * from |gRootView|. 1.1200 + * @param gCurrentTest.isVertical 1.1201 + * Whether the wheel event is for virtical scrolling or horizontal. 1.1202 + * @param gCurrentTest.isForward 1.1203 + * Whether the wheel event is to forward or to backward. 1.1204 + * @param gCurrentTest.expectedView 1.1205 + * The expected view which will be scrolled by wheel event. This 1.1206 + * value must not be null. 1.1207 + */ 1.1208 + 1.1209 + _clearTimer(); 1.1210 + _saveScrollPositions(); 1.1211 + if (!gCurrentTest.expectedView) { 1.1212 + runNextTestStep(); 1.1213 + return; 1.1214 + } 1.1215 + 1.1216 + gLitesnEvents = kListenEvent_All; 1.1217 + gCurrentTest.repeatTest = true; 1.1218 + gCurrentTest.autoRepeatDelay = 0; 1.1219 + 1.1220 + if (!_canScroll(gCurrentTest.expectedView, 1.1221 + gCurrentTest.isVertical, gCurrentTest.isForward)) { 1.1222 + gCurrentTest.expectedView = null; 1.1223 + } 1.1224 + var delta = gCurrentTest.delta ? gCurrentTest.delta : 4; 1.1225 + _fireWheelScrollEvent(gCurrentTest.offset, 1.1226 + gCurrentTest.isVertical, gCurrentTest.isForward, delta); 1.1227 +} 1.1228 + 1.1229 +function testOneTimeScroll() 1.1230 +{ 1.1231 + /** 1.1232 + * Testing one wheel event. |runNextTestStep| will be called immediately 1.1233 + * after this function by |onScrollView| or |onTimeout|. 1.1234 + * 1.1235 + * @param gCurrentTest.offset 1.1236 + * The cursor position of firing wheel event. The values are offset 1.1237 + * from |gRootView|. 1.1238 + * @param gCurrentTest.isVertical 1.1239 + * Whether the wheel event is for virtical scrolling or horizontal. 1.1240 + * @param gCurrentTest.isForward 1.1241 + * Whether the wheel event is to forward or to backward. 1.1242 + * @param gCurrentTest.expectedView 1.1243 + * The expected view which will be scrolled by wheel event. This 1.1244 + * value can be null. It means any views should not be scrolled. 1.1245 + */ 1.1246 + 1.1247 + _clearTimer(); 1.1248 + _saveScrollPositions(); 1.1249 + 1.1250 + gLitesnEvents = kListenEvent_All; 1.1251 + gCurrentTest.repeatTest = false; 1.1252 + gCurrentTest.autoRepeatDelay = 0; 1.1253 + 1.1254 + var delta = gCurrentTest.delta ? gCurrentTest.delta : 4; 1.1255 + _fireWheelScrollEvent(gCurrentTest.offset, 1.1256 + gCurrentTest.isVertical, gCurrentTest.isForward, delta); 1.1257 +} 1.1258 + 1.1259 +function testRestartScroll() 1.1260 +{ 1.1261 + /** 1.1262 + * Testing restart to scroll in expected view after timeout from the current 1.1263 + * transaction. This function recall this itself until to success this test 1.1264 + * or timeout from this test. 1.1265 + * 1.1266 + * @param gCurrentTest.offset 1.1267 + * The cursor position of firing wheel event. The values are offset 1.1268 + * from |gRootView|. 1.1269 + * @param gCurrentTest.isVertical 1.1270 + * Whether the wheel event is for virtical scrolling or horizontal. 1.1271 + * @param gCurrentTest.isForward 1.1272 + * Whether the wheel event is to forward or to backward. 1.1273 + * @param gCurrentTest.expectedView 1.1274 + * The expected view which will be scrolled by wheel event. This 1.1275 + * value must not be null. 1.1276 + */ 1.1277 + 1.1278 + _clearTimer(); 1.1279 + _saveScrollPositions(); 1.1280 + 1.1281 + if (!gCurrentTest.wasTransactionTimeout) { 1.1282 + gCurrentTest.repeatTest = true; 1.1283 + gCurrentTest.autoRepeatDelay = gTimeout / 3; 1.1284 + gLitesnEvents = kListenEvent_All; 1.1285 + gCurrentTest.isTimeoutTesting = true; 1.1286 + if (gCurrentTest.expectedView) { 1.1287 + gCurrentTest.expectedViewAfterTimeout = gCurrentTest.expectedView; 1.1288 + gCurrentTest.expectedView = null; 1.1289 + } 1.1290 + } else { 1.1291 + gCurrentTest.repeatTest = false; 1.1292 + gCurrentTest.autoRepeatDelay = 0; 1.1293 + gLitesnEvents = kListenEvent_All; 1.1294 + gCurrentTest.isTimeoutTesting = false; 1.1295 + gCurrentTest.expectedView = gCurrentTest.expectedViewAfterTimeout; 1.1296 + } 1.1297 + 1.1298 + var delta = gCurrentTest.delta ? gCurrentTest.delta : 4; 1.1299 + _fireWheelScrollEvent(gCurrentTest.offset, 1.1300 + gCurrentTest.isVertical, gCurrentTest.isForward, delta); 1.1301 +} 1.1302 + 1.1303 +/****************************************************************************** 1.1304 + * Event handlers 1.1305 + ******************************************************************************/ 1.1306 + 1.1307 +function onScrollView(aEvent) 1.1308 +{ 1.1309 + /** 1.1310 + * Scroll event handler of |gRootView|, |gSubView1|, |gSubView2| and 1.1311 + * |gSubView3|. If testing is failed, this function cancels all left tests. 1.1312 + * For checking the event is expected, the event firer must call 1.1313 + * |_saveScrollPositions|. 1.1314 + * 1.1315 + * @param gCurrentTest.expectedView 1.1316 + * The expected view which should be scrolled by the wheel event. 1.1317 + * This value can be null. It means any views should not be 1.1318 + * scrolled. 1.1319 + * @param gCurrentTest.isVertical 1.1320 + * The expected view should be scrolled vertical or horizontal. 1.1321 + * @param gCurrentTest.isForward 1.1322 + * The expected view should be scrolled to forward or backward. 1.1323 + * @param gCurrentTest.canFailRandomly 1.1324 + * If this is not undefined, this test can fail by unexpected view 1.1325 + * scrolling which is caused by unexpected timeout. If this is 1.1326 + * defined, |gCurrentTest.possibleView| must be set. If the view is 1.1327 + * same as the event target, the failure can be random. At this 1.1328 + * time, we should retry the current test list. 1.1329 + */ 1.1330 + 1.1331 + if (!(gLitesnEvents & kListenEvent_OnScroll)) 1.1332 + return; 1.1333 + 1.1334 + // Now testing a timeout, but a view is scrolled before timeout. 1.1335 + if (gCurrentTest.isTimeoutTesting && !gCurrentTest.wasTransactionTimeout) { 1.1336 + is(aEvent.target.id, "", 1.1337 + "The view scrolled before timeout (the expected view after timeout is " + 1.1338 + gCurrentTest.expectedView ? gCurrentTest.expectedView.id : "null" + 1.1339 + "): " + gCurrentTest.description); 1.1340 + runNextTestList(); 1.1341 + return; 1.1342 + } 1.1343 + 1.1344 + // Check whether the scrolled event should be fired or not. 1.1345 + if (!gCurrentTest.expectedView) { 1.1346 + is(aEvent.target.id, "", 1.1347 + "no views should be scrolled (" + 1.1348 + _getScrolledStateText(_getScrolledState(aEvent.target)) + "): " + 1.1349 + gCurrentTest.description); 1.1350 + runNextTestList(); 1.1351 + return; 1.1352 + } 1.1353 + 1.1354 + // Check whether the scrolled view is expected or not. 1.1355 + if (aEvent.target != gCurrentTest.expectedView) { 1.1356 + // If current test can fail randomly and the possible view is same as the 1.1357 + // event target, this failure may be caused by unexpected timeout. 1.1358 + // At this time, we should retry the current tests with slower settings. 1.1359 + if (gCurrentTest.canFailRandomly && 1.1360 + gCurrentTest.canFailRandomly.possibleView == aEvent.target && 1.1361 + gCurrentTestListStatus.retryWhenTransactionTimeout > 0) { 1.1362 + gCurrentTestListStatus.retryWhenTransactionTimeout--; 1.1363 + retryCurrentTestList(); 1.1364 + return; 1.1365 + } 1.1366 + is(aEvent.target.id, gCurrentTest.expectedView.id, 1.1367 + "wrong view was scrolled: " + gCurrentTest.description); 1.1368 + runNextTestList(); 1.1369 + return; 1.1370 + } 1.1371 + 1.1372 + // Check whether the scrolling direction is expected or not. 1.1373 + var expectedState = _getExpectedScrolledState(); 1.1374 + var currentState = _getScrolledState(aEvent.target); 1.1375 + if (expectedState != currentState) { 1.1376 + is(_getScrolledStateText(currentState), 1.1377 + _getScrolledStateText(expectedState), 1.1378 + "scrolled to wrong direction: " + gCurrentTest.description); 1.1379 + runNextTestList(); 1.1380 + return; 1.1381 + } 1.1382 + 1.1383 + ok(true, "passed: " + gCurrentTest.description); 1.1384 + continueTest(); 1.1385 +} 1.1386 + 1.1387 +function onMouseScrollFailed() 1.1388 +{ 1.1389 + /** 1.1390 + * Scroll failed event handler. If testing is failed, this function cancels 1.1391 + * all remains of current test-list, and go to next test-list. 1.1392 + * 1.1393 + * NOTE: This event is fired immediately after |_fireWheelScrollEvent|. 1.1394 + * 1.1395 + * @param gCurrentTest.expectedView 1.1396 + * The expected view which should be scrolled by the wheel event. 1.1397 + * This value can be null. It means any views should not be 1.1398 + * scrolled. When this is not null, this event means the test may 1.1399 + * be failed. 1.1400 + */ 1.1401 + 1.1402 + if (!(gLitesnEvents & kListenEvent_OnScrollFailed)) 1.1403 + return; 1.1404 + 1.1405 + ok(!gCurrentTest.expectedView, 1.1406 + "failed to scroll on current target: " + gCurrentTest.description); 1.1407 + if (gCurrentTest.expectedView) { 1.1408 + runNextTestList(); 1.1409 + return; 1.1410 + } 1.1411 + 1.1412 + continueTest(); 1.1413 +} 1.1414 + 1.1415 +function onTransactionTimeout() 1.1416 +{ 1.1417 + /** 1.1418 + * Scroll transaction timeout event handler. If the timeout is unexpected, 1.1419 + * i.e., |gCurrentTest.isTimeoutTesting| is not true, this function retry 1.1420 + * the current test-list. However, if the current test-list failed by timeout 1.1421 + * |gCurrentTestListStatus.retryWhenTransactionTimeout| times already, marking 1.1422 + * to failed the current test-list, and go to next test-list. 1.1423 + * 1.1424 + * @param gCurrentTest.expectedView 1.1425 + * The expected view which should be scrolled by the wheel event. 1.1426 + * This value can be null. It means any views should not be 1.1427 + * scrolled. When this is not null, this event means the testing may 1.1428 + * be failed. 1.1429 + * @param gCurrentTest.isTimeoutTesting 1.1430 + * If this value is true, the current testing have waited this 1.1431 + * event. Otherwise, the testing may be failed. 1.1432 + * @param gCurrentTestListStatus.retryWhenTransactionTimeout 1.1433 + * If |gCurrentTest.isTimeoutTesting| is not true but this event is 1.1434 + * fired, the failure may be randomly. Then, this event handler 1.1435 + * retry to test the current test-list until this cound will be zero. 1.1436 + */ 1.1437 + 1.1438 + if (!gCurrentTest.isTimeoutTesting && 1.1439 + gCurrentTestListStatus.retryWhenTransactionTimeout > 0) { 1.1440 + gCurrentTestListStatus.retryWhenTransactionTimeout--; 1.1441 + // retry current test list 1.1442 + retryCurrentTestList(); 1.1443 + return; 1.1444 + } 1.1445 + 1.1446 + gCurrentTest.wasTransactionTimeout = true; 1.1447 + 1.1448 + if (!(gLitesnEvents & kListenEvent_OnTransactionTimeout)) 1.1449 + return; 1.1450 + 1.1451 + ok(gCurrentTest.isTimeoutTesting, 1.1452 + "transaction timeout: " + gCurrentTest.description); 1.1453 + if (!gCurrentTest.isTimeoutTesting) { 1.1454 + runNextTestList(); 1.1455 + return; 1.1456 + } 1.1457 + 1.1458 + continueTest(); 1.1459 +} 1.1460 + 1.1461 +/****************************************************************************** 1.1462 + * Main function for this tests 1.1463 + ******************************************************************************/ 1.1464 + 1.1465 +function runNextTestStep() 1.1466 +{ 1.1467 + // When this is first time or the current test list is finised, load next 1.1468 + // test-list. 1.1469 + _clearTimer(); 1.1470 + if (!gCurrentTest) 1.1471 + runNextTestList(); 1.1472 + else 1.1473 + runTestStepAt(gCurrentTestListStatus.nextStepIndex); 1.1474 +} 1.1475 + 1.1476 +function runNextTestList() 1.1477 +{ 1.1478 + _clearTimer(); 1.1479 + 1.1480 + gLitesnEvents = kListenEvent_None; 1.1481 + _clearTransaction(); 1.1482 + resetTimeoutPrefs(); 1.1483 + if (gCurrentTestListStatus.nextListIndex >= gTestLists.length) { 1.1484 + finish(); 1.1485 + return; 1.1486 + } 1.1487 + 1.1488 + gCurrentTestListStatus.nextListIndex++; 1.1489 + gCurrentTestListStatus.retryWhenTransactionTimeout = 1.1490 + _getCurrentTestList().retryWhenTransactionTimeout; 1.1491 + runTestStepAt(0); 1.1492 +} 1.1493 + 1.1494 +function runTestStepAt(aStepIndex) 1.1495 +{ 1.1496 + _clearTimer(); 1.1497 + 1.1498 + disableNonTestMouseEvents(true); 1.1499 + 1.1500 + // load a step of testing. 1.1501 + gCurrentTestListStatus.nextStepIndex = aStepIndex; 1.1502 + gCurrentTest = 1.1503 + _getCurrentTestList().steps[gCurrentTestListStatus.nextStepIndex++]; 1.1504 + if (gCurrentTest) { 1.1505 + gCurrentTest.wasTransactionTimeout = false; 1.1506 + gTimer = setTimeout(gCurrentTest.func, gCurrentTest.delay); 1.1507 + } else { 1.1508 + // If current test-list doesn't have more testing, go to next test-list 1.1509 + // after cleaning up the current transaction. 1.1510 + _clearTransaction(); 1.1511 + runNextTestList(); 1.1512 + } 1.1513 +} 1.1514 + 1.1515 +function retryCurrentTestList() 1.1516 +{ 1.1517 + _clearTimer(); 1.1518 + 1.1519 + gLitesnEvents = kListenEvent_None; 1.1520 + _clearTransaction(); 1.1521 + ok(true, "WARNING: retry current test-list..."); 1.1522 + growUpTimeoutPrefs(); // retry the test with longer timeout settings. 1.1523 + runTestStepAt(0); 1.1524 +} 1.1525 + 1.1526 +function continueTest() 1.1527 +{ 1.1528 + /** 1.1529 + * This function is called from an event handler when a test succeeded. 1.1530 + * 1.1531 + * @param gCurrentTest.repeatTest 1.1532 + * When this is true, onScrollView calls |gCurrentTest.func|. So, 1.1533 + * same test can repeat. Otherwise, this calls |runNextTestStep|. 1.1534 + * @param gCurrentTest.autoRepeatDelay 1.1535 + * The delay value in milliseconds, this is used to call 1.1536 + * |gCurrentTest.func| via |setTimeout|. 1.1537 + */ 1.1538 + 1.1539 + _clearTimer(); 1.1540 + gLitesnEvents = kListenEvent_OnTransactionTimeout; 1.1541 + 1.1542 + // We should call each functions via setTimeout. Because sometimes this test 1.1543 + // is broken by stack overflow. 1.1544 + if (gCurrentTest.repeatTest) { 1.1545 + gTimer = setTimeout(gCurrentTest.func, gCurrentTest.autoRepeatDelay); 1.1546 + } else { 1.1547 + gTimer = setTimeout(runNextTestStep, 0); 1.1548 + } 1.1549 +} 1.1550 + 1.1551 +]]> 1.1552 +</script> 1.1553 + 1.1554 +</window>