Roll src/third_party/WebKit 3529d49:06e8485 (svn 202554:202555)
[chromium-blink-merge.git] / remoting / webapp / browser_test / scrollbar_browser_test.js
blob533e6691fac4b0d32a47d5a579ad9a9e82c48d0e
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 /**
6  * @suppress {checkTypes}
7  *
8  * @fileoverview
9  * Browser test for the scenario below:
10  * 1. Resize the client window to various sizes and verify the existence of
11  *    horizontal and/or vertical scroll-bars.
12  * 2. TODO(jamiewalch): Connect to a host and toggle various combinations of
13  *    scale and resize; repeat test 1.
14  * 3. TODO(jamiewalch): Disconnect; repeat test 1.
15  */
17 'use strict';
19 /** @constructor */
20 browserTest.Scrollbars = function() {
21   this.scroller_ = document.getElementById('scroller');
22   this.SCROLLBAR_WIDTH_ = 16;
23   this.BORDER_WIDTH_ = 1;
25   // The top border is already accounted for by getBoundingClientRect, but
26   // the bottom border is not.
27   var marker = document.getElementById('bottom-marker');
28   this.CONTENT_HEIGHT_ =
29       marker.getBoundingClientRect().top + this.BORDER_WIDTH_;
31   // The width of the content is computed from the width of a <section> (690px)
32   // plus the margin of the "inset" class (20px). There's no easy way to get
33   // that without hard-coding it. In fact, this is a bit simplistic because
34   // the horizontal space required by the header depends on the length of the
35   // product name.
36   this.CONTENT_WIDTH_ = 690 + 20 + 2 * this.BORDER_WIDTH_;
41 browserTest.Scrollbars.prototype.run = function(data) {
42   if (!base.isAppsV2()) {
43     browserTest.fail(
44         'Scroll-bar testing requires resizing the app window, which can ' +
45         'only be done programmatically in apps v2.');
46   }
48   // Verify that scrollbars are added/removed correctly on the home screen.
49   this.verifyHomeScreenScrollbars_()
50       .then(browserTest.pass, browserTest.fail);
54 /**
55  * Verify the test cases for the home-screen.
56  * @return {Promise}
57  */
58 browserTest.Scrollbars.prototype.verifyHomeScreenScrollbars_ = function() {
59   // Note that, due to crbug.com/240772, if the window already has
60   // scroll-bars, they will not be removed if the window size is
61   // increased by less than the scroll-bar width. We work around that
62   // when connected to a host because we know how big the content is
63   // (in fact, testing this work-around is the main motivation for
64   // writing this test), but it's not worth it for the home screen,
65   // so make the window large not to require scrollbars before each test.
66   var tooWide = this.CONTENT_WIDTH_ + 100;
67   var tooTall = this.CONTENT_HEIGHT_ + 100;
68   var removeScrollbars = this.resize_.bind(this, tooWide, tooTall);
70   // Verify there are no scroll-bars if the window is as big as it needs
71   // to be.
72   return removeScrollbars()
73   .then(this.resizeAndVerifyScroll_(
74         this.CONTENT_WIDTH_,
75         this.CONTENT_HEIGHT_,
76         false, false))
78   // Verify there is a vertical scroll-bar if the window is shorter than it
79   // needs to be.
80   .then(removeScrollbars)
81   .then(this.resizeAndVerifyScroll_.bind(
82         this,
83         this.CONTENT_WIDTH_ + this.SCROLLBAR_WIDTH_,
84         this.CONTENT_HEIGHT_ - 1,
85         false, true))
87   // Verify there is a horizontal scroll-bar if the window is narrow than it
88   // needs to be.
89   .then(removeScrollbars)
90   .then(this.resizeAndVerifyScroll_.bind(
91         this,
92         this.CONTENT_WIDTH_ - 1,
93         this.CONTENT_HEIGHT_ + this.SCROLLBAR_WIDTH_,
94         true, false))
96   // Verify there are both horizontal and vertical scroll-bars, even if one
97   // is only needed as a result of the space occupied by the other.
98   .then(removeScrollbars)
99   .then(this.resizeAndVerifyScroll_.bind(
100         this,
101         this.CONTENT_WIDTH_,
102         this.CONTENT_HEIGHT_ - 1,
103         true, true))
104   .then(removeScrollbars)
105   .then(this.resizeAndVerifyScroll_.bind(
106         this,
107         this.CONTENT_WIDTH_ - 1,
108         this.CONTENT_HEIGHT_,
109         true, true))
111   // Verify there are both horizontal and vertical scroll-bars, if both are
112   // required independently.
113   .then(removeScrollbars)
114   .then(this.resizeAndVerifyScroll_.bind(
115         this,
116         this.CONTENT_WIDTH_ - 1,
117         this.CONTENT_HEIGHT_ - 1,
118         true, true));
123  * Returns whether or not horizontal and vertical scroll-bars are expected
124  * and visible. To do this, it performs a hit-test close to the right and
125  * bottom edges of the scroller <div>; since the content of that <div> fills
126  * it completely, the hit-test will return the content unless there is a
127  * scroll-bar visible on the corresponding edge, in which case it will return
128  * the scroller <div> itself.
130  * @return {{horizontal: boolean, vertical:boolean}}
131  * @private
132  */
133 browserTest.Scrollbars.prototype.getScrollbarState_ = function() {
134   var rect = this.scroller_.getBoundingClientRect();
135   var rightElement = document.elementFromPoint(
136       rect.right - 1, (rect.top + rect.bottom) / 2);
137   var bottomElement = document.elementFromPoint(
138       (rect.left + rect.right) / 2, rect.bottom - 1);
139   return {
140     horizontal: bottomElement === this.scroller_,
141     vertical: rightElement === this.scroller_
142   };
147  * Returns a promise that resolves if the scroll-bar state is as expected, or
148  * rejects otherwise.
150  * @param {boolean} horizontalExpected
151  * @param {boolean} verticalExpected
152  * @return {Promise}
153  * @private
154  */
155 browserTest.Scrollbars.prototype.verifyScrollbarState_ =
156     function(horizontalExpected, verticalExpected) {
157   var scrollbarState = this.getScrollbarState_();
158   if (scrollbarState.horizontal && !horizontalExpected) {
159     return Promise.reject(new Error(
160         'Horizontal scrollbar present but not expected.'));
161   } else if (!scrollbarState.horizontal && horizontalExpected) {
162     return Promise.reject(new Error(
163         'Horizontal scrollbar expected but not present.'));
164   } else if (scrollbarState.vertical && !verticalExpected) {
165     return Promise.reject(new Error(
166         'Vertical scrollbar present but not expected.'));
167   } else if (!scrollbarState.vertical && verticalExpected) {
168     return Promise.reject(new Error(
169         'Vertical scrollbar expected but not present.'));
170   }
171   return Promise.resolve();
176  * @param {number} width
177  * @param {number} height
178  * @return {Promise} A promise that will be fulfilled when the window has
179  *     been resized and it's safe to test scroll-bar visibility.
180  * @private
181  */
182 browserTest.Scrollbars.prototype.resize_ = function(width, height) {
183   var win = chrome.app.window.current();
184   win.outerBounds.width = width;
185   win.outerBounds.height = height;
186   // Chrome takes a while to update the scroll-bars, so don't resolve
187   // immediately. Waiting for the onBoundsChanged event would be cleaner,
188   // but isn't reliable.
189   return base.Promise.sleep(500);
194  * @param {number} width
195  * @param {number} height
196  * @param {boolean} horizontalExpected
197  * @param {boolean} verticalExpected
198  * @return {Promise} A promise that will be fulfilled when the window has
199  *     been resized and it's safe to test scroll-bar visibility.
200  * @private
201  */
202 browserTest.Scrollbars.prototype.resizeAndVerifyScroll_ =
203     function(width, height, horizontalExpected, verticalExpected) {
204   return this.resize_(width, height).then(
205       this.verifyScrollbarState_.bind(
206           this, horizontalExpected, verticalExpected));