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