Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / LayoutTests / fast / scroll-behavior / resources / scroll-behavior-test.js
1 // A ScrollBehaviorTest runs a set of ScrollBehaviorTestCases. The only
2 // ScrollBehaviorTest method that should be called by external code is run().
3
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;
27 }
28
29 ScrollBehaviorTest.prototype.scrollListener = function(testCase) {
30     if (testCase.waitForEnd) {
31         if (this.scrollElement.scrollLeft == testCase.endX && this.scrollElement.scrollTop == testCase.endY)
32             this.testCaseComplete();
33         return;
34     }
35
36     // Wait for an intermediate frame, then instant-scroll to the end state.
37     if ((this.scrollElement.scrollLeft != testCase.startX || this.scrollElement.scrollTop != testCase.startY) &&
38         (this.scrollElement.scrollLeft != testCase.endX || this.scrollElement.scrollTop != testCase.endY)) {
39         this.scrollElement.scrollLeft = {x: testCase.endX, behavior: "instant"};
40         this.scrollElement.scrollTop = {y: testCase.endY, behavior: "instant"};
41         this.testCaseComplete();
42     }
43 };
44
45 ScrollBehaviorTest.prototype.startNextTestCase = function() {
46     if (this.currentTestCase >= this.testCases.length) {
47         this.allTestCasesComplete();
48         return;
49     }
50     var testCase = this.testCases[this.currentTestCase];
51     var isSmoothTest = (testCase.js == "smooth" || (testCase.css == "smooth" && testCase.js != "instant"));
52
53     this.asyncTest = async_test("Scroll x:" + testCase.x + ", y:" + testCase.y + ", smooth:" + isSmoothTest);
54
55     var currentPosition = {};
56     currentPosition.x = this.scrollElement.scrollLeft;
57     currentPosition.y = this.scrollElement.scrollTop;
58     var endPosition = this.getEndPosition(testCase, currentPosition);
59     testCase.setStartPosition(currentPosition);
60     testCase.setEndPosition(endPosition);
61
62     this.scrollElement.style.scrollBehavior = testCase.css;
63     this.jsScroll(testCase);
64
65     var scrollElement = this.scrollElement;
66     if (isSmoothTest) {
67         this.asyncTest.step(function() {
68             assert_equals(scrollElement.scrollLeft + ", " + scrollElement.scrollTop, testCase.startX + ", " + testCase.startY);
69         });
70         if (scrollElement.scrollLeft == testCase.endX && scrollElement.scrollTop == testCase.endY) {
71             // We've instant-scrolled. This means we've already failed the assert above, and will never
72             // reach an intermediate frame. End the test case now to avoid hanging while waiting for an
73             // intermediate frame.
74             this.testCaseComplete();
75         } else {
76             testCase.scrollListener = this.scrollListener.bind(this, testCase);
77             this.scrollEventTarget.addEventListener("scroll", testCase.scrollListener);
78         }
79     } else {
80         this.asyncTest.step(function() {
81             assert_equals(scrollElement.scrollLeft + ", " + scrollElement.scrollTop, testCase.endX + ", " + testCase.endY);
82         });
83         this.testCaseComplete();
84     }
85 }
86
87 ScrollBehaviorTest.prototype.testCaseComplete = function() {
88     var currentScrollListener = this.testCases[this.currentTestCase].scrollListener;
89     if (currentScrollListener) {
90         this.scrollEventTarget.removeEventListener("scroll", currentScrollListener);
91     }
92     this.asyncTest.done();
93
94     this.currentTestCase++;
95     this.startNextTestCase();
96 }
97
98 ScrollBehaviorTest.prototype.run = function() {
99     setup({explicit_done: true});
100     this.startNextTestCase();
101 }
102
103 ScrollBehaviorTest.prototype.allTestCasesComplete = function() {
104     done();
105 }
106
107
108 // A ScrollBehaviorTestCase represents a single scroll.
109 //
110 // Creates a ScrollBehaviorTestCase. |testData| is a dictionary with fields:
111 // css - Value of scroll-behavior CSS property.
112 // js - (optional) Value of scroll behavior used in javascript.
113 // x, y - Coordinates to be used when carrying out the scroll.
114 // waitForEnd - (must be provided for smooth scrolls) Whether the test runner should
115 //              wait until the scroll is complete, rather than only waiting until
116 //              the scroll is underway.
117 function ScrollBehaviorTestCase(testData) {
118     this.js = testData.js;
119     this.css = testData.css;
120     this.waitForEnd = testData.waitForEnd;
121     this.x = testData.x;
122     this.y = testData.y;
123 }
124
125 ScrollBehaviorTestCase.prototype.setStartPosition = function(startPosition) {
126     this.startX = startPosition.x;
127     this.startY = startPosition.y;
128 }
129
130 ScrollBehaviorTestCase.prototype.setEndPosition = function(endPosition) {
131     this.endX = endPosition.x;
132     this.endY = endPosition.y;
133 }