Index: remoting/webapp/browser_test/scrollbar_browser_test.js |
diff --git a/remoting/webapp/browser_test/scrollbar_browser_test.js b/remoting/webapp/browser_test/scrollbar_browser_test.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2424c8ce5764ae2cc648213cc2e1ccd212fe290f |
--- /dev/null |
+++ b/remoting/webapp/browser_test/scrollbar_browser_test.js |
@@ -0,0 +1,195 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+/** |
+ * @suppress {checkTypes} |
+ * |
+ * @fileoverview |
+ * Browser test for the scenario below: |
+ * 1. Resize the client window to various sizes and verify the existence of |
+ * horizontal and/or vertical scroll-bars. |
+ * 2. TODO(jamiewalch): Connect to a host and toggle various combinations of |
+ * scale and resize; repeat test 1. |
+ * 3. TODO(jamiewalch): Disconnect; repeat test 1. |
+ */ |
+ |
+'use strict'; |
+ |
+/** @constructor */ |
+browserTest.Scrollbars = function() { |
+ this.scroller_ = document.getElementById('scroller'); |
+ this.SCROLLBAR_WIDTH_ = 16; |
+ this.BORDER_WIDTH_ = 1; |
+ |
+ // The top border is already accounted for by getBoundingClientRect, but |
+ // the bottom border is not. |
+ var marker = document.getElementById('bottom-marker'); |
+ this.CONTENT_HEIGHT_ = |
+ marker.getBoundingClientRect().top + this.BORDER_WIDTH_; |
+ |
+ // The width of the content is computed from the width of a <section> (690px) |
+ // plus the margin of the "inset" class (20px). There's no easy way to get |
+ // that without hard-coding it. In fact, this is a bit simplistic because |
+ // the horizontal space required by the header depends on the length of the |
+ // product name. |
+ this.CONTENT_WIDTH_ = 690 + 20 + 2 * this.BORDER_WIDTH_; |
+ |
+}; |
+ |
+ |
+browserTest.Scrollbars.prototype.run = function(data) { |
+ if (!base.isAppsV2()) { |
+ browserTest.fail( |
+ 'Scroll-bar testing requires resizing the app window, which can ' + |
+ 'only be done programmatically in apps v2.'); |
+ } |
+ |
+ // Verify that scrollbars are added/removed correctly on the home screen. |
+ this.verifyHomeScreenScrollbars_() |
+ .then(browserTest.pass, browserTest.fail); |
+}; |
+ |
+ |
+/** |
+ * Verify the test cases for the home-screen. |
+ */ |
+browserTest.Scrollbars.prototype.verifyHomeScreenScrollbars_ = function() { |
+ // Note that, due to crbug.com/240772, if the window already has |
+ // scroll-bars, they will not be removed if the window size is |
+ // increased by less than the scroll-bar width. We work around that |
+ // when connected to a host because we know how big the content is |
+ // (in fact, testing this work-around is the main motivation for |
+ // writing this test), but it's not worth it for the home screen, |
+ // so make the window large not to require scrollbars before each test. |
+ var tooWide = this.CONTENT_WIDTH_ + 100; |
+ var tooTall = this.CONTENT_HEIGHT_ + 100; |
+ var removeScrollbars = this.resize_.bind(this, tooWide, tooTall); |
+ |
+ // Verify there are no scroll-bars if the window is as big as it needs |
+ // to be. |
+ return removeScrollbars() |
+ .then(this.resizeAndVerifyScroll_( |
+ this.CONTENT_WIDTH_, |
+ this.CONTENT_HEIGHT_, |
+ false, false)) |
+ |
+ // Verify there is a vertical scroll-bar if the window is shorter than it |
+ // needs to be. |
+ .then(removeScrollbars) |
+ .then(this.resizeAndVerifyScroll_.bind( |
+ this, |
+ this.CONTENT_WIDTH_ + this.SCROLLBAR_WIDTH_, |
+ this.CONTENT_HEIGHT_ - 1, |
+ false, true)) |
+ |
+ // Verify there is a horizontal scroll-bar if the window is narrow than it |
+ // needs to be. |
+ .then(removeScrollbars) |
+ .then(this.resizeAndVerifyScroll_.bind( |
+ this, |
+ this.CONTENT_WIDTH_ - 1, |
+ this.CONTENT_HEIGHT_ + this.SCROLLBAR_WIDTH_, |
+ true, false)) |
+ |
+ // Verify there are both horizontal and vertical scroll-bars, even if one |
+ // is only needed as a result of the space occupied by the other. |
+ .then(removeScrollbars) |
+ .then(this.resizeAndVerifyScroll_.bind( |
+ this, |
+ this.CONTENT_WIDTH_, |
+ this.CONTENT_HEIGHT_ - 1, |
+ true, true)) |
+ .then(removeScrollbars) |
+ .then(this.resizeAndVerifyScroll_.bind( |
+ this, |
+ this.CONTENT_WIDTH_ - 1, |
+ this.CONTENT_HEIGHT_, |
+ true, true)) |
+ |
+ // Verify there are both horizontal and vertical scroll-bars, if both are |
+ // required independently. |
+ .then(removeScrollbars) |
+ .then(this.resizeAndVerifyScroll_.bind( |
+ this, |
+ this.CONTENT_WIDTH_ - 1, |
+ this.CONTENT_HEIGHT_ - 1, |
+ true, true)); |
+}; |
+ |
+ |
+/** |
+ * Returns whether or not horizontal and vertical scroll-bars are expected |
+ * and visible. To do this, it performs a hit-test close to the right and |
+ * bottom edges of the scroller <div>; since the content of that <div> fills |
+ * it completely, the hit-test will return the content unless there is a |
+ * scroll-bar visible on the corresponding edge, in which case it will return |
+ * the scroller <div> itself. |
+ * |
+ * @private |
+ */ |
+browserTest.Scrollbars.prototype.getScrollbarState_ = function() { |
+ var rect = this.scroller_.getBoundingClientRect(); |
+ var rightElement = document.elementFromPoint( |
+ rect.right - 1, (rect.top + rect.bottom) / 2); |
+ var bottomElement = document.elementFromPoint( |
+ (rect.left + rect.right) / 2, rect.bottom - 1); |
+ return { |
+ horizontal: bottomElement === this.scroller_, |
+ vertical: rightElement === this.scroller_ |
+ }; |
+}; |
+ |
+ |
+/** |
+ * Returns a promise that resolves if the scroll-bar state is as expected, or |
+ * rejects otherwise. |
+ * |
+ * @private |
+ */ |
+browserTest.Scrollbars.prototype.verifyScrollbarState_ = |
+ function(horizontalExpected, verticalExpected) { |
+ var scrollbarState = this.getScrollbarState_(); |
+ if (scrollbarState.horizontal && !horizontalExpected) { |
+ return Promise.reject(new Error( |
+ 'Horizontal scrollbar present but not expected.')); |
+ } else if (!scrollbarState.horizontal && horizontalExpected) { |
+ return Promise.reject(new Error( |
+ 'Horizontal scrollbar expected but not present.')); |
+ } else if (scrollbarState.vertical && !verticalExpected) { |
+ return Promise.reject(new Error( |
+ 'Vertical scrollbar present but not expected.')); |
+ } else if (!scrollbarState.vertical && verticalExpected) { |
+ return Promise.reject(new Error( |
+ 'Vertical scrollbar expected but not present.')); |
+ } |
+ return Promise.resolve(); |
+}; |
+ |
+ |
+/** |
+ * @private |
+ * @return {Promise} A promise that will be fulfilled when the window has |
+ * been resized and it's safe to test scroll-bar visibility. |
+ */ |
+browserTest.Scrollbars.prototype.resize_ = function(width, height) { |
+ var win = chrome.app.window.current(); |
+ win.resizeTo(width, height); |
+ // Chrome takes a while to update the scroll-bars, so don't resolve |
+ // immediately. Waiting for the onBoundsChanged event would be cleaner, |
+ // but isn't reliable. |
+ return base.Promise.sleep(500); |
+}; |
+ |
+ |
+/** |
+ * @private |
+ * @return {Promise} A promise that will be fulfilled when the window has |
+ * been resized and it's safe to test scroll-bar visibility. |
+ */ |
+browserTest.Scrollbars.prototype.resizeAndVerifyScroll_ = |
+ function(width, height, horizontalExpected, verticalExpected) { |
+ return this.resize_(width, height).then( |
+ this.verifyScrollbarState_.bind( |
+ this, horizontalExpected, verticalExpected)); |
+}; |