OLD | NEW |
(Empty) | |
| 1 // A SmoothScrollInterruptionTest verifies that in-progress smooth scrolls |
| 2 // stop when interrupted by an instant scroll, another smooth scroll, a |
| 3 // touch scroll, or a mouse wheel scroll. |
| 4 // |
| 5 // The only SmoothScrollInerruptionTest method that should be called by |
| 6 // outside code is run(). |
| 7 // |
| 8 // Creates a SmoothScrollInterruptionTest with arguments: |
| 9 // scrollElement - Element being scrolled. |
| 10 // innerPoint - Absolute position (expressed as a dictionary with x and y fields
) |
| 11 // of a point inside |scrollElement|, that can be used as the locat
ion |
| 12 // of input events that trigger scrolls on |scrollElement|. |
| 13 // targets - A dictionary whose members y_min, y_mid, and y_max should be |
| 14 // y co-ordinates that are far enough apart from each other that a |
| 15 // smooth scroll between any pair of them will be non-trivial (that |
| 16 // is, take multiple frames to finish), and should be such that |
| 17 // y_min < y_mid < y_max. |
| 18 // jsScroll - Callback that takes a y co-ordinate and executes a js-driven |
| 19 // smooth scroll to that y co-ordinate. |
| 20 function SmoothScrollInterruptionTest(scrollElement, innerPoint, targets, jsScro
ll) { |
| 21 this.scrollElement = scrollElement; |
| 22 this.innerPoint = innerPoint; |
| 23 this.scrollStartPoint = targets.y_mid; |
| 24 this.scrollEndPoint = targets.y_max; |
| 25 this.scrollNewEndpoint = targets.y_min; |
| 26 this.jsScroll = jsScroll; |
| 27 |
| 28 this.testCases = []; |
| 29 this.testCases.push(new SmoothScrollInterruptionTestCase(interruptWithInstan
tScroll, verifyScrollInterruptedByInstantScroll, "instant scroll")); |
| 30 this.testCases.push(new SmoothScrollInterruptionTestCase(interruptWithSmooth
Scroll, verifyScrollInterruptedBySmoothScroll, "smooth scroll")); |
| 31 this.testCases.push(new SmoothScrollInterruptionTestCase(interruptWithTouchS
croll, verifyScrollInterruptedByInputDrivenScroll, "touch scroll")); |
| 32 this.testCases.push(new SmoothScrollInterruptionTestCase(interruptWithWheelS
croll, verifyScrollInterruptedByInputDrivenScroll, "wheel scroll")); |
| 33 |
| 34 this.currentTestCase = 0; |
| 35 } |
| 36 |
| 37 SmoothScrollInterruptionTest.prototype.startNextTestCase = function() { |
| 38 if (this.currentTestCase >= this.testCases.length) { |
| 39 this.allTestCasesComplete(); |
| 40 return; |
| 41 } |
| 42 |
| 43 var testCase = this.testCases[this.currentTestCase]; |
| 44 this.asyncTest = async_test(testCase.description); |
| 45 |
| 46 var scrollElement = this.scrollElement; |
| 47 var scrollStartPoint = this.scrollStartPoint; |
| 48 |
| 49 scrollElement.scrollTop = scrollStartPoint; |
| 50 this.jsScroll(this.scrollEndPoint); |
| 51 this.asyncTest.step(function() { |
| 52 assert_equals(scrollElement.scrollTop, scrollStartPoint); |
| 53 }); |
| 54 |
| 55 if (scrollElement.scrollTop == this.scrollEndPoint) { |
| 56 // We've instant-scrolled, and failed the assert above. |
| 57 this.testCaseComplete(); |
| 58 return; |
| 59 } |
| 60 |
| 61 window.requestAnimationFrame(this.waitForSmoothScrollStart.bind(this)); |
| 62 } |
| 63 |
| 64 SmoothScrollInterruptionTest.prototype.waitForSmoothScrollStart = function() { |
| 65 if (this.scrollElement.scrollTop == this.scrollStartPoint) { |
| 66 window.requestAnimationFrame(this.waitForSmoothScrollStart.bind(this)); |
| 67 return; |
| 68 } |
| 69 |
| 70 var scrollElement = this.scrollElement; |
| 71 var scrollEndPoint = this.scrollEndPoint; |
| 72 this.asyncTest.step(function() { |
| 73 assert_not_equals(scrollElement.scrollTop, scrollEndPoint); |
| 74 }); |
| 75 |
| 76 var testCase = this.testCases[this.currentTestCase]; |
| 77 testCase.interruptSmoothScroll(this); |
| 78 window.requestAnimationFrame(testCase.verifyScrollInterrupted.bind(testCase,
this, this.testCaseComplete.bind(this))); |
| 79 } |
| 80 |
| 81 SmoothScrollInterruptionTest.prototype.testCaseComplete = function() { |
| 82 this.asyncTest.done(); |
| 83 |
| 84 this.currentTestCase++; |
| 85 this.startNextTestCase(); |
| 86 } |
| 87 |
| 88 SmoothScrollInterruptionTest.prototype.run = function() { |
| 89 setup({explicit_done: true}); |
| 90 this.startNextTestCase(); |
| 91 } |
| 92 |
| 93 SmoothScrollInterruptionTest.prototype.allTestCasesComplete = function() { |
| 94 done(); |
| 95 } |
| 96 |
| 97 // A SmoothScrollInterruptionTestCase represents a single way of interrupting |
| 98 // a smooth scroll and verifying that the smooth scroll gets canceled. |
| 99 // |
| 100 // Creates a SmoothScrollInterruptionTestCase with arguments: |
| 101 // interruptSmoothScoll - Callback that takes a SmoothScrollInterruptionTest, |
| 102 // and interrupts the on-going smooth scroll. |
| 103 // verifyScrollInterrupted - Callback that takes a SmoothScrollInterruptionTest, |
| 104 // a |verificationComplete| callback, and a timestamp, |
| 105 // verifies (possibly asynchronously) that the smooth |
| 106 // scroll has been superseded by the interruption, and |
| 107 // then calls |verificationComplete|. |
| 108 // description - String describing this test case. |
| 109 function SmoothScrollInterruptionTestCase(interruptSmoothScroll, verifyScrollInt
errupted, description) { |
| 110 this.interruptSmoothScroll = interruptSmoothScroll; |
| 111 this.verifyScrollInterrupted = verifyScrollInterrupted; |
| 112 this.description = description; |
| 113 } |
| 114 |
| 115 |
| 116 function interruptWithInstantScroll(smoothScrollTest) { |
| 117 smoothScrollTest.scrollElement.scrollTop = smoothScrollTest.scrollNewEndpoin
t; |
| 118 smoothScrollTest.asyncTest.step(function() { |
| 119 assert_equals(smoothScrollTest.scrollElement.scrollTop, smoothScrollTest
.scrollNewEndpoint); |
| 120 }); |
| 121 } |
| 122 |
| 123 function verifyScrollInterruptedByInstantScroll(smoothScrollTest, verificationCo
mplete) { |
| 124 smoothScrollTest.asyncTest.step(function() { |
| 125 assert_equals(smoothScrollTest.scrollElement.scrollTop, smoothScrollTest
.scrollNewEndpoint); |
| 126 }); |
| 127 verificationComplete(); |
| 128 } |
| 129 |
| 130 function interruptWithSmoothScroll(smoothScrollTest) { |
| 131 smoothScrollTest.jsScroll(smoothScrollTest.scrollNewEndpoint); |
| 132 smoothScrollTest.asyncTest.step(function() { |
| 133 assert_not_equals(smoothScrollTest.scrollElement.scrollTop, smoothScroll
Test.scrollNewEndpoint); |
| 134 }); |
| 135 |
| 136 this.scrollInterruptionPoint = smoothScrollTest.scrollElement.scrollTop; |
| 137 } |
| 138 |
| 139 function verifyScrollInterruptedBySmoothScroll(smoothScrollTest, verificationCom
plete) { |
| 140 var currentPosition = smoothScrollTest.scrollElement.scrollTop; |
| 141 |
| 142 if (currentPosition < this.scrollInterruptionPoint && currentPosition > smoo
thScrollTest.scrollNewEndpoint) { |
| 143 verificationComplete(); |
| 144 } else { |
| 145 window.requestAnimationFrame(this.verifyScrollInterrupted.bind(this, smo
othScrollTest, verificationComplete)); |
| 146 } |
| 147 } |
| 148 |
| 149 function interruptWithTouchScroll(smoothScrollTest) { |
| 150 if (window.eventSender) { |
| 151 window.eventSender.gestureScrollBegin(smoothScrollTest.innerPoint.x, smo
othScrollTest.innerPoint.y); |
| 152 window.eventSender.gestureScrollUpdate(0, -10); |
| 153 window.eventSender.gestureScrollEnd(0, 0); |
| 154 } else { |
| 155 document.write("This test does not work in manual mode."); |
| 156 } |
| 157 } |
| 158 |
| 159 function verifyScrollInterruptedByInputDrivenScroll(smoothScrollTest, verificati
onComplete, timestamp) { |
| 160 var currentPosition = smoothScrollTest.scrollElement.scrollTop; |
| 161 |
| 162 if (this.previousPosition && this.previousPosition == currentPosition) { |
| 163 // Ensure that the animation has really stopped, not that we just have |
| 164 // two frames that are so close together that the animation only seems t
o |
| 165 // have stopped. |
| 166 if (timestamp - this.previousTimestamp > 16) { |
| 167 verificationComplete(); |
| 168 } else { |
| 169 window.requestAnimationFrame(this.verifyScrollInterrupted.bind(this,
smoothScrollTest, verificationComplete)); |
| 170 } |
| 171 |
| 172 return; |
| 173 } |
| 174 |
| 175 this.previousPosition = currentPosition; |
| 176 this.previousTimestamp = timestamp; |
| 177 smoothScrollTest.asyncTest.step(function() { |
| 178 assert_not_equals(currentPosition, smoothScrollTest.scrollEndPoint); |
| 179 }); |
| 180 window.requestAnimationFrame(this.verifyScrollInterrupted.bind(this, smoothS
crollTest, verificationComplete)); |
| 181 } |
| 182 |
| 183 function interruptWithWheelScroll(smoothScrollTest) { |
| 184 if (window.eventSender) { |
| 185 window.eventSender.mouseMoveTo(smoothScrollTest.innerPoint.x, smoothScro
llTest.innerPoint.y); |
| 186 window.eventSender.mouseScrollBy(0, -10); |
| 187 } else { |
| 188 document.write("This test does not work in manual mode."); |
| 189 } |
| 190 } |
OLD | NEW |