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.
6 * @suppress {checkTypes}
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.
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
36 this.CONTENT_WIDTH_
= 690 + 20 + 2 * this.BORDER_WIDTH_
;
41 browserTest
.Scrollbars
.prototype.run = function(data
) {
42 if (!base
.isAppsV2()) {
44 'Scroll-bar testing requires resizing the app window, which can ' +
45 'only be done programmatically in apps v2.');
48 // Verify that scrollbars are added/removed correctly on the home screen.
49 this.verifyHomeScreenScrollbars_()
50 .then(browserTest
.pass
, browserTest
.fail
);
55 * Verify the test cases for the home-screen.
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
72 return removeScrollbars()
73 .then(this.resizeAndVerifyScroll_(
78 // Verify there is a vertical scroll-bar if the window is shorter than it
80 .then(removeScrollbars
)
81 .then(this.resizeAndVerifyScroll_
.bind(
83 this.CONTENT_WIDTH_
+ this.SCROLLBAR_WIDTH_
,
84 this.CONTENT_HEIGHT_
- 1,
87 // Verify there is a horizontal scroll-bar if the window is narrow than it
89 .then(removeScrollbars
)
90 .then(this.resizeAndVerifyScroll_
.bind(
92 this.CONTENT_WIDTH_
- 1,
93 this.CONTENT_HEIGHT_
+ this.SCROLLBAR_WIDTH_
,
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(
102 this.CONTENT_HEIGHT_
- 1,
104 .then(removeScrollbars
)
105 .then(this.resizeAndVerifyScroll_
.bind(
107 this.CONTENT_WIDTH_
- 1,
108 this.CONTENT_HEIGHT_
,
111 // Verify there are both horizontal and vertical scroll-bars, if both are
112 // required independently.
113 .then(removeScrollbars
)
114 .then(this.resizeAndVerifyScroll_
.bind(
116 this.CONTENT_WIDTH_
- 1,
117 this.CONTENT_HEIGHT_
- 1,
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}}
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);
140 horizontal
: bottomElement
=== this.scroller_
,
141 vertical
: rightElement
=== this.scroller_
147 * Returns a promise that resolves if the scroll-bar state is as expected, or
150 * @param {boolean} horizontalExpected
151 * @param {boolean} verticalExpected
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.'));
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.
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.
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
));