14396a3dfbfbd83855a38b401e53390c9da3c709
[platform/framework/web/crosswalk.git] / src / chrome / test / data / extensions / platform_apps / window_api / test.js
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.
4
5 var callbackPass = chrome.test.callbackPass;
6 var callbackFail = chrome.test.callbackFail;
7 var defaultFuzzFactor = 1;
8
9 function assertFuzzyEq(expected, actual, fuzzFactor, message) {
10   if (!message) {
11     message = "Expected: " + expected + "; actual: " + actual + "; "
12                + "fuzzyFactor: " + fuzzFactor;
13   }
14
15   chrome.test.assertTrue(actual - fuzzFactor <= expected
16                          && actual + fuzzFactor >= expected, message);
17
18   if (actual != expected) {
19     console.log("FUZZ: a factor of " + Math.abs(actual - expected) +
20                 "has been used.");
21   }
22 }
23
24 // This helper will verify that |check| returns true. If it does not, it will do
25 // a trip to the event loop and will try again until |check| returns true. At
26 // which points |callback| will be called.
27 // NOTE: if the test fails, it will timeout.
28 function eventLoopCheck(check, callback) {
29   if (check()) {
30     callback();
31   } else {
32     setTimeout(callbackPass(function() { eventLoopCheck(check, callback); }));
33   }
34 }
35
36 // This help function will call the callback when the window passed to it will
37 // be loaded. The callback will have the AppWindow passed as a parameter.
38 function waitForLoad(win, callback) {
39   var window = win.contentWindow;
40
41   if (window.document.readyState == 'complete') {
42     callback(win);
43     return;
44   }
45
46   window.addEventListener('load', callbackPass(function() {
47     window.removeEventListener('load', arguments.callee);
48     callback(win);
49   }));
50 }
51
52 function assertConstraintsUnspecified(win) {
53   chrome.test.assertEq(null, win.innerBounds.minWidth);
54   chrome.test.assertEq(null, win.innerBounds.minHeight);
55   chrome.test.assertEq(null, win.innerBounds.maxWidth);
56   chrome.test.assertEq(null, win.innerBounds.maxHeight);
57   chrome.test.assertEq(null, win.outerBounds.minWidth);
58   chrome.test.assertEq(null, win.outerBounds.minHeight);
59   chrome.test.assertEq(null, win.outerBounds.maxWidth);
60   chrome.test.assertEq(null, win.outerBounds.maxHeight);
61 }
62
63 function assertBoundsConsistent(win) {
64   // Ensure that the inner and outer bounds are consistent. Since platforms
65   // have different frame padding, we cannot check the sizes precisely.
66   // It is a reasonable assumption that all platforms will have a title bar at
67   // the top of the window.
68   chrome.test.assertTrue(win.innerBounds.left >= win.outerBounds.left);
69   chrome.test.assertTrue(win.innerBounds.top > win.outerBounds.top);
70   chrome.test.assertTrue(win.innerBounds.width <= win.outerBounds.width);
71   chrome.test.assertTrue(win.innerBounds.height < win.outerBounds.height);
72
73   if (win.innerBounds.minWidth === null)
74     chrome.test.assertEq(null, win.outerBounds.minWidth);
75   else
76     chrome.test.assertTrue(
77         win.innerBounds.minWidth <= win.outerBounds.minWidth);
78
79   if (win.innerBounds.minHeight === null)
80     chrome.test.assertEq(null, win.outerBounds.minHeight);
81   else
82     chrome.test.assertTrue(
83         win.innerBounds.minHeight < win.outerBounds.minHeight);
84
85   if (win.innerBounds.maxWidth === null)
86     chrome.test.assertEq(null, win.outerBounds.maxWidth);
87   else
88     chrome.test.assertTrue(
89         win.innerBounds.maxWidth <= win.outerBounds.maxWidth);
90
91   if (win.innerBounds.maxHeight === null)
92     chrome.test.assertEq(null, win.outerBounds.maxHeight);
93   else
94     chrome.test.assertTrue(
95         win.innerBounds.maxHeight < win.outerBounds.maxHeight);
96 }
97
98 function testConflictingBoundsProperty(propertyName) {
99   var innerBounds = {};
100   var outerBounds = {};
101   innerBounds[propertyName] = 20;
102   outerBounds[propertyName] = 20;
103   chrome.app.window.create('test.html', {
104     innerBounds: innerBounds,
105     outerBounds: outerBounds
106   }, callbackFail('The ' + propertyName + ' property cannot be specified for ' +
107                   'both inner and outer bounds.')
108   );
109 }
110
111 function assertBoundsEq(expectedBounds, actualBounds) {
112   chrome.test.assertEq(expectedBounds.left, actualBounds.left);
113   chrome.test.assertEq(expectedBounds.top, actualBounds.top);
114   chrome.test.assertEq(expectedBounds.width, actualBounds.width);
115   chrome.test.assertEq(expectedBounds.height, actualBounds.height);
116 }
117
118 function assertConstraintsEq(expectedConstraints, actualConstraints) {
119   chrome.test.assertEq(expectedConstraints.minWidth,
120                        actualConstraints.minWidth);
121   chrome.test.assertEq(expectedConstraints.minHeight,
122                        actualConstraints.minHeight);
123   chrome.test.assertEq(expectedConstraints.maxWidth,
124                        actualConstraints.maxWidth);
125   chrome.test.assertEq(expectedConstraints.maxHeight,
126                        actualConstraints.maxHeight);
127 }
128
129 function runSetBoundsTest(boundsType, initialState, changeFields,
130                           expectedBounds, hasConstraints) {
131   var createOptions = {};
132   createOptions[boundsType] = initialState;
133   chrome.app.window.create('test.html', createOptions, callbackPass(
134   function(win) {
135     // Change the bounds.
136     if (typeof(changeFields.left) !== 'undefined' &&
137         typeof(changeFields.top) !== 'undefined') {
138       win[boundsType].setPosition(changeFields.left, changeFields.top);
139     } else if (typeof(changeFields.left) !== 'undefined')
140       win[boundsType].left = changeFields.left;
141     else if (typeof(changeFields.top) !== 'undefined')
142       win[boundsType].top = changeFields.top;
143
144     if (typeof(changeFields.width) !== 'undefined' &&
145         typeof(changeFields.height) !== 'undefined') {
146       win[boundsType].setSize(changeFields.width, changeFields.height);
147     } else if (typeof(changeFields.width) !== 'undefined')
148       win[boundsType].width = changeFields.width;
149     else if (typeof(changeFields.height) !== 'undefined')
150       win[boundsType].height = changeFields.height;
151
152     // Dummy call to wait for bounds to be changed in the browser.
153     chrome.test.waitForRoundTrip('msg', callbackPass(function(msg) {
154       assertBoundsConsistent(win);
155       assertBoundsEq(expectedBounds, win[boundsType]);
156       if (!hasConstraints)
157         assertConstraintsUnspecified(win);
158       win.close();
159     }));
160   }));
161 }
162
163 function runSetConstraintsTest(boundsType, initialState, changeFields,
164                                expectedConstraints, expectedBounds) {
165   var createOptions = {};
166   createOptions[boundsType] = initialState;
167   chrome.app.window.create('test.html', createOptions, callbackPass(
168   function(win) {
169     assertConstraintsEq(initialState, win[boundsType]);
170
171     // Change the constraints.
172     if (typeof(changeFields.minWidth) !== 'undefined' &&
173         typeof(changeFields.minHeight) !== 'undefined') {
174       win[boundsType].setMinimumSize(changeFields.minWidth,
175                                      changeFields.minHeight);
176     } else if (typeof(changeFields.minWidth) !== 'undefined')
177       win[boundsType].minWidth = changeFields.minWidth;
178     else if (typeof(changeFields.minHeight) !== 'undefined')
179       win[boundsType].minHeight = changeFields.minHeight;
180
181     if (typeof(changeFields.maxWidth) !== 'undefined' &&
182         typeof(changeFields.maxHeight) !== 'undefined') {
183       win[boundsType].setMaximumSize(changeFields.maxWidth,
184                                      changeFields.maxHeight);
185     } else if (typeof(changeFields.maxWidth) !== 'undefined')
186       win[boundsType].maxWidth = changeFields.maxWidth;
187     else if (typeof(changeFields.maxHeight) !== 'undefined')
188       win[boundsType].maxHeight = changeFields.maxHeight;
189
190     // Dummy call to wait for the constraints to be changed in the browser.
191     chrome.test.waitForRoundTrip('msg', callbackPass(function(msg) {
192       assertBoundsConsistent(win);
193       assertConstraintsEq(expectedConstraints, win[boundsType]);
194       if (expectedBounds) {
195         chrome.test.assertEq(expectedBounds.width, win[boundsType].width);
196         chrome.test.assertEq(expectedBounds.height, win[boundsType].height);
197       }
198       win.close();
199     }));
200   }));
201 }
202
203 function testCreate() {
204   chrome.test.runTests([
205     function basic() {
206       chrome.app.window.create('test.html',
207                                {id: 'testId'},
208                                callbackPass(function(win) {
209         chrome.test.assertEq(typeof win.contentWindow.window, 'object');
210         chrome.test.assertTrue(
211           typeof win.contentWindow.document !== 'undefined');
212         chrome.test.assertFalse(
213           'about:blank' === win.contentWindow.location.href);
214         var cw = win.contentWindow.chrome.app.window.current();
215         chrome.test.assertEq(cw, win);
216         chrome.test.assertEq('testId', cw.id);
217         win.contentWindow.close();
218       }))
219     },
220
221     function badWindow() {
222       chrome.app.window.create('404.html', callbackPass(function(win) {
223         chrome.test.assertTrue(typeof win === 'undefined');
224         // TODO(mlamouri): because |win| is not defined, we can not close that
225         // window...
226       }));
227     },
228
229     function loadEvent() {
230       chrome.app.window.create('test.html', callbackPass(function(win) {
231         win.contentWindow.onload = callbackPass(function() {
232           chrome.test.assertEq(document.readyState, 'complete');
233           win.contentWindow.close();
234         });
235       }));
236     },
237
238     function multiWindow() {
239       chrome.test.assertTrue(null === chrome.app.window.current());
240       chrome.app.window.create('test.html',
241                                {id: 'testId1'},
242                                callbackPass(function(win1) {
243         chrome.app.window.create('test.html',
244                                  {id: 'testId2'},
245                                  callbackPass(function(win2) {
246           var cw1 = win1.contentWindow.chrome.app.window.current();
247           var cw2 = win2.contentWindow.chrome.app.window.current();
248           chrome.test.assertEq('testId1', cw1.id);
249           chrome.test.assertEq('testId2', cw2.id);
250           chrome.test.assertTrue(cw1 === win1);
251           chrome.test.assertTrue(cw2 === win2);
252           chrome.test.assertFalse(cw1 === cw2);
253           win1.contentWindow.close();
254           win2.contentWindow.close();
255         }));
256       }));
257     }
258   ]);
259 }
260
261 function testDeprecatedBounds() {
262   chrome.test.runTests([
263     function contentSize() {
264       var options = { bounds: { left: 0, top: 0, width: 250, height: 200 } };
265       chrome.app.window.create('test.html', options, callbackPass(
266       function(win) {
267         var bounds = win.getBounds();
268         chrome.test.assertEq(options.bounds.width, bounds.width);
269         chrome.test.assertEq(options.bounds.height, bounds.height);
270         chrome.test.assertEq(options.bounds.width, win.innerBounds.width);
271         chrome.test.assertEq(options.bounds.height, win.innerBounds.height);
272         win.close();
273       }));
274     },
275
276     function windowPosition() {
277       var options = { bounds: { left: 0, top: 0, left: 250, top: 200 } };
278       chrome.app.window.create('test.html', options, callbackPass(
279       function(win) {
280         var bounds = win.getBounds();
281         chrome.test.assertEq(options.bounds.left, bounds.left);
282         chrome.test.assertEq(options.bounds.top, bounds.top);
283         chrome.test.assertEq(options.bounds.left, win.outerBounds.left);
284         chrome.test.assertEq(options.bounds.top, win.outerBounds.top);
285         win.close();
286       }));
287     },
288
289     function minSize() {
290       var options = {
291         bounds: { left: 0, top: 0, width: 250, height: 250 },
292         minWidth: 400, minHeight: 450
293       };
294       chrome.app.window.create('test.html', options, callbackPass(
295       function(win) {
296         var bounds = win.getBounds();
297         chrome.test.assertEq(options.minWidth, bounds.width);
298         chrome.test.assertEq(options.minHeight, bounds.height);
299         win.close();
300       }));
301     },
302
303     function maxSize() {
304       var options = {
305         bounds: { left: 0, top: 0, width: 250, height: 250 },
306         maxWidth: 200, maxHeight: 150
307       };
308       chrome.app.window.create('test.html', options, callbackPass(
309       function(win) {
310         var bounds = win.getBounds();
311         chrome.test.assertEq(options.maxWidth, bounds.width);
312         chrome.test.assertEq(options.maxHeight, bounds.height);
313         win.close();
314       }));
315     },
316
317     function minAndMaxSize() {
318       var options = {
319         bounds: { left: 0, top: 0, width: 250, height: 250 },
320         minWidth: 400, minHeight: 450,
321         maxWidth: 200, maxHeight: 150
322       };
323       chrome.app.window.create('test.html', options, callbackPass(
324       function(win) {
325         var bounds = win.getBounds();
326         chrome.test.assertEq(options.minWidth, bounds.width);
327         chrome.test.assertEq(options.minHeight, bounds.height);
328         win.close();
329       }));
330     },
331
332     function simpleSetBounds() {
333       chrome.app.window.create('test.html', {
334         bounds: { left: 0, top: 0, width: 250, height: 200 }
335       }, callbackPass(function(win) {
336         var newBounds = {width: 400, height: 450};
337         win.setBounds(newBounds);
338         chrome.test.waitForRoundTrip('msg', callbackPass(function() {
339           var bounds = win.getBounds();
340           chrome.test.assertEq(newBounds.width, bounds.width);
341           chrome.test.assertEq(newBounds.height, bounds.height);
342           win.close();
343         }));
344       }));
345     },
346
347     function heightOnlySetBounds() {
348       chrome.app.window.create('test.html', {
349         bounds: { left: 0, top: 0, width: 300, height: 256 }
350       }, callbackPass(function(win) {
351         win.setBounds({ height: 300 });
352         chrome.test.waitForRoundTrip('msg', callbackPass(function() {
353           var bounds = win.getBounds();
354           chrome.test.assertEq(300, bounds.width);
355           chrome.test.assertEq(300, bounds.height);
356           win.close();
357         }));
358       }));
359     },
360   ]);
361 }
362
363 function testInitialBounds() {
364   chrome.test.runTests([
365     function testNoOptions() {
366       chrome.app.window.create('test.html', {
367       }, callbackPass(function(win) {
368         chrome.test.assertTrue(win != null);
369         chrome.test.assertTrue(win.innerBounds.width > 0);
370         chrome.test.assertTrue(win.innerBounds.height > 0);
371         chrome.test.assertTrue(win.outerBounds.width > 0);
372         chrome.test.assertTrue(win.outerBounds.height > 0);
373         assertConstraintsUnspecified(win);
374         assertBoundsConsistent(win);
375         win.close();
376       }));
377     },
378
379     function testInnerBoundsOnly() {
380       var innerBounds = {
381         left: 150,
382         top: 100,
383         width: 400,
384         height: 300
385       };
386       chrome.app.window.create('test.html', {
387         innerBounds: innerBounds
388       }, callbackPass(function(win) {
389         chrome.test.assertTrue(win != null);
390         assertBoundsEq(innerBounds, win.innerBounds);
391         assertBoundsConsistent(win);
392         assertConstraintsUnspecified(win);
393         win.close();
394       }));
395     },
396
397     function testOuterBoundsOnly() {
398       var outerBounds = {
399         left: 150,
400         top: 100,
401         width: 400,
402         height: 300
403       };
404       chrome.app.window.create('test.html', {
405         outerBounds: outerBounds
406       }, callbackPass(function(win) {
407         chrome.test.assertTrue(win != null);
408         assertBoundsEq(outerBounds, win.outerBounds);
409         assertBoundsConsistent(win);
410         assertConstraintsUnspecified(win);
411         win.close();
412       }));
413     },
414
415     function testFrameless() {
416       var outerBounds = {
417         left: 150,
418         top: 100,
419         width: 400,
420         height: 300
421       };
422       chrome.app.window.create('test.html', {
423         outerBounds: outerBounds,
424         frame: 'none'
425       }, callbackPass(function(win) {
426         chrome.test.assertTrue(win != null);
427         assertBoundsEq(outerBounds, win.outerBounds);
428         assertBoundsEq(outerBounds, win.innerBounds);
429         assertConstraintsUnspecified(win);
430         win.close();
431       }));
432     },
433
434     function testInnerSizeAndOuterPos() {
435       var innerBounds = {
436         width: 400,
437         height: 300
438       };
439       var outerBounds = {
440         left: 150,
441         top: 100
442       };
443       chrome.app.window.create('test.html', {
444         innerBounds: innerBounds,
445         outerBounds: outerBounds
446       }, callbackPass(function(win) {
447         chrome.test.assertTrue(win != null);
448         chrome.test.assertEq(outerBounds.left, win.outerBounds.left);
449         chrome.test.assertEq(outerBounds.top, win.outerBounds.top);
450         chrome.test.assertEq(innerBounds.width, win.innerBounds.width);
451         chrome.test.assertEq(innerBounds.height, win.innerBounds.height);
452         assertBoundsConsistent(win);
453         assertConstraintsUnspecified(win);
454         win.close();
455       }));
456     },
457
458     function testInnerAndOuterBoundsEdgeCase() {
459       var innerBounds = {
460         left: 150,
461         height: 300
462       };
463       var outerBounds = {
464         width: 400,
465         top: 100
466       };
467       chrome.app.window.create('test.html', {
468         innerBounds: innerBounds,
469         outerBounds: outerBounds
470       }, callbackPass(function(win) {
471         chrome.test.assertTrue(win != null);
472         chrome.test.assertEq(innerBounds.left, win.innerBounds.left);
473         chrome.test.assertEq(innerBounds.height, win.innerBounds.height);
474         chrome.test.assertEq(outerBounds.top, win.outerBounds.top);
475         chrome.test.assertEq(outerBounds.width, win.outerBounds.width);
476         assertBoundsConsistent(win);
477         assertConstraintsUnspecified(win);
478         win.close();
479       }));
480     },
481
482     function testPositionOnly() {
483       var outerBounds = {
484         left: 150,
485         top: 100
486       };
487       chrome.app.window.create('test.html', {
488         outerBounds: outerBounds
489       }, callbackPass(function(win) {
490         chrome.test.assertTrue(win != null);
491         chrome.test.assertEq(outerBounds.left, win.outerBounds.left);
492         chrome.test.assertEq(outerBounds.top, win.outerBounds.top);
493         chrome.test.assertTrue(win.innerBounds.width > 0);
494         chrome.test.assertTrue(win.innerBounds.height > 0);
495         chrome.test.assertTrue(win.outerBounds.width > 0);
496         chrome.test.assertTrue(win.outerBounds.height > 0);
497         assertBoundsConsistent(win);
498         assertConstraintsUnspecified(win);
499         win.close();
500       }));
501     },
502
503     function testSizeOnly() {
504       var outerBounds = {
505         width: 500,
506         height: 400
507       };
508       chrome.app.window.create('test.html', {
509         outerBounds: outerBounds
510       }, callbackPass(function(win) {
511         chrome.test.assertTrue(win != null);
512         chrome.test.assertEq(outerBounds.width, win.outerBounds.width);
513         chrome.test.assertEq(outerBounds.height, win.outerBounds.height);
514         assertBoundsConsistent(win);
515         assertConstraintsUnspecified(win);
516         win.close();
517       }));
518     },
519
520     function testConflictingProperties() {
521       testConflictingBoundsProperty("width");
522       testConflictingBoundsProperty("height");
523       testConflictingBoundsProperty("left");
524       testConflictingBoundsProperty("top");
525       testConflictingBoundsProperty("minWidth");
526       testConflictingBoundsProperty("minHeight");
527       testConflictingBoundsProperty("maxWidth");
528       testConflictingBoundsProperty("maxHeight");
529     }
530   ]);
531 }
532
533 function testInitialConstraints() {
534   chrome.test.runTests([
535     function testMaxInnerConstraints() {
536       var innerBounds = {
537         width: 800,
538         height: 600,
539         maxWidth: 500,
540         maxHeight: 400
541       };
542       chrome.app.window.create('test.html', {
543         innerBounds: innerBounds
544       }, callbackPass(function(win) {
545         chrome.test.assertTrue(win != null);
546         chrome.test.assertEq(innerBounds.maxWidth, win.innerBounds.width);
547         chrome.test.assertEq(innerBounds.maxHeight, win.innerBounds.height);
548         chrome.test.assertEq(innerBounds.maxWidth, win.innerBounds.maxWidth);
549         chrome.test.assertEq(innerBounds.maxHeight, win.innerBounds.maxHeight);
550         assertBoundsConsistent(win);
551         win.close();
552       }));
553     },
554
555     function testMinInnerConstraints() {
556       var innerBounds = {
557         width: 100,
558         height: 100,
559         minWidth: 300,
560         minHeight: 200
561       };
562       chrome.app.window.create('test.html', {
563         innerBounds: innerBounds
564       }, callbackPass(function(win) {
565         chrome.test.assertTrue(win != null);
566         chrome.test.assertEq(innerBounds.minWidth, win.innerBounds.width);
567         chrome.test.assertEq(innerBounds.minHeight, win.innerBounds.height);
568         chrome.test.assertEq(innerBounds.minWidth, win.innerBounds.minWidth);
569         chrome.test.assertEq(innerBounds.minHeight, win.innerBounds.minHeight);
570         assertBoundsConsistent(win);
571         win.close();
572       }));
573     },
574
575     function testMaxOuterConstraints() {
576       var outerBounds = {
577         width: 800,
578         height: 600,
579         maxWidth: 500,
580         maxHeight: 400
581       };
582       chrome.app.window.create('test.html', {
583         outerBounds: outerBounds
584       }, callbackPass(function(win) {
585         chrome.test.assertTrue(win != null);
586         chrome.test.assertEq(outerBounds.maxWidth, win.outerBounds.width);
587         chrome.test.assertEq(outerBounds.maxHeight, win.outerBounds.height);
588         chrome.test.assertEq(outerBounds.maxWidth, win.outerBounds.maxWidth);
589         chrome.test.assertEq(outerBounds.maxHeight, win.outerBounds.maxHeight);
590         assertBoundsConsistent(win);
591         win.close();
592       }));
593     },
594
595     function testMinOuterConstraints() {
596       var outerBounds = {
597         width: 100,
598         height: 100,
599         minWidth: 300,
600         minHeight: 200
601       };
602       chrome.app.window.create('test.html', {
603         outerBounds: outerBounds
604       }, callbackPass(function(win) {
605         chrome.test.assertTrue(win != null);
606         chrome.test.assertEq(outerBounds.minWidth, win.outerBounds.width);
607         chrome.test.assertEq(outerBounds.minHeight, win.outerBounds.height);
608         chrome.test.assertEq(outerBounds.minWidth, win.outerBounds.minWidth);
609         chrome.test.assertEq(outerBounds.minHeight, win.outerBounds.minHeight);
610         assertBoundsConsistent(win);
611         win.close();
612       }));
613     },
614
615     function testMixedConstraints() {
616       var innerBounds = {
617         width: 100,
618         minHeight: 300
619       };
620       var outerBounds = {
621         height: 100,
622         minWidth: 400,
623       };
624       chrome.app.window.create('test.html', {
625         innerBounds: innerBounds,
626         outerBounds: outerBounds
627       }, callbackPass(function(win) {
628         chrome.test.assertTrue(win != null);
629         chrome.test.assertEq(outerBounds.minWidth, win.outerBounds.width);
630         chrome.test.assertEq(innerBounds.minHeight, win.innerBounds.height);
631         chrome.test.assertEq(outerBounds.minWidth, win.outerBounds.minWidth);
632         chrome.test.assertEq(innerBounds.minHeight, win.innerBounds.minHeight);
633         assertBoundsConsistent(win);
634         win.close();
635       }));
636     },
637
638     function testBadConstraints() {
639       var outerBounds = {
640         width: 500,
641         height: 400,
642         minWidth: 800,
643         minHeight: 700,
644         maxWidth: 300,
645         maxHeight: 200
646       };
647       chrome.app.window.create('test.html', {
648         outerBounds: outerBounds
649       }, callbackPass(function(win) {
650         chrome.test.assertTrue(win != null);
651         chrome.test.assertEq(outerBounds.minWidth, win.outerBounds.width);
652         chrome.test.assertEq(outerBounds.minHeight, win.outerBounds.height);
653         chrome.test.assertEq(outerBounds.minWidth, win.outerBounds.minWidth);
654         chrome.test.assertEq(outerBounds.minHeight, win.outerBounds.minHeight);
655         chrome.test.assertEq(outerBounds.minWidth, win.outerBounds.maxWidth);
656         chrome.test.assertEq(outerBounds.minHeight, win.outerBounds.maxHeight);
657         assertBoundsConsistent(win);
658         win.close();
659       }));
660     },
661
662     function testFrameless() {
663       var outerBounds = {
664         minWidth: 50,
665         minHeight: 50,
666         maxWidth: 800,
667         maxHeight: 800
668       };
669       chrome.app.window.create('test.html', {
670         outerBounds: outerBounds,
671         frame: 'none'
672       }, callbackPass(function(win) {
673         chrome.test.assertTrue(win != null);
674         assertConstraintsEq(outerBounds, win.outerBounds);
675         assertConstraintsEq(outerBounds, win.innerBounds);
676         win.close();
677       }));
678     }
679   ]);
680 }
681
682 function testSetBounds() {
683   chrome.test.runTests([
684     function testLeft() {
685       var init = { left: 150, top: 100, width: 300, height: 200 };
686       var change = { left: 189 };
687       var expected = { left: 189, top: 100, width: 300, height: 200 };
688       runSetBoundsTest('innerBounds', init, change, expected);
689       runSetBoundsTest('outerBounds', init, change, expected);
690     },
691
692     function testLeftNull() {
693       var init = { left: 150, top: 100, width: 300, height: 200 };
694       var change = { left: null };
695       runSetBoundsTest('innerBounds', init, change, init);
696       runSetBoundsTest('outerBounds', init, change, init);
697     },
698
699     function testTop() {
700       var init = { left: 150, top: 100, width: 300, height: 200 };
701       var change = { top: 167 };
702       var expected = { left: 150, top: 167, width: 300, height: 200 };
703       runSetBoundsTest('innerBounds', init, change, expected);
704       runSetBoundsTest('outerBounds', init, change, expected);
705     },
706
707     function testTopNull() {
708       var init = { left: 150, top: 100, width: 300, height: 200 };
709       var change = { top: null };
710       runSetBoundsTest('innerBounds', init, change, init);
711       runSetBoundsTest('outerBounds', init, change, init);
712     },
713
714     function testWidth() {
715       var init = { left: 150, top: 100, width: 300, height: 200 };
716       var change = { width: 245 };
717       var expected = { left: 150, top: 100, width: 245, height: 200 };
718       runSetBoundsTest('innerBounds', init, change, expected);
719       runSetBoundsTest('outerBounds', init, change, expected);
720     },
721
722     function testWidthNull() {
723       var init = { left: 150, top: 100, width: 300, height: 200 };
724       var change = { width: null };
725       runSetBoundsTest('innerBounds', init, change, init);
726       runSetBoundsTest('outerBounds', init, change, init);
727     },
728
729     function testHeight() {
730       var init = { left: 150, top: 100, width: 300, height: 200 };
731       var change = { height: 196 };
732       var expected = { left: 150, top: 100, width: 300, height: 196 };
733       runSetBoundsTest('innerBounds', init, change, expected);
734       runSetBoundsTest('outerBounds', init, change, expected);
735     },
736
737     function testHeightNull() {
738       var init = { left: 150, top: 100, width: 300, height: 200 };
739       var change = { height: null };
740       runSetBoundsTest('innerBounds', init, change, init);
741       runSetBoundsTest('outerBounds', init, change, init);
742     },
743
744     function testPosition() {
745       var init = { left: 150, top: 100, width: 300, height: 200 };
746       var change = { left: 162, top: 112 };
747       var expected = { left: 162, top: 112, width: 300, height: 200 };
748       runSetBoundsTest('innerBounds', init, change, expected);
749       runSetBoundsTest('outerBounds', init, change, expected);
750     },
751
752     function testPositionNull() {
753       var init = { left: 150, top: 100, width: 300, height: 200 };
754       var change = { left: null, top: null };
755       runSetBoundsTest('innerBounds', init, change, init);
756       runSetBoundsTest('outerBounds', init, change, init);
757     },
758
759     function testSize() {
760       var init = { left: 150, top: 100, width: 300, height: 200 };
761       var change = { width: 306, height: 216 };
762       var expected = { left: 150, top: 100, width: 306, height: 216 };
763       runSetBoundsTest('innerBounds', init, change, expected);
764       runSetBoundsTest('outerBounds', init, change, expected);
765     },
766
767     function testSizeNull() {
768       var init = { left: 150, top: 100, width: 300, height: 200 };
769       var change = { width: null, height: null };
770       runSetBoundsTest('innerBounds', init, change, init);
771       runSetBoundsTest('outerBounds', init, change, init);
772     },
773
774     function testMinSize() {
775       var init = { left: 150, top: 100, width: 300, height: 200,
776                    minWidth: 235, minHeight: 170 };
777       var change = { width: 50, height: 60 };
778       var expected = { left: 150, top: 100, width: 235, height: 170 };
779       runSetBoundsTest('innerBounds', init, change, expected, true);
780       runSetBoundsTest('outerBounds', init, change, expected, true);
781     },
782
783     function testMaxSize() {
784       var init = { left: 150, top: 100, width: 300, height: 200,
785                    maxWidth: 330, maxHeight: 230 };
786       var change = { width: 400, height: 300 };
787       var expected = { left: 150, top: 100, width: 330, height: 230 };
788       runSetBoundsTest('innerBounds', init, change, expected, true);
789       runSetBoundsTest('outerBounds', init, change, expected, true);
790     },
791
792     function testMinAndMaxSize() {
793       var init = { left: 150, top: 100, width: 300, height: 200,
794                    minWidth: 120, minHeight: 170,
795                    maxWidth: 330, maxHeight: 230 };
796       var change = { width: 225, height: 195 };
797       var expected = { left: 150, top: 100, width: 225, height: 195 };
798       runSetBoundsTest('innerBounds', init, change, expected, true);
799       runSetBoundsTest('outerBounds', init, change, expected, true);
800     },
801   ]);
802 }
803
804 function testSetSizeConstraints() {
805   chrome.test.runTests([
806     function testMinWidth() {
807       var init = { minWidth: 300, minHeight: 200,
808                    maxWidth: 350, maxHeight: 250 };
809       var change = { minWidth: 111 };
810       var expected = { minWidth: 111, minHeight: 200,
811                        maxWidth: 350, maxHeight: 250 };
812       runSetConstraintsTest('innerBounds', init, change, expected);
813       runSetConstraintsTest('outerBounds', init, change, expected);
814     },
815
816     function testClearMinWidth() {
817       var init = { minWidth: 300, minHeight: 200,
818                    maxWidth: 350, maxHeight: 250 };
819       var change = { minWidth: null };
820       var expected = { minWidth: null, minHeight: 200,
821                        maxWidth: 350, maxHeight: 250 };
822       runSetConstraintsTest('innerBounds', init, change, expected);
823       runSetConstraintsTest('outerBounds', init, change, expected);
824     },
825
826     function testMaxWidth() {
827       var init = { minWidth: 300, minHeight: 200,
828                    maxWidth: 350, maxHeight: 250 };
829       var change = { maxWidth: 347 };
830       var expected = { minWidth: 300, minHeight: 200,
831                        maxWidth: 347, maxHeight: 250 };
832       runSetConstraintsTest('innerBounds', init, change, expected);
833       runSetConstraintsTest('outerBounds', init, change, expected);
834     },
835
836     function testClearMaxWidth() {
837       var init = { minWidth: 300, minHeight: 200,
838                    maxWidth: 350, maxHeight: 250 };
839       var change = { maxWidth: null };
840       var expected = { minWidth: 300, minHeight: 200,
841                        maxWidth: null, maxHeight: 250 };
842       runSetConstraintsTest('innerBounds', init, change, expected);
843       runSetConstraintsTest('outerBounds', init, change, expected);
844     },
845
846     function testMinHeight() {
847       var init = { minWidth: 300, minHeight: 200,
848                    maxWidth: 350, maxHeight: 250 };
849       var change = { minHeight: 198 };
850       var expected = { minWidth: 300, minHeight: 198,
851                        maxWidth: 350, maxHeight: 250 };
852       runSetConstraintsTest('innerBounds', init, change, expected);
853       runSetConstraintsTest('outerBounds', init, change, expected);
854     },
855
856     function testClearMinHeight() {
857       var init = { minWidth: 300, minHeight: 200,
858                    maxWidth: 350, maxHeight: 250 };
859       var change = { minHeight: null };
860       var expected = { minWidth: 300, minHeight: null,
861                        maxWidth: 350, maxHeight: 250 };
862       runSetConstraintsTest('innerBounds', init, change, expected);
863       runSetConstraintsTest('outerBounds', init, change, expected);
864     },
865
866     function testMaxHeight() {
867       var init = { minWidth: 300, minHeight: 200,
868                    maxWidth: 350, maxHeight: 250 };
869       var change = { maxHeight: 278 };
870       var expected = { minWidth: 300, minHeight: 200,
871                        maxWidth: 350, maxHeight: 278 };
872       runSetConstraintsTest('innerBounds', init, change, expected);
873       runSetConstraintsTest('outerBounds', init, change, expected);
874     },
875
876     function testClearMaxHeight() {
877       var init = { minWidth: 300, minHeight: 200,
878                    maxWidth: 350, maxHeight: 250 };
879       var change = { maxHeight: null };
880       var expected = { minWidth: 300, minHeight: 200,
881                        maxWidth: 350, maxHeight: null };
882       runSetConstraintsTest('innerBounds', init, change, expected);
883       runSetConstraintsTest('outerBounds', init, change, expected);
884     },
885
886     function testSetMinSize() {
887       // This test expects the bounds to be changed.
888       var init = { width: 225, height: 125,
889                    minWidth: null, minHeight: null,
890                    maxWidth: null, maxHeight: null };
891       var change = { minWidth: 235, minHeight: 135 };
892       var expected = { width: 235, height: 135,
893                        minWidth: 235, minHeight: 135,
894                        maxWidth: null, maxHeight: null };
895       runSetConstraintsTest('innerBounds', init, change, expected, expected);
896       runSetConstraintsTest('outerBounds', init, change, expected, expected);
897     },
898
899     function testSetMaxSize() {
900       // This test expects the bounds to be changed.
901       var init = { width: 225, height: 125,
902                    minWidth: null, minHeight: null,
903                    maxWidth: null, maxHeight: null };
904       var change = { maxWidth: 198, maxHeight: 107 };
905       var expected = { width: 198, height: 107,
906                        minWidth: null, minHeight: null,
907                        maxWidth: 198, maxHeight: 107 };
908       runSetConstraintsTest('innerBounds', init, change, expected, expected);
909       runSetConstraintsTest('outerBounds', init, change, expected, expected);
910     },
911
912     function testChangeMinAndMaxSize() {
913       var init = { width: 325, height: 225,
914                    minWidth: 300, minHeight: 200,
915                    maxWidth: 350, maxHeight: 250 };
916       var change = { minWidth: 287, minHeight: 198,
917                      maxWidth: 334, maxHeight: 278 };
918       runSetConstraintsTest('innerBounds', init, change, change, init);
919       runSetConstraintsTest('outerBounds', init, change, change, init);
920     },
921
922     function testClearMinAndMaxSize() {
923       var init = { width: 325, height: 225,
924                    minWidth: 300, minHeight: 200,
925                    maxWidth: 350, maxHeight: 250 };
926       var change = { minWidth: null, minHeight: null,
927                      maxWidth: null, maxHeight: null };
928       runSetConstraintsTest('innerBounds', init, change, change, init);
929       runSetConstraintsTest('outerBounds', init, change, change, init);
930     },
931
932     function testClearConstraints() {
933       // This checks that bounds are not clipped once constraints are removed.
934       var createOptions = {
935         innerBounds: {
936           width: 325, height: 225,
937           minWidth: 300, minHeight: 200,
938           maxWidth: 350, maxHeight: 250
939         }
940       };
941       chrome.app.window.create('test.html', createOptions, callbackPass(
942       function(win) {
943         win.innerBounds.setMinimumSize(null, null);
944         win.innerBounds.setMaximumSize(null, null);
945
946         // Set the size smaller than the initial min.
947         win.innerBounds.setSize(234, 198);
948
949         // Dummy call to wait for bounds to be changed in the browser.
950         chrome.test.waitForRoundTrip('msg', callbackPass(function(msg) {
951           chrome.test.assertEq(234, win.innerBounds.width);
952           chrome.test.assertEq(198, win.innerBounds.height);
953
954           // Set the size larger than the initial max.
955           win.innerBounds.setSize(361, 278);
956
957           chrome.test.waitForRoundTrip('msg', callbackPass(function(msg) {
958             chrome.test.assertEq(361, win.innerBounds.width);
959             chrome.test.assertEq(278, win.innerBounds.height);
960             win.close();
961           }));
962         }));
963       }));
964     },
965
966     function testMinWidthLargerThanMaxWidth() {
967       var init = { width: 102, height: 103,
968                    minWidth: 100, minHeight: 101,
969                    maxWidth: 104, maxHeight: 105 };
970       var change = { minWidth: 200 };
971       var expected = { minWidth: 200, minHeight: 101,
972                        maxWidth: 200, maxHeight: 105 };
973       runSetConstraintsTest('innerBounds', init, change, expected);
974     },
975
976     function testMinHeightLargerThanMaxHeight() {
977       var init = { width: 102, height: 103,
978                    minWidth: 100, minHeight: 101,
979                    maxWidth: 104, maxHeight: 105 };
980       var change = { minHeight: 200 };
981       var expected = { minWidth: 100, minHeight: 200,
982                        maxWidth: 104, maxHeight: 200 };
983       runSetConstraintsTest('innerBounds', init, change, expected);
984     },
985
986     function testMaxWidthSmallerThanMinWidth() {
987       var init = { width: 102, height: 103,
988                    minWidth: 100, minHeight: 101,
989                    maxWidth: 104, maxHeight: 105 };
990       var change = { maxWidth: 50 };
991       var expected = { minWidth: 100, minHeight: 101,
992                        maxWidth: 100, maxHeight: 105 };
993       runSetConstraintsTest('innerBounds', init, change, expected);
994     },
995
996     function testMaxHeightSmallerThanMinHeight() {
997       var init = { width: 102, height: 103,
998                    minWidth: 100, minHeight: 101,
999                    maxWidth: 104, maxHeight: 105 };
1000       var change = { maxHeight: 50 };
1001       var expected = { minWidth: 100, minHeight: 101,
1002                        maxWidth: 104, maxHeight: 101 };
1003       runSetConstraintsTest('innerBounds', init, change, expected);
1004     },
1005   ]);
1006 }
1007
1008 function testSingleton() {
1009   chrome.test.runTests([
1010     function noParameterWithId() {
1011       chrome.app.window.create(
1012         'test.html', { id: 'singleton-id' },
1013         callbackPass(function(win) {
1014           var w = win.contentWindow;
1015
1016           chrome.app.window.create(
1017             'test.html', { id: 'singleton-id' },
1018             callbackPass(function(win) {
1019               var w2 = win.contentWindow;
1020               chrome.test.assertTrue(w === w2);
1021
1022               w.close();
1023               w2.close();
1024             })
1025           );
1026         })
1027       );
1028     },
1029   ]);
1030 }
1031
1032 function testCloseEvent() {
1033   chrome.test.runTests([
1034     function basic() {
1035       chrome.app.window.create('test.html', callbackPass(function(win) {
1036         win.onClosed.addListener(callbackPass(function() {
1037           // Mission accomplished.
1038         }));
1039         win.contentWindow.close();
1040       }));
1041     }
1042   ]);
1043 }
1044
1045 function testMaximize() {
1046   chrome.test.runTests([
1047     function basic() {
1048       chrome.app.window.create('test.html',
1049                                { innerBounds: {width: 200, height: 200} },
1050         callbackPass(function(win) {
1051           // TODO(mlamouri): we should be able to use onMaximized here but to
1052           // make that happen we need to make sure the event is not fired when
1053           // .maximize() is called but when the maximizing is finished.
1054           // See crbug.com/316091
1055           function isWindowMaximized() {
1056             return win.contentWindow.outerHeight == screen.availHeight &&
1057                    win.contentWindow.outerWidth == screen.availWidth;
1058           }
1059
1060           eventLoopCheck(isWindowMaximized, function() {
1061             win.close();
1062           });
1063
1064           win.maximize();
1065         })
1066       );
1067     },
1068
1069     function nonResizableWindow() {
1070       chrome.app.window.create('test.html',
1071                                { innerBounds: {width: 200, height: 200},
1072                                  resizable: false },
1073         callbackPass(function(win) {
1074           // TODO(mlamouri): we should be able to use onMaximized here but to
1075           // make that happen we need to make sure the event is not fired when
1076           // .maximize() is called but when the maximizing is finished.
1077           // See crbug.com/316091
1078           function isWindowMaximized() {
1079             return win.contentWindow.outerHeight == screen.availHeight &&
1080                    win.contentWindow.outerWidth == screen.availWidth;
1081           }
1082
1083           eventLoopCheck(isWindowMaximized, function() {
1084             win.close();
1085           });
1086
1087           win.maximize();
1088         })
1089       );
1090     },
1091   ]);
1092 }
1093
1094 function testRestore() {
1095   chrome.test.runTests([
1096     function basic() {
1097       chrome.app.window.create('test.html',
1098                                { innerBounds: {width: 200, height: 200} },
1099         callbackPass(function(win) {
1100           var oldWidth = win.contentWindow.innerWidth;
1101           var oldHeight = win.contentWindow.innerHeight;
1102
1103           // TODO(mlamouri): we should be able to use onMaximized here but to
1104           // make that happen we need to make sure the event is not fired when
1105           // .maximize() is called but when the maximizing is finished.
1106           // See crbug.com/316091
1107           function isWindowMaximized() {
1108             return win.contentWindow.outerHeight == screen.availHeight &&
1109                    win.contentWindow.outerWidth == screen.availWidth;
1110           }
1111           function isWindowRestored() {
1112             return win.contentWindow.innerHeight == oldHeight &&
1113                    win.contentWindow.innerWidth == oldWidth;
1114           }
1115
1116           eventLoopCheck(isWindowMaximized, function() {
1117             eventLoopCheck(isWindowRestored, function() {
1118               win.close();
1119             });
1120
1121             win.restore();
1122           });
1123
1124           win.maximize();
1125         })
1126       );
1127     }
1128   ]);
1129 }
1130
1131 function testRestoreAfterClose() {
1132   chrome.test.runTests([
1133     function restoredBoundsLowerThanNewMinSize() {
1134       chrome.app.window.create('test.html', {
1135         innerBounds: {
1136           width: 100, height: 150,
1137           minWidth: 200, minHeight: 250,
1138           maxWidth: 200, maxHeight: 250
1139         },
1140         id: 'test-id'
1141       }, callbackPass(function(win) {
1142         var w = win.contentWindow;
1143         assertFuzzyEq(200, w.innerWidth, defaultFuzzFactor);
1144         assertFuzzyEq(250, w.innerHeight, defaultFuzzFactor);
1145
1146         win.onClosed.addListener(callbackPass(function() {
1147           chrome.app.window.create('test.html', {
1148             innerBounds: {
1149               width: 500, height: 550,
1150               minWidth: 400, minHeight: 450,
1151               maxWidth: 600, maxHeight: 650
1152             },
1153             id: 'test-id'
1154           }, callbackPass(function(win) {
1155             var w = win.contentWindow;
1156             assertFuzzyEq(400, w.innerWidth, defaultFuzzFactor);
1157             assertFuzzyEq(450, w.innerHeight, defaultFuzzFactor);
1158             w.close();
1159           }));
1160         }));
1161
1162         w.close();
1163       }));
1164     }
1165   ]);
1166 }
1167
1168 function testRestoreAfterGeometryCacheChange() {
1169   chrome.test.runTests([
1170     function restorePositionAndSize() {
1171       chrome.app.window.create('test.html', {
1172         outerBounds: { left: 200, top: 200 },
1173         innerBounds: { width: 200, height: 200 },
1174         id: 'test-ra',
1175       }, callbackPass(function(win) { waitForLoad(win, function(win) {
1176         var w = win.contentWindow;
1177         chrome.test.assertEq(200, w.screenX);
1178         chrome.test.assertEq(200, w.screenY);
1179         chrome.test.assertEq(200, w.innerHeight);
1180         chrome.test.assertEq(200, w.innerWidth);
1181
1182         w.resizeTo(300, 300);
1183         w.moveTo(100, 100);
1184
1185         chrome.app.window.create('test.html', {
1186           outerBounds: { left: 200, top: 200, width: 200, height: 200 },
1187           id: 'test-rb', frame: 'none'
1188         }, callbackPass(function(win2) { waitForLoad(win2, function(win2) {
1189           var w2 = win2.contentWindow;
1190           chrome.test.assertEq(200, w2.screenX);
1191           chrome.test.assertEq(200, w2.screenY);
1192           chrome.test.assertEq(200, w2.innerWidth);
1193           chrome.test.assertEq(200, w2.innerHeight);
1194
1195           w2.resizeTo(100, 100);
1196           w2.moveTo(300, 300);
1197
1198           chrome.test.sendMessage('ListenGeometryChange', function(reply) {
1199             win.onClosed.addListener(callbackPass(function() {
1200               chrome.app.window.create('test.html', {
1201                 id: 'test-ra'
1202               }, callbackPass(function(win) { waitForLoad(win, function(win) {
1203                 var w = win.contentWindow;
1204                 chrome.test.assertEq(100, w.screenX);
1205                 chrome.test.assertEq(100, w.screenY);
1206                 chrome.test.assertEq(300, w.outerWidth);
1207                 chrome.test.assertEq(300, w.outerHeight);
1208               })}));
1209             }));
1210
1211             win2.onClosed.addListener(callbackPass(function() {
1212               chrome.app.window.create('test.html', {
1213                 id: 'test-rb', frame: 'none'
1214               },callbackPass(function(win2) { waitForLoad(win2, function(win2) {
1215                 var w = win2.contentWindow;
1216                 chrome.test.assertEq(300, w.screenX);
1217                 chrome.test.assertEq(300, w.screenY);
1218                 chrome.test.assertEq(100, w.outerWidth);
1219                 chrome.test.assertEq(100, w.outerHeight);
1220               })}));
1221             }));
1222
1223             win.close();
1224             win2.close();
1225           });
1226         })}));
1227       })}));
1228     },
1229   ]);
1230 }
1231
1232 function testBadging() {
1233   chrome.test.runTests([
1234     function testSettingAndClearingBadge() {
1235       chrome.app.window.create('test.html', callbackPass(function(win) {
1236         win.setBadgeIcon('square.png');
1237         win.clearBadge();
1238         win.setBadgeIcon('non_square.png');
1239         win.clearBadge();
1240         chrome.test.sendMessage(
1241             'WaitForRoundTrip', callbackPass(function(reply) {}));
1242       }));
1243     },
1244   ]);
1245 }
1246
1247 function testFrameColors() {
1248   chrome.test.runTests([
1249     function testWithNoColor() {
1250       chrome.app.window.create('test.html', callbackPass(function(win) {
1251         chrome.test.assertEq(false, win.hasFrameColor);
1252         win.close();
1253       }));
1254     },
1255
1256     function testWithFrameNone() {
1257       chrome.app.window.create('test.html', {
1258         frame: 'none'
1259       },
1260       callbackPass(function(win) {
1261         chrome.test.assertEq(false, win.hasFrameColor);
1262         win.close();
1263       }));
1264     },
1265
1266     function testWithBlack() {
1267       chrome.app.window.create('test.html', {
1268         frame: {
1269           type: 'chrome',
1270           color: '#000000'
1271         }
1272       },
1273       callbackPass(function(win) {
1274         chrome.test.assertEq(true, win.hasFrameColor);
1275         chrome.test.assertEq(0x000000, win.activeFrameColor);
1276         chrome.test.assertEq(0x000000, win.inactiveFrameColor);
1277         win.close();
1278       }));
1279     },
1280
1281     function testWithWhite() {
1282       chrome.app.window.create('test.html', {
1283         frame: {
1284           color: '#FFFFFF'
1285         }
1286       },
1287       callbackPass(function(win) {
1288         chrome.test.assertEq(true, win.hasFrameColor);
1289         chrome.test.assertEq(0xFFFFFF, win.activeFrameColor);
1290         chrome.test.assertEq(0xFFFFFF, win.inactiveFrameColor);
1291         win.close();
1292       }));
1293     },
1294
1295     function testWithActiveInactive() {
1296       chrome.app.window.create('test.html', {
1297         frame: {
1298           type: 'chrome',
1299           color: '#000000',
1300           inactiveColor: '#FFFFFF'
1301         }
1302       },
1303       callbackPass(function(win) {
1304         chrome.test.assertEq(true, win.hasFrameColor);
1305         chrome.test.assertEq(0x000000, win.activeFrameColor);
1306         chrome.test.assertEq(0xFFFFFF, win.inactiveFrameColor);
1307         win.close();
1308       }));
1309     },
1310
1311     function testWithWhiteShorthand() {
1312       chrome.app.window.create('test.html', {
1313         frame: {
1314           color: '#FFF'
1315         }
1316       },
1317       callbackPass(function(win) {
1318         chrome.test.assertEq(true, win.hasFrameColor);
1319         chrome.test.assertEq(0xFFFFFF, win.activeFrameColor);
1320         chrome.test.assertEq(0xFFFFFF, win.inactiveFrameColor);
1321         win.close();
1322       }));
1323     },
1324
1325     function testWithFrameNoneAndColor() {
1326       chrome.app.window.create('test.html', {
1327         frame: {
1328           type: 'none',
1329           color: '#FFF'
1330         }
1331       },
1332       callbackFail('Windows with no frame cannot have a color.'));
1333     },
1334
1335     function testWithInactiveColorAndNoColor() {
1336       chrome.app.window.create('test.html', {
1337         frame: {
1338           inactiveColor: '#FFF'
1339         }
1340       },
1341       callbackFail('frame.inactiveColor must be used with frame.color.'));
1342     },
1343
1344      function testWithInvalidColor() {
1345       chrome.app.window.create('test.html', {
1346         frame: {
1347           color: 'DontWorryBeHappy'
1348         }
1349       },
1350       callbackFail('The color specification could not be parsed.'));
1351     }
1352   ]);
1353 }
1354
1355 function testVisibleOnAllWorkspaces() {
1356   chrome.test.runTests([
1357     function setAndUnsetVisibleOnAllWorkspaces() {
1358       chrome.app.window.create('test.html', {
1359         visibleOnAllWorkspaces: true
1360       }, callbackPass(function(win) {
1361         win.setVisibleOnAllWorkspaces(false);
1362         win.setVisibleOnAllWorkspaces(true);
1363         chrome.test.sendMessage(
1364             'WaitForRoundTrip', callbackPass(function(reply) {}));
1365       }));
1366     },
1367   ]);
1368 }
1369
1370 chrome.app.runtime.onLaunched.addListener(function() {
1371   chrome.test.sendMessage('Launched', function(reply) {
1372     window[reply]();
1373   });
1374 });