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 /** @suppress {reportUnknownTypes} */
55 browserTest.FakeDesktopViewport.prototype.raiseEvent =
57 return this.bumpScroller_.raiseEvent.apply(this.bumpScroller_, arguments);
60 /** @return {remoting.DesktopViewport} */
61 function getViewportForTesting() {
62 var desktopApp = /** @type {remoting.DesktopRemoting} */ (remoting.app);
63 var view = desktopApp.getConnectedViewForTesting();
65 return view.getViewportForTesting();
71 browserTest.Bump_Scroll = function() {
72 // To avoid dependencies on the actual host desktop size, we simulate a
73 // desktop larger or smaller than the client window. The exact value is
74 // arbitrary, but must be positive.
76 this.kHostDesktopSizeDelta = 10;
80 * @param {{pin:string}} data
82 browserTest.Bump_Scroll.prototype.run = function(data) {
83 browserTest.expect(typeof data.pin == 'string');
85 if (!base.isAppsV2()) {
87 'Bump-scroll requires full-screen, which can only be activated ' +
88 'programmatically in apps v2.');
91 var mockConnection = new remoting.MockConnection();
93 function onPluginCreated(/** remoting.MockClientPlugin */ plugin) {
94 plugin.mock$useDefaultBehavior(remoting.MockClientPlugin.AuthMethod.PIN);
96 mockConnection.pluginFactory().mock$setPluginCreated(onPluginCreated);
100 mockConnection.restore();
101 browserTest.disconnect();
104 this.testVerifyScroll().then(function() {
105 return browserTest.connectMe2Me();
107 return browserTest.enterPIN(data.pin);
109 this.noScrollWindowed.bind(this)
111 this.activateFullscreen.bind(this)
113 this.noScrollSmaller.bind(this)
114 // The order of these operations is important. Because the plugin starts
115 // scrolled to the top-left, it needs to be scrolled right and down first.
117 this.scrollDirection.bind(this, 1.0, 0.5) // Right edge
119 this.scrollDirection.bind(this, 0.5, 1.0) // Bottom edge
121 this.scrollDirection.bind(this, 0.0, 0.5) // Left edge
123 this.scrollDirection.bind(this, 0.5, 0.0) // Top edge
127 return browserTest.pass();
131 return browserTest.fail(error);
139 browserTest.Bump_Scroll.prototype.noScrollWindowed = function() {
140 var viewport = getViewportForTesting();
141 viewport.setPluginSizeForBumpScrollTesting(
142 window.innerWidth + this.kHostDesktopSizeDelta,
143 window.innerHeight + this.kHostDesktopSizeDelta);
144 this.moveMouseTo(0, 0);
145 return this.verifyNoScroll();
151 browserTest.Bump_Scroll.prototype.noScrollSmaller = function() {
152 var viewport = getViewportForTesting();
153 viewport.setPluginSizeForBumpScrollTesting(
154 window.innerWidth - this.kHostDesktopSizeDelta,
155 window.innerHeight - this.kHostDesktopSizeDelta);
156 this.moveMouseTo(0, 0);
157 return this.verifyNoScroll();
161 * @param {number} widthFraction
162 * @param {number} heightFraction
165 browserTest.Bump_Scroll.prototype.scrollDirection =
166 function(widthFraction, heightFraction) {
167 var viewport = getViewportForTesting();
168 viewport.setPluginSizeForBumpScrollTesting(
169 screen.width + this.kHostDesktopSizeDelta,
170 screen.height + this.kHostDesktopSizeDelta);
171 /** @type {number} */
172 var expectedTop = heightFraction === 0.0 ? 0 :
173 heightFraction == 1.0 ? -this.kHostDesktopSizeDelta :
175 /** @type {number} */
176 var expectedLeft = widthFraction === 0.0 ? 0 :
177 widthFraction === 1.0 ? -this.kHostDesktopSizeDelta :
179 var result = this.verifyScroll(expectedTop, expectedLeft);
180 this.moveMouseTo(widthFraction * screen.width,
181 heightFraction * screen.height);
188 browserTest.Bump_Scroll.prototype.activateFullscreen = function() {
189 return new Promise(function(fulfill, reject) {
190 remoting.fullscreen.activate(true, function() {
191 // The onFullscreen callback is invoked before the window has
192 // resized, so defer fulfilling the promise so that innerWidth
193 // and innerHeight are correct.
194 base.Promise.sleep(1000).then(fulfill);
196 base.Promise.sleep(5000).then(function(){
197 reject('Timed out waiting for full-screen');
206 browserTest.Bump_Scroll.prototype.moveMouseTo = function(x, y) {
221 relatedTarget: undefined
223 var event = document.createEvent('MouseEvents');
224 event.initMouseEvent('mousemove',
225 e.bubbles, e.cancelable, e.view, e.detail,
226 e.screenX, e.screenY, e.clientX, e.clientY,
227 e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
228 e.button, document.documentElement);
229 document.documentElement.dispatchEvent(event);
233 * verifyScroll() is complicated enough to warrant a test.
236 browserTest.Bump_Scroll.prototype.testVerifyScroll = function() {
237 var STARTED = remoting.BumpScroller.Events.bumpScrollStarted;
238 var STOPPED = remoting.BumpScroller.Events.bumpScrollStopped;
239 var fakeViewport = new browserTest.FakeDesktopViewport;
242 // No events raised (e.g. windowed mode).
243 var result = this.verifyNoScroll(fakeViewport)
246 // Start and end events raised, but no scrolling (e.g. full-screen mode
247 // with host desktop <= window size).
248 fakeViewport = new browserTest.FakeDesktopViewport;
249 var result = that.verifyNoScroll(fakeViewport);
250 fakeViewport.raiseEvent(STARTED, {});
251 fakeViewport.raiseEvent(STOPPED, {});
255 // Start and end events raised, with incorrect scrolling.
256 fakeViewport = new browserTest.FakeDesktopViewport;
257 var result = base.Promise.negate(
258 that.verifyScroll(2, 2, fakeViewport));
259 fakeViewport.raiseEvent(STARTED, {});
260 fakeViewport.setPluginPositionForTesting(1, 1);
261 fakeViewport.raiseEvent(STOPPED, {});
265 // Start event raised, but not end event.
266 fakeViewport = new browserTest.FakeDesktopViewport;
267 var result = base.Promise.negate(
268 that.verifyScroll(2, 2, fakeViewport));
269 fakeViewport.raiseEvent(STARTED, {});
270 fakeViewport.setPluginPositionForTesting(2, 2);
274 // Start and end events raised, with correct scrolling.
275 fakeViewport = new browserTest.FakeDesktopViewport;
276 var result = that.verifyScroll(2, 2, fakeViewport);
277 fakeViewport.raiseEvent(STARTED, {});
278 fakeViewport.setPluginPositionForTesting(2, 2);
279 fakeViewport.raiseEvent(STOPPED, {});
287 * Verify that a bump scroll operation takes place and that the top-left corner
288 * of the plugin is as expected when it completes.
289 * @param {number|undefined} expectedTop The expected vertical position of the
290 * plugin, or undefined if it is not expected to change.
291 * @param {number|undefined} expectedLeft The expected horizontal position of
292 * the plugin, or undefined if it is not expected to change.
293 * @param {browserTest.FakeDesktopViewport=} opt_desktopViewport
294 * DesktopViewport fake, for testing.
297 browserTest.Bump_Scroll.prototype.verifyScroll =
298 function (expectedTop, expectedLeft, opt_desktopViewport) {
299 var desktopViewport = opt_desktopViewport || getViewportForTesting();
300 console.assert(desktopViewport != null, '|desktopViewport| is null.');
301 var STARTED = remoting.BumpScroller.Events.bumpScrollStarted;
302 var STOPPED = remoting.BumpScroller.Events.bumpScrollStopped;
304 var initialPosition = desktopViewport.getPluginPositionForTesting();
305 var initialTop = initialPosition.top;
306 var initialLeft = initialPosition.left;
308 /** @return {Promise} */
309 var verifyPluginPosition = function() {
310 var position = desktopViewport.getPluginPositionForTesting();
311 if (expectedLeft === undefined) {
312 expectedLeft = initialLeft;
314 if (expectedTop === undefined) {
315 expectedTop = initialTop;
317 if (position.top != expectedTop || position.left != expectedLeft) {
318 return Promise.reject(
319 new Error('No or incorrect scroll detected: (' +
320 position.left + ',' + position.top + ' instead of ' +
321 expectedLeft + ',' + expectedTop + ')'));
323 return Promise.resolve();
327 var bumpScroller = desktopViewport.getBumpScrollerForTesting();
328 var started = browserTest.expectEvent(bumpScroller, STARTED, 1000);
329 var stopped = browserTest.expectEvent(bumpScroller, STOPPED, 5000);
330 return started.then(function() {
333 // If no started event is raised, the test might still pass if it asserted
335 if (expectedTop === undefined && expectedLeft === undefined) {
336 return Promise.resolve();
338 return Promise.reject(
339 new Error('Scroll expected but no start event fired.'));
342 return verifyPluginPosition();
347 * @param {browserTest.FakeDesktopViewport=} opt_desktopViewport
348 * DesktopViewport fake, for testing.
350 * @return {Promise<boolean>} A promise that resolves to true if no scrolling
351 * occurs within a timeout.
353 browserTest.Bump_Scroll.prototype.verifyNoScroll =
354 function(opt_desktopViewport) {
355 var desktopViewport = opt_desktopViewport || getViewportForTesting();
356 var bumpScroller = desktopViewport.getBumpScrollerForTesting();
358 Promise.resolve(true);
360 return this.verifyScroll(undefined, undefined, desktopViewport);