Home | History | Annotate | Download | only in browser_test
      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.
      4 
      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  */
     16 
     17 'use strict';
     18 
     19 /** @constructor */
     20 browserTest.Scrollbars = function() {
     21   this.scroller_ = document.getElementById('scroller');
     22   this.SCROLLBAR_WIDTH_ = 16;
     23   this.BORDER_WIDTH_ = 1;
     24 
     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_;
     30 
     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_;
     37 
     38 };
     39 
     40 
     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   }
     47 
     48   // Verify that scrollbars are added/removed correctly on the home screen.
     49   this.verifyHomeScreenScrollbars_()
     50       .then(browserTest.pass, browserTest.fail);
     51 };
     52 
     53 
     54 /**
     55  * Verify the test cases for the home-screen.
     56  */
     57 browserTest.Scrollbars.prototype.verifyHomeScreenScrollbars_ = function() {
     58   // Note that, due to crbug.com/240772, if the window already has
     59   // scroll-bars, they will not be removed if the window size is
     60   // increased by less than the scroll-bar width. We work around that
     61   // when connected to a host because we know how big the content is
     62   // (in fact, testing this work-around is the main motivation for
     63   // writing this test), but it's not worth it for the home screen,
     64   // so make the window large not to require scrollbars before each test.
     65   var tooWide = this.CONTENT_WIDTH_ + 100;
     66   var tooTall = this.CONTENT_HEIGHT_ + 100;
     67   var removeScrollbars = this.resize_.bind(this, tooWide, tooTall);
     68 
     69   // Verify there are no scroll-bars if the window is as big as it needs
     70   // to be.
     71   return removeScrollbars()
     72   .then(this.resizeAndVerifyScroll_(
     73         this.CONTENT_WIDTH_,
     74         this.CONTENT_HEIGHT_,
     75         false, false))
     76 
     77   // Verify there is a vertical scroll-bar if the window is shorter than it
     78   // needs to be.
     79   .then(removeScrollbars)
     80   .then(this.resizeAndVerifyScroll_.bind(
     81         this,
     82         this.CONTENT_WIDTH_ + this.SCROLLBAR_WIDTH_,
     83         this.CONTENT_HEIGHT_ - 1,
     84         false, true))
     85 
     86   // Verify there is a horizontal scroll-bar if the window is narrow than it
     87   // needs to be.
     88   .then(removeScrollbars)
     89   .then(this.resizeAndVerifyScroll_.bind(
     90         this,
     91         this.CONTENT_WIDTH_ - 1,
     92         this.CONTENT_HEIGHT_ + this.SCROLLBAR_WIDTH_,
     93         true, false))
     94 
     95   // Verify there are both horizontal and vertical scroll-bars, even if one
     96   // is only needed as a result of the space occupied by the other.
     97   .then(removeScrollbars)
     98   .then(this.resizeAndVerifyScroll_.bind(
     99         this,
    100         this.CONTENT_WIDTH_,
    101         this.CONTENT_HEIGHT_ - 1,
    102         true, true))
    103   .then(removeScrollbars)
    104   .then(this.resizeAndVerifyScroll_.bind(
    105         this,
    106         this.CONTENT_WIDTH_ - 1,
    107         this.CONTENT_HEIGHT_,
    108         true, true))
    109 
    110   // Verify there are both horizontal and vertical scroll-bars, if both are
    111   // required independently.
    112   .then(removeScrollbars)
    113   .then(this.resizeAndVerifyScroll_.bind(
    114         this,
    115         this.CONTENT_WIDTH_ - 1,
    116         this.CONTENT_HEIGHT_ - 1,
    117         true, true));
    118 };
    119 
    120 
    121 /**
    122  * Returns whether or not horizontal and vertical scroll-bars are expected
    123  * and visible. To do this, it performs a hit-test close to the right and
    124  * bottom edges of the scroller <div>; since the content of that <div> fills
    125  * it completely, the hit-test will return the content unless there is a
    126  * scroll-bar visible on the corresponding edge, in which case it will return
    127  * the scroller <div> itself.
    128  *
    129  * @private
    130  */
    131 browserTest.Scrollbars.prototype.getScrollbarState_ = function() {
    132   var rect = this.scroller_.getBoundingClientRect();
    133   var rightElement = document.elementFromPoint(
    134       rect.right - 1, (rect.top + rect.bottom) / 2);
    135   var bottomElement = document.elementFromPoint(
    136       (rect.left + rect.right) / 2, rect.bottom - 1);
    137   return {
    138     horizontal: bottomElement === this.scroller_,
    139     vertical: rightElement === this.scroller_
    140   };
    141 };
    142 
    143 
    144 /**
    145  * Returns a promise that resolves if the scroll-bar state is as expected, or
    146  * rejects otherwise.
    147  *
    148  * @private
    149  */
    150 browserTest.Scrollbars.prototype.verifyScrollbarState_ =
    151     function(horizontalExpected, verticalExpected) {
    152   var scrollbarState = this.getScrollbarState_();
    153   if (scrollbarState.horizontal && !horizontalExpected) {
    154     return Promise.reject(new Error(
    155         'Horizontal scrollbar present but not expected.'));
    156   } else if (!scrollbarState.horizontal && horizontalExpected) {
    157     return Promise.reject(new Error(
    158         'Horizontal scrollbar expected but not present.'));
    159   } else if (scrollbarState.vertical && !verticalExpected) {
    160     return Promise.reject(new Error(
    161         'Vertical scrollbar present but not expected.'));
    162   } else if (!scrollbarState.vertical && verticalExpected) {
    163     return Promise.reject(new Error(
    164         'Vertical scrollbar expected but not present.'));
    165   }
    166   return Promise.resolve();
    167 };
    168 
    169 
    170 /**
    171  * @private
    172  * @return {Promise} A promise that will be fulfilled when the window has
    173  *     been resized and it's safe to test scroll-bar visibility.
    174  */
    175 browserTest.Scrollbars.prototype.resize_ = function(width, height) {
    176   var win = chrome.app.window.current();
    177   win.resizeTo(width, height);
    178   // Chrome takes a while to update the scroll-bars, so don't resolve
    179   // immediately. Waiting for the onBoundsChanged event would be cleaner,
    180   // but isn't reliable.
    181   return base.Promise.sleep(500);
    182 };
    183 
    184 
    185 /**
    186  * @private
    187  * @return {Promise} A promise that will be fulfilled when the window has
    188  *     been resized and it's safe to test scroll-bar visibility.
    189  */
    190 browserTest.Scrollbars.prototype.resizeAndVerifyScroll_ =
    191     function(width, height, horizontalExpected, verticalExpected) {
    192   return this.resize_(width, height).then(
    193       this.verifyScrollbarState_.bind(
    194           this, horizontalExpected, verticalExpected));
    195 };
    196