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.
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.
16 browserTest.FakeDesktopViewport = function() {
18 this.pluginPosition_ = {
23 this.bumpScroller_ = new base.EventSourceImpl();
24 this.bumpScroller_.defineEvents(Object.keys(remoting.BumpScroller.Events));
29 * @param {number} left
30 * @return {void} nothing.
32 browserTest.FakeDesktopViewport.prototype.setPluginPositionForTesting =
34 this.pluginPosition_ = {
41 * @return {{top: number, left:number}} The top-left corner of the plugin.
43 browserTest.FakeDesktopViewport.prototype.getPluginPositionForTesting =
45 return this.pluginPosition_;
48 /** @return {base.EventSource} */
49 browserTest.FakeDesktopViewport.prototype.getBumpScrollerForTesting =
51 return this.bumpScroller_;
54 browserTest.FakeDesktopViewport.prototype.raiseEvent =
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();
64 return view.getViewportForTesting();
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.
75 this.kHostDesktopSizeDelta = 10;
79 * @param {{pin:string}} data
81 browserTest.Bump_Scroll.prototype.run = function(data) {
82 browserTest.expect(typeof data.pin == 'string');
84 if (!base.isAppsV2()) {
86 'Bump-scroll requires full-screen, which can only be activated ' +
87 'programmatically in apps v2.');
90 var mockConnection = new remoting.MockConnection();
91 mockConnection.plugin().mock$useDefaultBehavior(
92 remoting.MockClientPlugin.AuthMethod.PIN);
95 mockConnection.restore();
96 browserTest.disconnect();
99 this.testVerifyScroll().then(function() {
100 return browserTest.connectMe2Me();
102 return browserTest.enterPIN(data.pin);
104 this.noScrollWindowed.bind(this)
106 this.activateFullscreen.bind(this)
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.
112 this.scrollDirection.bind(this, 1.0, 0.5) // Right edge
114 this.scrollDirection.bind(this, 0.5, 1.0) // Bottom edge
116 this.scrollDirection.bind(this, 0.0, 0.5) // Left edge
118 this.scrollDirection.bind(this, 0.5, 0.0) // Top edge
122 return browserTest.pass(value);
126 return browserTest.fail(error);
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();
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
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 :
170 /** @type {number} */
171 var expectedLeft = widthFraction === 0.0 ? 0 :
172 widthFraction === 1.0 ? -this.kHostDesktopSizeDelta :
174 var result = this.verifyScroll(expectedTop, expectedLeft);
175 this.moveMouseTo(widthFraction * screen.width,
176 heightFraction * screen.height);
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);
191 base.Promise.sleep(5000).then(function(){
192 reject('Timed out waiting for full-screen');
201 browserTest.Bump_Scroll.prototype.moveMouseTo = function(x, y) {
216 relatedTarget: undefined
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.
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;
237 // No events raised (e.g. windowed mode).
238 var result = this.verifyNoScroll(fakeViewport)
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, {});
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, {});
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);
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, {});
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.
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;
309 if (expectedTop === undefined) {
310 expectedTop = initialTop;
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 + ')'));
318 return Promise.resolve();
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() {
328 // If no started event is raised, the test might still pass if it asserted
330 if (expectedTop === undefined && expectedLeft === undefined) {
331 return Promise.resolve();
333 return Promise.reject(
334 new Error('Scroll expected but no start event fired.'));
337 return verifyPluginPosition();
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.
348 browserTest.Bump_Scroll.prototype.verifyNoScroll =
349 function(opt_desktopViewport) {
350 var desktopViewport = opt_desktopViewport || getViewportForTesting();
351 var bumpScroller = desktopViewport.getBumpScrollerForTesting();
353 Promise.resolve(true);
355 return this.verifyScroll(undefined, undefined, desktopViewport);