1 // Copyright 2013 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 var callbackPass = chrome.test.callbackPass;
6 var defaultFuzzFactor = 1;
8 function assertFuzzyEq(expected, actual, fuzzFactor, message) {
10 message = "Expected: " + expected + "; actual: " + actual + "; "
11 + "fuzzyFactor: " + fuzzFactor;
14 chrome.test.assertTrue(actual - fuzzFactor <= expected
15 && actual + fuzzFactor >= expected, message);
17 if (actual != expected) {
18 console.log("FUZZ: a factor of " + Math.abs(actual - expected) +
23 // This helper will verify that |check| returns true. If it does not, it will do
24 // a trip to the event loop and will try again until |check| returns true. At
25 // which points |callback| will be called.
26 // NOTE: if the test fails, it will timeout.
27 function eventLoopCheck(check, callback) {
31 setTimeout(callbackPass(function() { eventLoopCheck(check, callback); }));
35 // This help function will call the callback when the window passed to it will
36 // be loaded. The callback will have the AppWindow passed as a parameter.
37 function waitForLoad(win, callback) {
38 var window = win.contentWindow;
40 if (window.document.readyState == 'complete') {
45 window.addEventListener('load', callbackPass(function() {
46 window.removeEventListener('load', arguments.callee);
51 function testCreate() {
52 chrome.test.runTests([
54 chrome.app.window.create('test.html',
56 callbackPass(function(win) {
57 chrome.test.assertEq(typeof win.contentWindow.window, 'object');
58 chrome.test.assertTrue(
59 typeof win.contentWindow.document !== 'undefined');
60 chrome.test.assertFalse(
61 'about:blank' === win.contentWindow.location.href);
62 var cw = win.contentWindow.chrome.app.window.current();
63 chrome.test.assertEq(cw, win);
64 chrome.test.assertEq('testId', cw.id);
65 win.contentWindow.close();
69 function badWindow() {
70 chrome.app.window.create('404.html', callbackPass(function(win) {
71 chrome.test.assertTrue(typeof win === 'undefined');
72 // TODO(mlamouri): because |win| is not defined, we can not close that
77 function loadEvent() {
78 chrome.app.window.create('test.html', callbackPass(function(win) {
79 win.contentWindow.onload = callbackPass(function() {
80 chrome.test.assertEq(document.readyState, 'complete');
81 win.contentWindow.close();
86 function multiWindow() {
87 chrome.test.assertTrue(null === chrome.app.window.current());
88 chrome.app.window.create('test.html',
90 callbackPass(function(win1) {
91 chrome.app.window.create('test.html',
93 callbackPass(function(win2) {
94 var cw1 = win1.contentWindow.chrome.app.window.current();
95 var cw2 = win2.contentWindow.chrome.app.window.current();
96 chrome.test.assertEq('testId1', cw1.id);
97 chrome.test.assertEq('testId2', cw2.id);
98 chrome.test.assertTrue(cw1 === win1);
99 chrome.test.assertTrue(cw2 === win2);
100 chrome.test.assertFalse(cw1 === cw2);
101 win1.contentWindow.close();
102 win2.contentWindow.close();
107 function contentSize() {
108 chrome.app.window.create('test.html',
109 { bounds: { width: 250, height: 200 } }, callbackPass(function(win) {
110 assertFuzzyEq(250, win.contentWindow.innerWidth, defaultFuzzFactor);
111 assertFuzzyEq(200, win.contentWindow.innerHeight, defaultFuzzFactor);
117 chrome.app.window.create('test.html', {
118 bounds: { width: 250, height: 250 },
119 minWidth: 400, minHeight: 450
120 }, callbackPass(function(win) {
121 var w = win.contentWindow;
122 assertFuzzyEq(400, w.innerWidth, defaultFuzzFactor);
123 assertFuzzyEq(450, w.innerHeight, defaultFuzzFactor);
129 chrome.app.window.create('test.html', {
130 bounds: { width: 250, height: 250 },
131 maxWidth: 200, maxHeight: 150
132 }, callbackPass(function(win) {
133 var w = win.contentWindow;
134 assertFuzzyEq(200, w.innerWidth, defaultFuzzFactor);
135 assertFuzzyEq(150, w.innerHeight, defaultFuzzFactor);
140 function minAndMaxSize() {
141 chrome.app.window.create('test.html', {
142 bounds: { width: 250, height: 250 },
143 minWidth: 400, minHeight: 450,
144 maxWidth: 200, maxHeight: 150
145 }, callbackPass(function(win) {
146 var w = win.contentWindow;
147 assertFuzzyEq(400, w.innerWidth, defaultFuzzFactor);
148 assertFuzzyEq(450, w.innerHeight, defaultFuzzFactor);
155 function testSingleton() {
156 chrome.test.runTests([
157 function noParameterWithId() {
158 chrome.app.window.create(
159 'test.html', { id: 'singleton-id' },
160 callbackPass(function(win) {
161 var w = win.contentWindow;
163 chrome.app.window.create(
164 'test.html', { id: 'singleton-id' },
165 callbackPass(function(win) {
166 var w2 = win.contentWindow;
167 chrome.test.assertTrue(w === w2);
179 function testBounds() {
180 chrome.test.runTests([
181 function simpleSetBounds() {
182 chrome.app.window.create('test.html',
183 { bounds: { width: 250, height: 200 } }, callbackPass(function(win) {
184 var b = win.getBounds();
185 win.setBounds({width: 400, height: 450})
186 // Listen to onresize here rather than win.onBoundsChanged, because
187 // onBoundsChanged is fired before the web contents are resized.
188 win.contentWindow.onresize = callbackPass(function() {
189 assertFuzzyEq(400, win.contentWindow.innerWidth, defaultFuzzFactor);
190 assertFuzzyEq(450, win.contentWindow.innerHeight, defaultFuzzFactor);
196 function heightOnlySetBounds() {
197 chrome.app.window.create('test.html', {
198 bounds: { width: 512, height: 256 }
199 }, callbackPass(function(win) {
200 win.setBounds({ height: 512 });
201 win.contentWindow.onresize = callbackPass(function() {
202 assertFuzzyEq(512, win.contentWindow.innerHeight, defaultFuzzFactor);
210 function testCloseEvent() {
211 chrome.test.runTests([
213 chrome.app.window.create('test.html', callbackPass(function(win) {
214 win.onClosed.addListener(callbackPass(function() {
215 // Mission accomplished.
217 win.contentWindow.close();
223 function testMaximize() {
224 chrome.test.runTests([
226 chrome.app.window.create('test.html',
227 { bounds: {width: 200, height: 200} },
228 callbackPass(function(win) {
229 // TODO(mlamouri): we should be able to use onMaximized here but to
230 // make that happen we need to make sure the event is not fired when
231 // .maximize() is called but when the maximizing is finished.
232 // See crbug.com/316091
233 function isWindowMaximized() {
234 return win.contentWindow.outerHeight == screen.availHeight &&
235 win.contentWindow.outerWidth == screen.availWidth;
238 eventLoopCheck(isWindowMaximized, function() {
247 function nonResizableWindow() {
248 chrome.app.window.create('test.html',
249 { bounds: {width: 200, height: 200},
251 callbackPass(function(win) {
252 // TODO(mlamouri): we should be able to use onMaximized here but to
253 // make that happen we need to make sure the event is not fired when
254 // .maximize() is called but when the maximizing is finished.
255 // See crbug.com/316091
256 function isWindowMaximized() {
257 return win.contentWindow.outerHeight == screen.availHeight &&
258 win.contentWindow.outerWidth == screen.availWidth;
261 eventLoopCheck(isWindowMaximized, function() {
272 function testRestore() {
273 chrome.test.runTests([
275 chrome.app.window.create('test.html',
276 { bounds: {width: 200, height: 200} },
277 callbackPass(function(win) {
278 var oldWidth = win.contentWindow.innerWidth;
279 var oldHeight = win.contentWindow.innerHeight;
281 // TODO(mlamouri): we should be able to use onMaximized here but to
282 // make that happen we need to make sure the event is not fired when
283 // .maximize() is called but when the maximizing is finished.
284 // See crbug.com/316091
285 function isWindowMaximized() {
286 return win.contentWindow.outerHeight == screen.availHeight &&
287 win.contentWindow.outerWidth == screen.availWidth;
289 function isWindowRestored() {
290 return win.contentWindow.innerHeight == oldHeight &&
291 win.contentWindow.innerWidth == oldWidth;
294 eventLoopCheck(isWindowMaximized, function() {
295 eventLoopCheck(isWindowRestored, function() {
309 function testRestoreAfterClose() {
310 chrome.test.runTests([
311 function restoredBoundsLowerThanNewMinSize() {
312 chrome.app.window.create('test.html', {
313 bounds: { width: 100, height: 150 },
314 minWidth: 200, minHeight: 250,
315 maxWidth: 200, maxHeight: 250,
317 }, callbackPass(function(win) {
318 var w = win.contentWindow;
319 assertFuzzyEq(200, w.innerWidth, defaultFuzzFactor);
320 assertFuzzyEq(250, w.innerHeight, defaultFuzzFactor);
322 win.onClosed.addListener(callbackPass(function() {
323 chrome.app.window.create('test.html', {
324 bounds: { width: 500, height: 550 },
325 minWidth: 400, minHeight: 450,
326 maxWidth: 600, maxHeight: 650,
328 }, callbackPass(function(win) {
329 var w = win.contentWindow;
330 assertFuzzyEq(400, w.innerWidth, defaultFuzzFactor);
331 assertFuzzyEq(450, w.innerHeight, defaultFuzzFactor);
342 function testRestoreAfterGeometryCacheChange() {
343 chrome.test.runTests([
344 function restorePositionAndSize() {
345 chrome.app.window.create('test.html', {
346 bounds: { left: 200, top: 200, width: 200, height: 200 }, id: 'test-ra',
347 }, callbackPass(function(win) { waitForLoad(win, function(win) {
348 var w = win.contentWindow;
349 // The fuzzy factor here is related to the fact that depending on the
350 // platform, the bounds initialization will set the inner bounds or the
352 // TODO(mlamouri): remove the fuzz factor.
353 assertFuzzyEq(200, w.screenX, 5);
354 assertFuzzyEq(200, w.screenY, 30);
355 chrome.test.assertEq(200, w.innerHeight);
356 chrome.test.assertEq(200, w.innerWidth);
358 w.resizeTo(300, 300);
361 chrome.app.window.create('test.html', {
362 bounds: { left: 200, top: 200, width: 200, height: 200 },
363 id: 'test-rb', frame: 'none'
364 }, callbackPass(function(win2) { waitForLoad(win2, function(win2) {
365 var w2 = win2.contentWindow;
366 chrome.test.assertEq(200, w2.screenX);
367 chrome.test.assertEq(200, w2.screenY);
368 chrome.test.assertEq(200, w2.innerWidth);
369 chrome.test.assertEq(200, w2.innerHeight);
371 w2.resizeTo(100, 100);
374 chrome.test.sendMessage('ListenGeometryChange', function(reply) {
375 win.onClosed.addListener(callbackPass(function() {
376 chrome.app.window.create('test.html', {
378 }, callbackPass(function(win) { waitForLoad(win, function(win) {
379 var w = win.contentWindow;
380 chrome.test.assertEq(100, w.screenX);
381 chrome.test.assertEq(100, w.screenY);
382 chrome.test.assertEq(300, w.outerWidth);
383 chrome.test.assertEq(300, w.outerHeight);
387 win2.onClosed.addListener(callbackPass(function() {
388 chrome.app.window.create('test.html', {
389 id: 'test-rb', frame: 'none'
390 },callbackPass(function(win2) { waitForLoad(win2, function(win2) {
391 var w = win2.contentWindow;
392 chrome.test.assertEq(300, w.screenX);
393 chrome.test.assertEq(300, w.screenY);
394 chrome.test.assertEq(100, w.outerWidth);
395 chrome.test.assertEq(100, w.outerHeight);
408 function testSizeConstraints() {
409 chrome.test.runTests([
410 function testUndefinedMinAndMaxSize() {
411 chrome.app.window.create('test.html', {
412 bounds: { width: 250, height: 250 }
413 }, callbackPass(function(win) {
414 chrome.test.assertEq(undefined, win.getMinWidth());
415 chrome.test.assertEq(undefined, win.getMinHeight());
416 chrome.test.assertEq(undefined, win.getMaxWidth());
417 chrome.test.assertEq(undefined, win.getMaxHeight());
422 function testSetUndefinedMinAndMaxSize() {
423 chrome.app.window.create('test.html', {
424 bounds: { width: 102, height: 103 },
425 minWidth: 100, minHeight: 101,
426 maxWidth: 104, maxHeight: 105
427 }, callbackPass(function(win) {
428 chrome.test.assertEq(100, win.getMinWidth());
429 chrome.test.assertEq(101, win.getMinHeight());
430 chrome.test.assertEq(104, win.getMaxWidth());
431 chrome.test.assertEq(105, win.getMaxHeight());
432 win.setMinWidth(null);
433 win.setMinHeight(null);
434 win.setMaxWidth(null);
435 win.setMaxHeight(null);
436 win.setBounds({ width: 103, height: 102 });
438 win.contentWindow.onresize = callbackPass(function() {
439 chrome.test.assertEq(undefined, win.getMinWidth());
440 chrome.test.assertEq(undefined, win.getMinHeight());
441 chrome.test.assertEq(undefined, win.getMaxWidth());
442 chrome.test.assertEq(undefined, win.getMaxHeight());
448 function testChangingMinAndMaxSize() {
449 chrome.app.window.create('test.html', {
450 bounds: { width: 102, height: 103 },
451 minWidth: 100, minHeight: 101,
452 maxWidth: 104, maxHeight: 105
453 }, callbackPass(function(win) {
454 chrome.test.assertEq(100, win.getMinWidth());
455 chrome.test.assertEq(101, win.getMinHeight());
456 chrome.test.assertEq(104, win.getMaxWidth());
457 chrome.test.assertEq(105, win.getMaxHeight());
459 win.setMinHeight(99);
460 win.setMaxWidth(106);
461 win.setMaxHeight(107);
462 win.setBounds({ width: 103, height: 102 });
464 win.contentWindow.onresize = callbackPass(function() {
465 chrome.test.assertEq(98, win.getMinWidth());
466 chrome.test.assertEq(99, win.getMinHeight());
467 chrome.test.assertEq(106, win.getMaxWidth());
468 chrome.test.assertEq(107, win.getMaxHeight());
474 function testMinWidthLargerThanMaxWidth() {
475 chrome.app.window.create('test.html', {
476 bounds: { width: 102, height: 103 },
477 minWidth: 100, minHeight: 101,
478 maxWidth: 104, maxHeight: 105
479 }, callbackPass(function(win) {
480 win.setMinWidth(200);
481 win.contentWindow.onresize = callbackPass(function() {
482 chrome.test.assertEq(200, win.getMinWidth());
483 chrome.test.assertEq(101, win.getMinHeight());
484 chrome.test.assertEq(200, win.getMaxWidth());
485 chrome.test.assertEq(105, win.getMaxHeight());
491 function testMinHeightLargerThanMaxHeight() {
492 chrome.app.window.create('test.html', {
493 bounds: { width: 102, height: 103 },
494 minWidth: 100, minHeight: 101,
495 maxWidth: 104, maxHeight: 105
496 }, callbackPass(function(win) {
497 win.setMinHeight(200);
499 win.contentWindow.onresize = callbackPass(function() {
500 chrome.test.assertEq(100, win.getMinWidth());
501 chrome.test.assertEq(200, win.getMinHeight());
502 chrome.test.assertEq(104, win.getMaxWidth());
503 chrome.test.assertEq(200, win.getMaxHeight());
509 function testMaxWidthSmallerThanMinWidth() {
510 chrome.app.window.create('test.html', {
511 bounds: { width: 102, height: 103 },
512 minWidth: 100, minHeight: 101,
513 maxWidth: 104, maxHeight: 105
514 }, callbackPass(function(win) {
517 win.contentWindow.onresize = callbackPass(function() {
518 chrome.test.assertEq(100, win.getMinWidth());
519 chrome.test.assertEq(101, win.getMinHeight());
520 chrome.test.assertEq(100, win.getMaxWidth());
521 chrome.test.assertEq(105, win.getMaxHeight());
527 function testMaxHeightSmallerThanMinHeight() {
528 chrome.app.window.create('test.html', {
529 bounds: { width: 102, height: 103 },
530 minWidth: 100, minHeight: 101,
531 maxWidth: 104, maxHeight: 105
532 }, callbackPass(function(win) {
533 win.setMaxHeight(50);
535 win.contentWindow.onresize = callbackPass(function() {
536 chrome.test.assertEq(100, win.getMinWidth());
537 chrome.test.assertEq(101, win.getMinHeight());
538 chrome.test.assertEq(104, win.getMaxWidth());
539 chrome.test.assertEq(101, win.getMaxHeight());
547 function testBadging() {
548 chrome.test.runTests([
549 function testSettingAndClearingBadge() {
550 chrome.app.window.create('test.html', callbackPass(function(win) {
551 win.setBadgeIcon('square.png');
553 win.setBadgeIcon('non_square.png');
555 chrome.test.sendMessage(
556 'WaitForRoundTrip', callbackPass(function(reply) {}));
562 chrome.app.runtime.onLaunched.addListener(function() {
563 chrome.test.sendMessage('Launched', function(reply) {