Fix broken path in extensions/common/PRESUBMIT.py
[chromium-blink-merge.git] / remoting / webapp / browser_test / bump_scroll_browser_test.js
blob38eea467206034bc741ce7c78cff58ab10af5a71
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  * @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  */
13 'use strict';
15 /** @constructor */
16 browserTest.FakeDesktopViewport = function() {
17   /** @private */
18   this.pluginPosition_ = {
19     top: 0,
20     left: 0
21   };
22   /** @private */
23   this.bumpScroller_ = new base.EventSourceImpl();
24   this.bumpScroller_.defineEvents(Object.keys(remoting.BumpScroller.Events));
27 /**
28  * @param {number} top
29  * @param {number} left
30  * @return {void} nothing.
31  */
32 browserTest.FakeDesktopViewport.prototype.setPluginPositionForTesting =
33     function(top, left) {
34   this.pluginPosition_ = {
35     top: top,
36     left: left
37   };
40 /**
41  * @return {{top: number, left:number}} The top-left corner of the plugin.
42  */
43 browserTest.FakeDesktopViewport.prototype.getPluginPositionForTesting =
44     function() {
45   return this.pluginPosition_;
48 /** @return {base.EventSource} */
49 browserTest.FakeDesktopViewport.prototype.getBumpScrollerForTesting =
50     function() {
51   return this.bumpScroller_;
54 browserTest.FakeDesktopViewport.prototype.raiseEvent =
55     function() {
56   return this.bumpScroller_.raiseEvent.apply(this.bumpScroller_, arguments);
59 /** @return {remoting.DesktopViewport} */
60 function getViewportForTesting() {
61   var desktopApp = /** @type {remoting.DesktopRemoting} */ (remoting.app);
62   var view = desktopApp.getConnectedViewForTesting();
63   if (view) {
64     return view.getViewportForTesting();
65   }
66   return null;
69 /** @constructor */
70 browserTest.Bump_Scroll = function() {
71   // To avoid dependencies on the actual host desktop size, we simulate a
72   // desktop larger or smaller than the client window. The exact value is
73   // arbitrary, but must be positive.
74   /** @type {number} */
75   this.kHostDesktopSizeDelta = 10;
78 /**
79  * @param {{pin:string}} data
80  */
81 browserTest.Bump_Scroll.prototype.run = function(data) {
82   browserTest.expect(typeof data.pin == 'string');
84   if (!base.isAppsV2()) {
85     browserTest.fail(
86         'Bump-scroll requires full-screen, which can only be activated ' +
87         'programmatically in apps v2.');
88   }
90   var mockConnection = new remoting.MockConnection();
91   mockConnection.plugin().mock$useDefaultBehavior(
92       remoting.MockClientPlugin.AuthMethod.PIN);
94   function cleanup() {
95     mockConnection.restore();
96     browserTest.disconnect();
97   }
99   this.testVerifyScroll().then(function() {
100     return browserTest.connectMe2Me();
101   }).then(function() {
102     return browserTest.enterPIN(data.pin);
103   }).then(
104     this.noScrollWindowed.bind(this)
105   ).then(
106     this.activateFullscreen.bind(this)
107   ).then(
108     this.noScrollSmaller.bind(this)
109     // The order of these operations is important. Because the plugin starts
110     // scrolled to the top-left, it needs to be scrolled right and down first.
111   ).then(
112     this.scrollDirection.bind(this, 1.0, 0.5)  // Right edge
113   ).then(
114     this.scrollDirection.bind(this, 0.5, 1.0)  // Bottom edge
115   ).then(
116     this.scrollDirection.bind(this, 0.0, 0.5)  // Left edge
117   ).then(
118     this.scrollDirection.bind(this, 0.5, 0.0)  // Top edge
119   ).then(
120     function(value) {
121       cleanup();
122       return browserTest.pass(value);
123     },
124     function(error) {
125       cleanup();
126       return browserTest.fail(error);
127     }
128   );
132  * @return {Promise}
133  */
134 browserTest.Bump_Scroll.prototype.noScrollWindowed = function() {
135   var viewport = getViewportForTesting();
136   viewport.setPluginSizeForBumpScrollTesting(
137       window.innerWidth + this.kHostDesktopSizeDelta,
138       window.innerHeight + this.kHostDesktopSizeDelta);
139   this.moveMouseTo(0, 0);
140   return this.verifyNoScroll();
144  * @return {Promise}
145  */
146 browserTest.Bump_Scroll.prototype.noScrollSmaller = function() {
147   var viewport = getViewportForTesting();
148   viewport.setPluginSizeForBumpScrollTesting(
149       window.innerWidth - this.kHostDesktopSizeDelta,
150       window.innerHeight - this.kHostDesktopSizeDelta);
151   this.moveMouseTo(0, 0);
152   return this.verifyNoScroll();
156  * @param {number} widthFraction
157  * @param {number} heightFraction
158  * @return {Promise}
159  */
160 browserTest.Bump_Scroll.prototype.scrollDirection =
161     function(widthFraction, heightFraction) {
162   var viewport = getViewportForTesting();
163   viewport.setPluginSizeForBumpScrollTesting(
164       screen.width + this.kHostDesktopSizeDelta,
165       screen.height + this.kHostDesktopSizeDelta);
166   /** @type {number} */
167   var expectedTop = heightFraction === 0.0 ? 0 :
168                     heightFraction == 1.0 ? -this.kHostDesktopSizeDelta :
169                     undefined;
170   /** @type {number} */
171   var expectedLeft = widthFraction === 0.0 ? 0 :
172                      widthFraction === 1.0 ? -this.kHostDesktopSizeDelta :
173                      undefined;
174   var result = this.verifyScroll(expectedTop, expectedLeft);
175   this.moveMouseTo(widthFraction * screen.width,
176                    heightFraction * screen.height);
177   return result;
181  * @return {Promise}
182  */
183 browserTest.Bump_Scroll.prototype.activateFullscreen = function() {
184   return new Promise(function(fulfill, reject) {
185     remoting.fullscreen.activate(true, function() {
186       // The onFullscreen callback is invoked before the window has
187       // resized, so defer fulfilling the promise so that innerWidth
188       // and innerHeight are correct.
189       base.Promise.sleep(1000).then(fulfill);
190     });
191     base.Promise.sleep(5000).then(function(){
192       reject('Timed out waiting for full-screen');
193     });
194   });
198  * @param {number} x
199  * @param {number} y
200  */
201 browserTest.Bump_Scroll.prototype.moveMouseTo = function(x, y) {
202   var e = {
203     bubbles: true,
204     cancelable: false,
205     view: window,
206     detail: 0,
207     screenX: x,
208     screenY: y,
209     clientX: x,
210     clientY: y,
211     ctrlKey: false,
212     altKey: false,
213     shiftKey: false,
214     metaKey: false,
215     button: 0,
216     relatedTarget: undefined
217   };
218   var event = document.createEvent('MouseEvents');
219   event.initMouseEvent('mousemove',
220                        e.bubbles, e.cancelable, e.view, e.detail,
221                        e.screenX, e.screenY, e.clientX, e.clientY,
222                        e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
223                        e.button, document.documentElement);
224   document.documentElement.dispatchEvent(event);
228  * verifyScroll() is complicated enough to warrant a test.
229  * @return {Promise}
230  */
231 browserTest.Bump_Scroll.prototype.testVerifyScroll = function() {
232   var STARTED = remoting.BumpScroller.Events.bumpScrollStarted;
233   var STOPPED = remoting.BumpScroller.Events.bumpScrollStopped;
234   var fakeViewport = new browserTest.FakeDesktopViewport;
235   var that = this;
237   // No events raised (e.g. windowed mode).
238   var result = this.verifyNoScroll(fakeViewport)
240   .then(function() {
241     // Start and end events raised, but no scrolling (e.g. full-screen mode
242     // with host desktop <= window size).
243     fakeViewport = new browserTest.FakeDesktopViewport;
244     var result = that.verifyNoScroll(fakeViewport);
245     fakeViewport.raiseEvent(STARTED, {});
246     fakeViewport.raiseEvent(STOPPED, {});
247     return result;
249   }).then(function() {
250     // Start and end events raised, with incorrect scrolling.
251     fakeViewport = new browserTest.FakeDesktopViewport;
252     var result = base.Promise.negate(
253         that.verifyScroll(2, 2, fakeViewport));
254     fakeViewport.raiseEvent(STARTED, {});
255     fakeViewport.setPluginPositionForTesting(1, 1);
256     fakeViewport.raiseEvent(STOPPED, {});
257     return result;
259   }).then(function() {
260     // Start event raised, but not end event.
261     fakeViewport = new browserTest.FakeDesktopViewport;
262     var result = base.Promise.negate(
263         that.verifyScroll(2, 2, fakeViewport));
264     fakeViewport.raiseEvent(STARTED, {});
265     fakeViewport.setPluginPositionForTesting(2, 2);
266     return result;
268   }).then(function() {
269     // Start and end events raised, with correct scrolling.
270     fakeViewport = new browserTest.FakeDesktopViewport;
271     var result = that.verifyScroll(2, 2, fakeViewport);
272     fakeViewport.raiseEvent(STARTED, {});
273     fakeViewport.setPluginPositionForTesting(2, 2);
274     fakeViewport.raiseEvent(STOPPED, {});
275     return result;
276   });
278   return result;
282  * Verify that a bump scroll operation takes place and that the top-left corner
283  * of the plugin is as expected when it completes.
284  * @param {number|undefined} expectedTop The expected vertical position of the
285  *    plugin, or undefined if it is not expected to change.
286  * @param {number|undefined} expectedLeft The expected horizontal position of
287  *    the plugin, or undefined if it is not expected to change.
288  * @param {browserTest.FakeDesktopViewport=} opt_desktopViewport
289  *     DesktopViewport fake, for testing.
290  * @return {Promise}
291  */
292 browserTest.Bump_Scroll.prototype.verifyScroll =
293     function (expectedTop, expectedLeft, opt_desktopViewport) {
294   var desktopViewport = opt_desktopViewport || getViewportForTesting();
295   base.debug.assert(desktopViewport != null);
296   var STARTED = remoting.BumpScroller.Events.bumpScrollStarted;
297   var STOPPED = remoting.BumpScroller.Events.bumpScrollStopped;
299   var initialPosition = desktopViewport.getPluginPositionForTesting();
300   var initialTop = initialPosition.top;
301   var initialLeft = initialPosition.left;
303   /** @return {Promise} */
304   var verifyPluginPosition = function() {
305     var position = desktopViewport.getPluginPositionForTesting();
306     if (expectedLeft === undefined) {
307       expectedLeft = initialLeft;
308     }
309     if (expectedTop === undefined) {
310       expectedTop = initialTop;
311     }
312     if (position.top != expectedTop || position.left != expectedLeft) {
313       return Promise.reject(
314           new Error('No or incorrect scroll detected: (' +
315                     position.left + ',' + position.top + ' instead of ' +
316                     expectedLeft + ',' + expectedTop + ')'));
317     } else {
318       return Promise.resolve();
319     }
320   };
322   var bumpScroller = desktopViewport.getBumpScrollerForTesting();
323   var started = browserTest.expectEvent(bumpScroller, STARTED, 1000);
324   var stopped = browserTest.expectEvent(bumpScroller, STOPPED, 5000);
325   return started.then(function() {
326     return stopped;
327   }, function() {
328     // If no started event is raised, the test might still pass if it asserted
329     // no scrolling.
330     if (expectedTop === undefined && expectedLeft === undefined) {
331       return Promise.resolve();
332     } else {
333       return Promise.reject(
334           new Error('Scroll expected but no start event fired.'));
335     }
336   }).then(function() {
337     return verifyPluginPosition();
338   });
342  * @param {browserTest.FakeDesktopViewport=} opt_desktopViewport
343  *     DesktopViewport fake, for testing.
345  * @return {Promise<boolean>} A promise that resolves to true if no scrolling
346  *   occurs within a timeout.
347  */
348 browserTest.Bump_Scroll.prototype.verifyNoScroll =
349     function(opt_desktopViewport) {
350   var desktopViewport = opt_desktopViewport || getViewportForTesting();
351   var bumpScroller = desktopViewport.getBumpScrollerForTesting();
352   if (!bumpScroller) {
353     Promise.resolve(true);
354   }
355   return this.verifyScroll(undefined, undefined, desktopViewport);