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 |