Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / LayoutTests / fast / scroll-behavior / resources / scroll-behavior-test.js
blob6242af2ea4309f69e568369eb8f61cd20972e502
1 // A ScrollBehaviorTest runs a set of ScrollBehaviorTestCases. The only
2 // ScrollBehaviorTest method that should be called by external code is run().
4 // Creates a ScrollBehaviorTest with arguments:
5 // scrollElement - Element being scrolled.
6 // scrollEventTarget - Target for scroll events for |scrollElement|.
7 // testsCases - Array of ScrollBehaviorTestCases.
8 // getEndPosition - Callback that takes a test case and start position, and
9 // returns the corresponding end position (where positions
10 // are dictionaries with x and y fields).
11 // jsScroll - Callback that takes a test case and executes the corresponding
12 // js-driven scroll (e.g. by setting scrollLeft/scrollTop or by
13 // calling scroll, scrollTo, or scrollBy). This should assume that
14 // scrollElement's scroll-behavior CSS property has already been
15 // set appropriately.
16 function ScrollBehaviorTest(scrollElement,
17 scrollEventTarget,
18 testCases,
19 getEndPosition,
20 jsScroll) {
21 this.scrollElement = scrollElement;
22 this.scrollEventTarget = scrollEventTarget;
23 this.testCases = testCases;
24 this.currentTestCase = 0;
25 this.getEndPosition = getEndPosition;
26 this.jsScroll = jsScroll;
29 ScrollBehaviorTest.prototype.scrollListener = function(testCase) {
30 var endReached = (this.scrollElement.scrollLeft == testCase.endX && this.scrollElement.scrollTop == testCase.endY);
31 if (endReached) {
32 this.testCaseComplete();
33 return;
36 if (testCase.waitForEnd)
37 return;
39 // Wait for the animation to start, then instant-scroll to the end state.
40 if (this.scrollElement.scrollLeft != testCase.startX || this.scrollElement.scrollTop != testCase.startY) {
41 // Instant scroll, and then wait for the next scroll event. This allows
42 // the instant scroll to propagate to the compositor (when using
43 // composited scrolling) so that the next smooth scroll starts at this
44 // position (the compositor always starts smooth scrolls at the current
45 // scroll position on the compositor thread).
46 this.scrollElement.scrollTo({left: testCase.endX, top: testCase.endY, behavior: "instant"});
47 testCase.waitForEnd = true;
51 ScrollBehaviorTest.prototype.startNextTestCase = function() {
52 if (this.currentTestCase >= this.testCases.length) {
53 this.allTestCasesComplete();
54 return;
56 var testCase = this.testCases[this.currentTestCase];
57 if (testCase.pageScaleFactor && window.internals) {
58 internals.setPageScaleFactor(testCase.pageScaleFactor);
61 var isSmoothTest = (testCase.js == "smooth" || (testCase.css == "smooth" && testCase.js != "instant"));
63 this.asyncTest = async_test("Scroll x:" + testCase.x + ", y:" + testCase.y + ", smooth:" + isSmoothTest);
65 var currentPosition = {};
66 currentPosition.x = this.scrollElement.scrollLeft;
67 currentPosition.y = this.scrollElement.scrollTop;
68 var endPosition = this.getEndPosition(testCase, currentPosition);
69 testCase.setStartPosition(currentPosition);
70 testCase.setEndPosition(endPosition);
72 this.scrollElement.style.scrollBehavior = testCase.css;
73 this.jsScroll(testCase);
75 var scrollElement = this.scrollElement;
76 if (isSmoothTest) {
77 this.asyncTest.step(function() {
78 assert_equals(scrollElement.scrollLeft + ", " + scrollElement.scrollTop, testCase.startX + ", " + testCase.startY);
79 });
80 if (scrollElement.scrollLeft == testCase.endX && scrollElement.scrollTop == testCase.endY) {
81 // We've instant-scrolled. This means we've already failed the assert above, and will never
82 // reach an intermediate frame. End the test case now to avoid hanging while waiting for an
83 // intermediate frame.
84 this.testCaseComplete();
85 } else {
86 testCase.scrollListener = this.scrollListener.bind(this, testCase);
87 this.scrollEventTarget.addEventListener("scroll", testCase.scrollListener);
89 } else {
90 this.asyncTest.step(function() {
91 assert_equals(scrollElement.scrollLeft + ", " + scrollElement.scrollTop, testCase.endX + ", " + testCase.endY);
92 });
93 this.testCaseComplete();
97 ScrollBehaviorTest.prototype.testCaseComplete = function() {
98 var currentScrollListener = this.testCases[this.currentTestCase].scrollListener;
99 if (currentScrollListener) {
100 this.scrollEventTarget.removeEventListener("scroll", currentScrollListener);
102 this.asyncTest.done();
104 this.currentTestCase++;
105 this.startNextTestCase();
108 ScrollBehaviorTest.prototype.run = function() {
109 setup({explicit_done: true, explicit_timeout: true});
110 this.startNextTestCase();
113 ScrollBehaviorTest.prototype.allTestCasesComplete = function() {
114 done();
118 // A ScrollBehaviorTestCase represents a single scroll.
120 // Creates a ScrollBehaviorTestCase. |testData| is a dictionary with fields:
121 // css - Value of scroll-behavior CSS property.
122 // js - (optional) Value of scroll behavior used in javascript.
123 // x, y - Coordinates to be used when carrying out the scroll.
124 // waitForEnd - (must be provided for smooth scrolls) Whether the test runner should
125 // wait until the scroll is complete, rather than only waiting until
126 // the scroll is underway.
127 // pageScaleFactor - (optional) if set, applies pinch-zoom by the given factor.
128 function ScrollBehaviorTestCase(testData) {
129 this.js = testData.js;
130 this.css = testData.css;
131 this.waitForEnd = testData.waitForEnd;
132 this.x = testData.x;
133 this.y = testData.y;
134 this.pageScaleFactor = testData.pageScaleFactor;
137 ScrollBehaviorTestCase.prototype.setStartPosition = function(startPosition) {
138 this.startX = startPosition.x;
139 this.startY = startPosition.y;
142 ScrollBehaviorTestCase.prototype.setEndPosition = function(endPosition) {
143 this.endX = endPosition.x;
144 this.endY = endPosition.y;