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  * @fileoverview
      7  * @suppress {checkTypes}
      8  * Browser test for the scenario below:
      9  * 1. Enter full-screen mode
     10  * 2. Move the mouse to each edge; verify that the desktop bump-scrolls.
     11  */
     12 
     13 'use strict';
     14 
     15 /** @constructor */
     16 browserTest.FakeClientSession = function() {
     17   this.pluginPosition = {
     18     top: 0,
     19     left: 0
     20   };
     21   this.defineEvents(Object.keys(remoting.ClientSession.Events));
     22 };
     23 
     24 base.extend(browserTest.FakeClientSession, base.EventSource);
     25 
     26 browserTest.FakeClientSession.prototype.getPluginPositionForTesting =
     27     function() {
     28   return this.pluginPosition;
     29 };
     30 
     31 
     32 /** @constructor */
     33 browserTest.Bump_Scroll = function() {
     34   // To aviod dependencies on the actual host desktop size, we simulate a
     35   // desktop larger or smaller than the client window. The exact value is
     36   // arbitrary, but must be positive.
     37   this.kHostDesktopSizeDelta = 10;
     38 };
     39 
     40 browserTest.Bump_Scroll.prototype.run = function(data) {
     41   browserTest.expect(typeof data.pin == 'string');
     42 
     43   if (!base.isAppsV2()) {
     44     browserTest.fail(
     45         'Bump-scroll requires full-screen, which can only be activated ' +
     46         'programmatically in apps v2.')
     47   }
     48 
     49   this.testVerifyScroll().then(function() {
     50     return browserTest.connectMe2Me();
     51   }).then(function() {
     52     return browserTest.enterPIN(data.pin);
     53   }).then(
     54     this.noScrollWindowed.bind(this)
     55   ).then(
     56     this.activateFullscreen.bind(this)
     57   ).then(
     58     this.noScrollSmaller.bind(this)
     59     // The order of these operations is important. Because the plugin starts
     60     // scrolled to the top-left, it needs to be scrolled right and down first.
     61   ).then(
     62     this.scrollDirection.bind(this, 1.0, 0.5)  // Right edge
     63   ).then(
     64     this.scrollDirection.bind(this, 0.5, 1.0)  // Bottom edge
     65   ).then(
     66     this.scrollDirection.bind(this, 0.0, 0.5)  // Left edge
     67   ).then(
     68     this.scrollDirection.bind(this, 0.5, 0.0)  // Top edge
     69   ).then(
     70     function(value) {
     71       browserTest.disconnect();
     72       return browserTest.pass(value);
     73     },
     74     function(error) {
     75       browserTest.disconnect();
     76       return browserTest.fail(error);
     77     }
     78   );
     79 };
     80 
     81 browserTest.Bump_Scroll.prototype.noScrollWindowed = function() {
     82   remoting.clientSession.pluginWidthForBumpScrollTesting =
     83       window.innerWidth + this.kHostDesktopSizeDelta;
     84   remoting.clientSession.pluginHeightForBumpScrollTesting =
     85       window.innerHeight + this.kHostDesktopSizeDelta;
     86   this.moveMouseTo(0, 0);
     87   return this.verifyScroll(undefined, undefined);
     88 };
     89 
     90 browserTest.Bump_Scroll.prototype.noScrollSmaller = function() {
     91   remoting.clientSession.pluginWidthForBumpScrollTesting =
     92       window.innerWidth - this.kHostDesktopSizeDelta;
     93   remoting.clientSession.pluginHeightForBumpScrollTesting =
     94       window.innerHeight - this.kHostDesktopSizeDelta;
     95   this.moveMouseTo(0, 0);
     96   return this.verifyScroll(undefined, undefined);
     97 };
     98 
     99 browserTest.Bump_Scroll.prototype.scrollDirection =
    100     function(widthFraction, heightFraction) {
    101   remoting.clientSession.pluginWidthForBumpScrollTesting =
    102       screen.width + this.kHostDesktopSizeDelta;
    103   remoting.clientSession.pluginHeightForBumpScrollTesting =
    104       screen.height + this.kHostDesktopSizeDelta;
    105   var expectedTop = heightFraction == 0.0 ? 0 :
    106                     heightFraction == 1.0 ? -this.kHostDesktopSizeDelta :
    107                     undefined;
    108   var expectedLeft = widthFraction == 0.0 ? 0 :
    109                      widthFraction == 1.0 ? -this.kHostDesktopSizeDelta :
    110                      undefined;
    111   var result = this.verifyScroll(expectedTop, expectedLeft);
    112   this.moveMouseTo(widthFraction * screen.width,
    113                    heightFraction * screen.height);
    114   return result;
    115 };
    116 
    117 browserTest.Bump_Scroll.prototype.activateFullscreen = function() {
    118   return new Promise(function(fulfill, reject) {
    119     remoting.fullscreen.activate(true, function() {
    120       // The onFullscreen callback is invoked before the window has
    121       // resized, so defer fulfilling the promise so that innerWidth
    122       // and innerHeight are correct.
    123       base.Promise.sleep(1000).then(fulfill);
    124     });
    125     base.Promise.sleep(5000).then(function(){
    126       reject('Timed out waiting for full-screen');
    127     });
    128   });
    129 };
    130 
    131 browserTest.Bump_Scroll.prototype.moveMouseTo = function(x, y) {
    132   var e = {
    133     bubbles: true,
    134     cancelable: false,
    135     view: window,
    136     detail: 0,
    137     screenX: x,
    138     screenY: y,
    139     clientX: x,
    140     clientY: y,
    141     ctrlKey: false,
    142     altKey: false,
    143     shiftKey: false,
    144     metaKey: false,
    145     button: 0,
    146     relatedTarget: undefined
    147   };
    148   var event = document.createEvent('MouseEvents');
    149   event.initMouseEvent('mousemove',
    150                        e.bubbles, e.cancelable, e.view, e.detail,
    151                        e.screenX, e.screenY, e.clientX, e.clientY,
    152                        e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
    153                        e.button, document.documentElement);
    154   document.documentElement.dispatchEvent(event);
    155 };
    156 
    157 // verifyScroll is complicated enough to warrant a test
    158 browserTest.Bump_Scroll.prototype.testVerifyScroll = function() {
    159   var STARTED = remoting.ClientSession.Events.bumpScrollStarted;
    160   var STOPPED = remoting.ClientSession.Events.bumpScrollStopped;
    161   var fakeSession = new browserTest.FakeClientSession;
    162   var that = this;
    163 
    164   // No events raised (e.g. windowed mode).
    165   var result = this.verifyScroll(undefined, undefined, fakeSession)
    166 
    167   .then(function() {
    168     // Start and end events raised, but no scrolling (e.g. full-screen mode
    169     // with host desktop <= window size).
    170     fakeSession = new browserTest.FakeClientSession;
    171     var result = that.verifyScroll(undefined, undefined, fakeSession);
    172     fakeSession.raiseEvent(STARTED, {});
    173     fakeSession.raiseEvent(STOPPED, {});
    174     return result;
    175 
    176   }).then(function() {
    177     // Start and end events raised, with incorrect scrolling.
    178     fakeSession = new browserTest.FakeClientSession;
    179     var result = base.Promise.negate(
    180         that.verifyScroll(2, 2, fakeSession));
    181     fakeSession.raiseEvent(STARTED, {});
    182     fakeSession.pluginPosition.top = 1;
    183     fakeSession.pluginPosition.left = 1;
    184     fakeSession.raiseEvent(STOPPED, {});
    185     return result;
    186 
    187   }).then(function() {
    188     // Start event raised, but not end event.
    189     fakeSession = new browserTest.FakeClientSession;
    190     var result = base.Promise.negate(
    191         that.verifyScroll(2, 2, fakeSession));
    192     fakeSession.raiseEvent(STARTED, {});
    193     fakeSession.pluginPosition.top = 2;
    194     fakeSession.pluginPosition.left = 2;
    195     return result;
    196 
    197   }).then(function() {
    198     // Start and end events raised, with correct scrolling.
    199     fakeSession = new browserTest.FakeClientSession;
    200     var result = that.verifyScroll(2, 2, fakeSession);
    201     fakeSession.raiseEvent(STARTED, {});
    202     fakeSession.pluginPosition.top = 2;
    203     fakeSession.pluginPosition.left = 2;
    204     fakeSession.raiseEvent(STOPPED, {});
    205     return result;
    206   });
    207 
    208   return result;
    209 };
    210 
    211 /**
    212  * Verify that a bump scroll operation takes place and that the top-left corner
    213  * of the plugin is as expected when it completes.
    214  * @param {number|undefined} expectedTop The expected vertical position of the
    215  *    plugin, or undefined if it is not expected to change.
    216  * @param {number|undefined} expectedLeft The expected horizontal position of
    217  *    the plugin, or undefined if it is not expected to change.
    218  * @param {browserTest.FakeClientSession=} opt_clientSession ClientSession-like
    219  *     fake, for testing.
    220  */
    221 browserTest.Bump_Scroll.prototype.verifyScroll =
    222     function (expectedTop, expectedLeft, opt_clientSession) {
    223   var clientSession = opt_clientSession || remoting.clientSession;
    224   base.debug.assert(clientSession != null);
    225   var STARTED = remoting.ClientSession.Events.bumpScrollStarted;
    226   var STOPPED = remoting.ClientSession.Events.bumpScrollStopped;
    227 
    228   var initialPosition = clientSession.getPluginPositionForTesting();
    229   var initialTop = initialPosition.top;
    230   var initialLeft = initialPosition.left;
    231 
    232   var verifyPluginPosition = function() {
    233     var position = clientSession.getPluginPositionForTesting();
    234     if (expectedLeft === undefined) {
    235       expectedLeft = initialLeft;
    236     }
    237     if (expectedTop === undefined) {
    238       expectedTop = initialTop;
    239     }
    240     if (position.top != expectedTop || position.left != expectedLeft) {
    241       return Promise.reject(
    242           new Error('No or incorrect scroll detected: (' +
    243                     position.left + ',' + position.top + ' instead of ' +
    244                     expectedLeft + ',' + expectedTop + ')'));
    245     } else {
    246       return Promise.resolve();
    247     }
    248   };
    249 
    250   var started = browserTest.expectEvent(clientSession, STARTED, 1000);
    251   var stopped = browserTest.expectEvent(clientSession, STOPPED, 5000);
    252   return started.then(function() {
    253     return stopped.then(function() {
    254       return verifyPluginPosition();
    255     });
    256   }, function() {
    257     // If no started event is raised, the test might still pass if it asserted
    258     // no scrolling.
    259     if (expectedTop == undefined && expectedLeft == undefined) {
    260       return Promise.resolve();
    261     } else {
    262       return Promise.reject(
    263           new Error('Scroll expected but no start event fired.'));
    264     }
    265   });
    266 };
    267