Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / panels / panel_browsertest.cc
1 // Copyright (c) 2012 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 #include "base/bind.h"
6 #include "base/prefs/pref_service.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/app/chrome_command_ids.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/devtools/devtools_window.h"
11 #include "chrome/browser/extensions/extension_apitest.h"
12 #include "chrome/browser/net/url_request_mock_util.h"
13 #include "chrome/browser/prefs/browser_prefs.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
16 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/browser/ui/browser_commands.h"
19 #include "chrome/browser/ui/browser_finder.h"
20 #include "chrome/browser/ui/browser_iterator.h"
21 #include "chrome/browser/ui/browser_window.h"
22 #include "chrome/browser/ui/panels/base_panel_browser_test.h"
23 #include "chrome/browser/ui/panels/docked_panel_collection.h"
24 #include "chrome/browser/ui/panels/native_panel.h"
25 #include "chrome/browser/ui/panels/panel.h"
26 #include "chrome/browser/ui/panels/panel_manager.h"
27 #include "chrome/browser/ui/panels/test_panel_active_state_observer.h"
28 #include "chrome/browser/web_applications/web_app.h"
29 #include "chrome/common/chrome_switches.h"
30 #include "chrome/common/pref_names.h"
31 #include "chrome/common/url_constants.h"
32 #include "chrome/test/base/interactive_test_utils.h"
33 #include "chrome/test/base/ui_test_utils.h"
34 #include "content/public/browser/native_web_keyboard_event.h"
35 #include "content/public/browser/notification_service.h"
36 #include "content/public/browser/web_contents.h"
37 #include "content/public/common/url_constants.h"
38 #include "content/public/test/browser_test_utils.h"
39 #include "content/test/net/url_request_mock_http_job.h"
40 #include "extensions/common/constants.h"
41 #include "net/base/net_util.h"
42 #include "testing/gtest/include/gtest/gtest.h"
43 #include "ui/base/hit_test.h"
44 #include "ui/events/event_utils.h"
45 #include "ui/gfx/screen.h"
46
47 using content::WebContents;
48
49 class PanelBrowserTest : public BasePanelBrowserTest {
50  public:
51   PanelBrowserTest() : BasePanelBrowserTest() {
52   }
53
54  protected:
55   // Helper function for debugging.
56   void PrintAllPanelBounds() {
57     const std::vector<Panel*>& panels = PanelManager::GetInstance()->panels();
58     DLOG(WARNING) << "PanelBounds:";
59     for (size_t i = 0; i < panels.size(); ++i) {
60       DLOG(WARNING) << "#=" << i
61                     << ", ptr=" << panels[i]
62                     << ", x=" << panels[i]->GetBounds().x()
63                     << ", y=" << panels[i]->GetBounds().y()
64                     << ", width=" << panels[i]->GetBounds().width()
65                     << ", height" << panels[i]->GetBounds().height();
66     }
67   }
68
69   std::vector<gfx::Rect> GetAllPanelBounds() {
70     std::vector<Panel*> panels = PanelManager::GetInstance()->panels();
71     std::vector<gfx::Rect> bounds;
72     for (size_t i = 0; i < panels.size(); i++)
73       bounds.push_back(panels[i]->GetBounds());
74     return bounds;
75   }
76
77   std::vector<gfx::Rect> AddXDeltaToBounds(const std::vector<gfx::Rect>& bounds,
78                                            const std::vector<int>& delta_x) {
79     std::vector<gfx::Rect> new_bounds = bounds;
80     for (size_t i = 0; i < bounds.size(); ++i)
81       new_bounds[i].Offset(delta_x[i], 0);
82     return new_bounds;
83   }
84
85   std::vector<Panel::ExpansionState> GetAllPanelExpansionStates() {
86     std::vector<Panel*> panels = PanelManager::GetInstance()->panels();
87     std::vector<Panel::ExpansionState> expansion_states;
88     for (size_t i = 0; i < panels.size(); i++)
89       expansion_states.push_back(panels[i]->expansion_state());
90     return expansion_states;
91   }
92
93   std::vector<bool> GetAllPanelActiveStates() {
94     std::vector<Panel*> panels = PanelManager::GetInstance()->panels();
95     std::vector<bool> active_states;
96     for (size_t i = 0; i < panels.size(); i++)
97       active_states.push_back(panels[i]->IsActive());
98     return active_states;
99   }
100
101   std::vector<bool> ProduceExpectedActiveStates(
102       int expected_active_panel_index) {
103     std::vector<Panel*> panels = PanelManager::GetInstance()->panels();
104     std::vector<bool> active_states;
105     for (int i = 0; i < static_cast<int>(panels.size()); i++)
106       active_states.push_back(i == expected_active_panel_index);
107     return active_states;
108   }
109
110   void WaitForPanelActiveStates(const std::vector<bool>& old_states,
111                                 const std::vector<bool>& new_states) {
112     DCHECK(old_states.size() == new_states.size());
113     std::vector<Panel*> panels = PanelManager::GetInstance()->panels();
114     for (size_t i = 0; i < old_states.size(); i++) {
115       if (old_states[i] != new_states[i]){
116         WaitForPanelActiveState(
117             panels[i], new_states[i] ? SHOW_AS_ACTIVE : SHOW_AS_INACTIVE);
118       }
119     }
120   }
121
122   void TestMinimizeRestore() {
123     // This constant is used to generate a point 'sufficiently higher then
124     // top edge of the panel'. On some platforms (Mac) we extend hover area
125     // a bit above the minimized panel as well, so it takes significant
126     // distance to 'move mouse out' of the hover-sensitive area.
127     const int kFarEnoughFromHoverArea = 153;
128
129     PanelManager* panel_manager = PanelManager::GetInstance();
130     std::vector<Panel*> panels = panel_manager->panels();
131     std::vector<gfx::Rect> test_begin_bounds = GetAllPanelBounds();
132     std::vector<gfx::Rect> expected_bounds = test_begin_bounds;
133     std::vector<Panel::ExpansionState> expected_expansion_states(
134         panels.size(), Panel::EXPANDED);
135     std::vector<NativePanelTesting*> native_panels_testing(panels.size());
136     for (size_t i = 0; i < panels.size(); ++i) {
137       native_panels_testing[i] = CreateNativePanelTesting(panels[i]);
138     }
139
140     // Verify titlebar click does not minimize.
141     for (size_t index = 0; index < panels.size(); ++index) {
142       // Press left mouse button.  Verify nothing changed.
143       native_panels_testing[index]->PressLeftMouseButtonTitlebar(
144           panels[index]->GetBounds().origin());
145       EXPECT_EQ(expected_bounds, GetAllPanelBounds());
146       EXPECT_EQ(expected_expansion_states, GetAllPanelExpansionStates());
147
148       // Release mouse button.  Verify nothing changed.
149       native_panels_testing[index]->ReleaseMouseButtonTitlebar();
150       EXPECT_EQ(expected_bounds, GetAllPanelBounds());
151       EXPECT_EQ(expected_expansion_states, GetAllPanelExpansionStates());
152     }
153
154     // Minimize all panels for next stage in test.
155     for (size_t index = 0; index < panels.size(); ++index) {
156       panels[index]->Minimize();
157       expected_bounds[index].set_height(panel::kMinimizedPanelHeight);
158       expected_bounds[index].set_y(
159           test_begin_bounds[index].y() +
160           test_begin_bounds[index].height() - panel::kMinimizedPanelHeight);
161       expected_expansion_states[index] = Panel::MINIMIZED;
162       EXPECT_EQ(expected_bounds, GetAllPanelBounds());
163       EXPECT_EQ(expected_expansion_states, GetAllPanelExpansionStates());
164     }
165
166     // Setup bounds and expansion states for minimized and titlebar-only
167     // states.
168     std::vector<Panel::ExpansionState> titlebar_exposed_states(
169         panels.size(), Panel::TITLE_ONLY);
170     std::vector<gfx::Rect> minimized_bounds = expected_bounds;
171     std::vector<Panel::ExpansionState> minimized_states(
172         panels.size(), Panel::MINIMIZED);
173     std::vector<gfx::Rect> titlebar_exposed_bounds = test_begin_bounds;
174     for (size_t index = 0; index < panels.size(); ++index) {
175       titlebar_exposed_bounds[index].set_height(
176           panels[index]->native_panel()->TitleOnlyHeight());
177       titlebar_exposed_bounds[index].set_y(
178           test_begin_bounds[index].y() +
179           test_begin_bounds[index].height() -
180           panels[index]->native_panel()->TitleOnlyHeight());
181     }
182
183     // Test hover.  All panels are currently in minimized state.
184     EXPECT_EQ(minimized_states, GetAllPanelExpansionStates());
185     for (size_t index = 0; index < panels.size(); ++index) {
186       // Hover mouse on minimized panel.
187       // Verify titlebar is exposed on all panels.
188       gfx::Point hover_point(panels[index]->GetBounds().origin());
189       MoveMouseAndWaitForExpansionStateChange(panels[index], hover_point);
190       EXPECT_EQ(titlebar_exposed_bounds, GetAllPanelBounds());
191       EXPECT_EQ(titlebar_exposed_states, GetAllPanelExpansionStates());
192
193       // Hover mouse above the panel. Verify all panels are minimized.
194       hover_point.set_y(
195           panels[index]->GetBounds().y() - kFarEnoughFromHoverArea);
196       MoveMouseAndWaitForExpansionStateChange(panels[index], hover_point);
197       EXPECT_EQ(minimized_bounds, GetAllPanelBounds());
198       EXPECT_EQ(minimized_states, GetAllPanelExpansionStates());
199
200       // Hover mouse below minimized panel.
201       // Verify titlebar is exposed on all panels.
202       hover_point.set_y(panels[index]->GetBounds().y() +
203                         panels[index]->GetBounds().height() + 5);
204       MoveMouseAndWaitForExpansionStateChange(panels[index], hover_point);
205       EXPECT_EQ(titlebar_exposed_bounds, GetAllPanelBounds());
206       EXPECT_EQ(titlebar_exposed_states, GetAllPanelExpansionStates());
207
208       // Hover below titlebar exposed panel.  Verify nothing changed.
209       hover_point.set_y(panels[index]->GetBounds().y() +
210                         panels[index]->GetBounds().height() + 6);
211       MoveMouse(hover_point);
212       EXPECT_EQ(titlebar_exposed_bounds, GetAllPanelBounds());
213       EXPECT_EQ(titlebar_exposed_states, GetAllPanelExpansionStates());
214
215       // Hover mouse above panel.  Verify all panels are minimized.
216       hover_point.set_y(
217           panels[index]->GetBounds().y() - kFarEnoughFromHoverArea);
218       MoveMouseAndWaitForExpansionStateChange(panels[index], hover_point);
219       EXPECT_EQ(minimized_bounds, GetAllPanelBounds());
220       EXPECT_EQ(minimized_states, GetAllPanelExpansionStates());
221     }
222
223     // Test restore.  All panels are currently in minimized state.
224     for (size_t index = 0; index < panels.size(); ++index) {
225       // Hover on the last panel.  This is to test the case of clicking on the
226       // panel when it's in titlebar exposed state.
227       if (index == panels.size() - 1)
228         MoveMouse(minimized_bounds[index].origin());
229
230       // Click minimized or title bar exposed panel as the case may be.
231       // Verify panel is restored to its original size.
232       native_panels_testing[index]->PressLeftMouseButtonTitlebar(
233           panels[index]->GetBounds().origin());
234       native_panels_testing[index]->ReleaseMouseButtonTitlebar();
235       expected_bounds[index].set_height(
236           test_begin_bounds[index].height());
237       expected_bounds[index].set_y(test_begin_bounds[index].y());
238       expected_expansion_states[index] = Panel::EXPANDED;
239       EXPECT_EQ(expected_bounds, GetAllPanelBounds());
240       EXPECT_EQ(expected_expansion_states, GetAllPanelExpansionStates());
241
242       // Hover again on the last panel which is now restored, to reset the
243       // titlebar exposed state.
244       if (index == panels.size() - 1)
245         MoveMouse(minimized_bounds[index].origin());
246     }
247
248     // The below could be separate tests, just adding a TODO here for tracking.
249     // TODO(prasadt): Add test for dragging when in titlebar exposed state.
250     // TODO(prasadt): Add test in presence of auto hiding task bar.
251
252     for (size_t i = 0; i < panels.size(); ++i)
253       delete native_panels_testing[i];
254   }
255 };
256
257 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, CheckDockedPanelProperties) {
258   PanelManager* panel_manager = PanelManager::GetInstance();
259   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
260
261   // Create 3 docked panels that are in expanded, title-only or minimized states
262   // respectively.
263   Panel* panel1 = CreatePanelWithBounds("1", gfx::Rect(0, 0, 100, 100));
264   Panel* panel2 = CreatePanelWithBounds("2", gfx::Rect(0, 0, 100, 100));
265   Panel* panel3 = CreatePanelWithBounds("3", gfx::Rect(0, 0, 100, 100));
266   panel2->SetExpansionState(Panel::TITLE_ONLY);
267   EXPECT_EQ(Panel::TITLE_ONLY, panel2->expansion_state());
268   panel3->SetExpansionState(Panel::MINIMIZED);
269   EXPECT_EQ(Panel::MINIMIZED, panel3->expansion_state());
270   scoped_ptr<NativePanelTesting> panel1_testing(
271       CreateNativePanelTesting(panel1));
272   scoped_ptr<NativePanelTesting> panel2_testing(
273       CreateNativePanelTesting(panel2));
274   scoped_ptr<NativePanelTesting> panel3_testing(
275       CreateNativePanelTesting(panel3));
276
277   // Ensure that the layout message can get a chance to be processed so that
278   // the button visibility can be updated.
279   base::MessageLoop::current()->RunUntilIdle();
280
281   EXPECT_EQ(3, panel_manager->num_panels());
282   EXPECT_TRUE(docked_collection->HasPanel(panel1));
283   EXPECT_TRUE(docked_collection->HasPanel(panel2));
284   EXPECT_TRUE(docked_collection->HasPanel(panel3));
285
286   EXPECT_EQ(Panel::EXPANDED, panel1->expansion_state());
287   EXPECT_EQ(Panel::TITLE_ONLY, panel2->expansion_state());
288   EXPECT_EQ(Panel::MINIMIZED, panel3->expansion_state());
289
290   EXPECT_TRUE(panel1->IsAlwaysOnTop());
291   EXPECT_TRUE(panel2->IsAlwaysOnTop());
292   EXPECT_TRUE(panel3->IsAlwaysOnTop());
293
294   EXPECT_TRUE(panel1_testing->IsButtonVisible(panel::CLOSE_BUTTON));
295   EXPECT_TRUE(panel2_testing->IsButtonVisible(panel::CLOSE_BUTTON));
296   EXPECT_TRUE(panel3_testing->IsButtonVisible(panel::CLOSE_BUTTON));
297
298   EXPECT_TRUE(panel1_testing->IsButtonVisible(panel::MINIMIZE_BUTTON));
299   EXPECT_FALSE(panel2_testing->IsButtonVisible(panel::MINIMIZE_BUTTON));
300   EXPECT_FALSE(panel3_testing->IsButtonVisible(panel::MINIMIZE_BUTTON));
301
302   EXPECT_FALSE(panel1_testing->IsButtonVisible(panel::RESTORE_BUTTON));
303   EXPECT_TRUE(panel2_testing->IsButtonVisible(panel::RESTORE_BUTTON));
304   EXPECT_TRUE(panel3_testing->IsButtonVisible(panel::RESTORE_BUTTON));
305
306   // Expanded panel cannot be resized at the bottom.
307   EXPECT_EQ(panel::RESIZABLE_EXCEPT_BOTTOM, panel1->CanResizeByMouse());
308   EXPECT_EQ(panel::NOT_RESIZABLE, panel2->CanResizeByMouse());
309   EXPECT_EQ(panel::NOT_RESIZABLE, panel3->CanResizeByMouse());
310
311   EXPECT_EQ(panel::TOP_ROUNDED, panel1_testing->GetWindowCornerStyle());
312   EXPECT_EQ(panel::TOP_ROUNDED, panel1_testing->GetWindowCornerStyle());
313   EXPECT_EQ(panel::TOP_ROUNDED, panel3_testing->GetWindowCornerStyle());
314
315   EXPECT_EQ(Panel::USE_PANEL_ATTENTION, panel1->attention_mode());
316   EXPECT_EQ(Panel::USE_PANEL_ATTENTION, panel2->attention_mode());
317   EXPECT_EQ(Panel::USE_PANEL_ATTENTION, panel3->attention_mode());
318
319   panel_manager->CloseAll();
320 }
321
322 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, CreatePanel) {
323   PanelManager* panel_manager = PanelManager::GetInstance();
324   EXPECT_EQ(0, panel_manager->num_panels()); // No panels initially.
325
326   Panel* panel = CreatePanel("PanelTest");
327   EXPECT_EQ(1, panel_manager->num_panels());
328
329   gfx::Rect bounds = panel->GetBounds();
330   EXPECT_GT(bounds.x(), 0);
331   EXPECT_GT(bounds.y(), 0);
332   EXPECT_GT(bounds.width(), 0);
333   EXPECT_GT(bounds.height(), 0);
334
335   EXPECT_EQ(bounds.right(),
336             panel_manager->docked_collection()->StartingRightPosition());
337
338   CloseWindowAndWait(panel);
339
340   EXPECT_EQ(0, panel_manager->num_panels());
341 }
342
343 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, CreateBigPanel) {
344   gfx::Rect work_area = PanelManager::GetInstance()->
345       display_settings_provider()->GetPrimaryWorkArea();
346   Panel* panel = CreatePanelWithBounds("BigPanel", work_area);
347   gfx::Rect bounds = panel->GetBounds();
348   EXPECT_EQ(panel->max_size().width(), bounds.width());
349   EXPECT_LT(bounds.width(), work_area.width());
350   EXPECT_EQ(panel->max_size().height(), bounds.height());
351   EXPECT_LT(bounds.height(), work_area.height());
352   panel->Close();
353 }
354
355 class WaitForStableInitialSize : public TestPanelNotificationObserver {
356  public:
357   explicit WaitForStableInitialSize(Panel* panel)
358       : TestPanelNotificationObserver(
359           chrome::NOTIFICATION_PANEL_COLLECTION_UPDATED,
360           content::NotificationService::AllSources()),
361         panel_(panel) {}
362   virtual ~WaitForStableInitialSize() {}
363
364  protected:
365   virtual bool AtExpectedState() OVERRIDE {
366     return panel_->GetBounds().height() > panel_->TitleOnlyHeight();
367   }
368   Panel* panel_;
369 };
370
371 class WaitForAutoResizeWider : public TestPanelNotificationObserver {
372  public:
373   explicit WaitForAutoResizeWider(Panel* panel)
374       : TestPanelNotificationObserver(
375           chrome::NOTIFICATION_PANEL_COLLECTION_UPDATED,
376           content::NotificationService::AllSources()),
377         panel_(panel),
378         initial_size_(panel->GetBounds().size()) {}
379   virtual ~WaitForAutoResizeWider() {}
380
381  protected:
382   virtual bool AtExpectedState() OVERRIDE {
383     return panel_->GetBounds().width() > initial_size_.width();
384   }
385   Panel* panel_;
386   gfx::Size initial_size_;
387 };
388
389 class WaitForAutoResizeNarrower : public TestPanelNotificationObserver {
390  public:
391   explicit WaitForAutoResizeNarrower(Panel* panel)
392       : TestPanelNotificationObserver(
393           chrome::NOTIFICATION_PANEL_COLLECTION_UPDATED,
394           content::NotificationService::AllSources()),
395         panel_(panel),
396         initial_size_(panel->GetBounds().size()) {}
397   virtual ~WaitForAutoResizeNarrower() {}
398
399  protected:
400   virtual bool AtExpectedState() OVERRIDE {
401     return panel_->GetBounds().width() < initial_size_.width();
402   }
403   Panel* panel_;
404   gfx::Size initial_size_;
405 };
406
407 // crbug.com/160504
408 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DISABLED_AutoResize) {
409   PanelManager* panel_manager = PanelManager::GetInstance();
410   panel_manager->enable_auto_sizing(true);
411   // Bigger space is needed by this test.
412   mock_display_settings_provider()->SetPrimaryDisplay(
413       gfx::Rect(0, 0, 1200, 900), gfx::Rect(0, 0, 1200, 900));
414
415   // Create a test panel with web contents loaded.
416   CreatePanelParams params("PanelTest1", gfx::Rect(), SHOW_AS_ACTIVE);
417   GURL url(ui_test_utils::GetTestUrl(
418       base::FilePath(kTestDir),
419       base::FilePath(FILE_PATH_LITERAL("update-preferred-size.html"))));
420   params.url = url;
421   Panel* panel = CreatePanelWithParams(params);
422
423   // Ensure panel has auto resized to original web content size.
424   // The resize will update the docked panel collection.
425   WaitForStableInitialSize initial_resize(panel);
426   initial_resize.Wait();
427   gfx::Rect initial_bounds = panel->GetBounds();
428
429   // Expand the test page. The resize will update the docked panel collection.
430   WaitForAutoResizeWider enlarge(panel);
431   EXPECT_TRUE(content::ExecuteScript(
432       panel->GetWebContents(), "changeSize(50);"));
433   enlarge.Wait();
434   gfx::Rect bounds_on_grow = panel->GetBounds();
435   EXPECT_GT(bounds_on_grow.width(), initial_bounds.width());
436   EXPECT_EQ(bounds_on_grow.height(), initial_bounds.height());
437
438   // Shrink the test page. The resize will update the docked panel collection.
439   WaitForAutoResizeNarrower shrink(panel);
440   EXPECT_TRUE(content::ExecuteScript(
441       panel->GetWebContents(), "changeSize(-30);"));
442   shrink.Wait();
443   gfx::Rect bounds_on_shrink = panel->GetBounds();
444   EXPECT_LT(bounds_on_shrink.width(), bounds_on_grow.width());
445   EXPECT_GT(bounds_on_shrink.width(), initial_bounds.width());
446   EXPECT_EQ(bounds_on_shrink.height(), initial_bounds.height());
447
448   // Verify resizing turns off auto-resizing and panel no longer auto-resizes.
449   gfx::Rect previous_bounds = panel->GetBounds();
450   // These should be identical because the panel is expanded.
451   EXPECT_EQ(previous_bounds.size(), panel->GetRestoredBounds().size());
452   gfx::Size new_size(previous_bounds.size());
453   new_size.Enlarge(5, 5);
454   gfx::Rect new_bounds(previous_bounds.origin(), new_size);
455   panel->SetBounds(new_bounds);
456   EXPECT_FALSE(panel->auto_resizable());
457   EXPECT_EQ(new_bounds.size(), panel->GetBounds().size());
458   EXPECT_EQ(new_bounds.size(), panel->GetRestoredBounds().size());
459
460   // Turn back on auto-resize and verify that panel auto resizes.
461   content::WindowedNotificationObserver auto_resize_enabled(
462       chrome::NOTIFICATION_PANEL_COLLECTION_UPDATED,
463       content::NotificationService::AllSources());
464   panel->SetAutoResizable(true);
465   auto_resize_enabled.Wait();
466   gfx::Rect bounds_auto_resize_enabled = panel->GetBounds();
467   EXPECT_EQ(bounds_on_shrink.width(), bounds_auto_resize_enabled.width());
468   EXPECT_EQ(bounds_on_shrink.height(), bounds_auto_resize_enabled.height());
469
470   panel->Close();
471 }
472
473 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, ResizePanel) {
474   PanelManager* panel_manager = PanelManager::GetInstance();
475   panel_manager->enable_auto_sizing(true);
476
477   Panel* panel = CreatePanel("TestPanel");
478   EXPECT_TRUE(panel->auto_resizable());
479   EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
480
481   // Verify resizing turns off auto-resizing and that it works.
482   gfx::Rect original_bounds = panel->GetBounds();
483   // These should be identical because the panel is expanded.
484   EXPECT_EQ(original_bounds.size(), panel->GetRestoredBounds().size());
485   gfx::Size new_size(original_bounds.size());
486   new_size.Enlarge(5, 5);
487   gfx::Rect new_bounds(original_bounds.origin(), new_size);
488   panel->SetBounds(new_bounds);
489   EXPECT_FALSE(panel->auto_resizable());
490   EXPECT_EQ(new_bounds.size(), panel->GetBounds().size());
491   EXPECT_EQ(new_bounds.size(), panel->GetRestoredBounds().size());
492
493   // Verify current height unaffected when panel is not expanded.
494   panel->SetExpansionState(Panel::MINIMIZED);
495   int original_height = panel->GetBounds().height();
496   new_size.Enlarge(5, 5);
497   new_bounds.set_size(new_size);
498   panel->SetBounds(new_bounds);
499   EXPECT_EQ(new_bounds.size().width(), panel->GetBounds().width());
500   EXPECT_EQ(original_height, panel->GetBounds().height());
501   EXPECT_EQ(new_bounds.size(), panel->GetRestoredBounds().size());
502
503   panel->Close();
504 }
505
506 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, AnimateBounds) {
507   // Create a detached panel, instead of docked panel because it cannot be
508   // moved to any location.
509   Panel* panel = CreateDetachedPanel("1", gfx::Rect(200, 100, 100, 100));
510   scoped_ptr<NativePanelTesting> panel_testing(
511       CreateNativePanelTesting(panel));
512
513   // Validates that no animation should be triggered when the panel is being
514   // dragged.
515   gfx::Point mouse_location(panel->GetBounds().origin());
516   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
517   panel_testing->DragTitlebar(mouse_location + gfx::Vector2d(-100, 5));
518   EXPECT_FALSE(panel_testing->IsAnimatingBounds());
519   panel_testing->FinishDragTitlebar();
520
521   // Set bounds with animation.
522   gfx::Rect bounds = gfx::Rect(10, 20, 150, 160);
523   panel->SetPanelBounds(bounds);
524   EXPECT_TRUE(panel_testing->IsAnimatingBounds());
525   WaitForBoundsAnimationFinished(panel);
526   EXPECT_FALSE(panel_testing->IsAnimatingBounds());
527   EXPECT_EQ(bounds, panel->GetBounds());
528
529   // Set bounds without animation.
530   bounds = gfx::Rect(30, 40, 200, 220);
531   panel->SetPanelBoundsInstantly(bounds);
532   EXPECT_FALSE(panel_testing->IsAnimatingBounds());
533   EXPECT_EQ(bounds, panel->GetBounds());
534
535   panel->Close();
536 }
537
538 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, RestoredBounds) {
539   Panel* panel = CreatePanelWithBounds("PanelTest", gfx::Rect(0, 0, 100, 100));
540   EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
541   EXPECT_EQ(panel->GetBounds(), panel->GetRestoredBounds());
542
543   panel->SetExpansionState(Panel::MINIMIZED);
544   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
545   gfx::Rect bounds = panel->GetBounds();
546   gfx::Rect restored = panel->GetRestoredBounds();
547   EXPECT_EQ(bounds.x(), restored.x());
548   EXPECT_GT(bounds.y(), restored.y());
549   EXPECT_EQ(bounds.width(), restored.width());
550   EXPECT_LT(bounds.height(), restored.height());
551
552   panel->SetExpansionState(Panel::TITLE_ONLY);
553   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
554   bounds = panel->GetBounds();
555   restored = panel->GetRestoredBounds();
556   EXPECT_EQ(bounds.x(), restored.x());
557   EXPECT_GT(bounds.y(), restored.y());
558   EXPECT_EQ(bounds.width(), restored.width());
559   EXPECT_LT(bounds.height(), restored.height());
560
561   panel->SetExpansionState(Panel::MINIMIZED);
562   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
563   bounds = panel->GetBounds();
564   restored = panel->GetRestoredBounds();
565   EXPECT_EQ(bounds.x(), restored.x());
566   EXPECT_GT(bounds.y(), restored.y());
567   EXPECT_EQ(bounds.width(), restored.width());
568   EXPECT_LT(bounds.height(), restored.height());
569
570   panel->SetExpansionState(Panel::EXPANDED);
571   EXPECT_EQ(panel->GetBounds(), panel->GetRestoredBounds());
572
573   // Verify that changing the panel bounds does not affect the restored height.
574   int saved_restored_height = restored.height();
575   panel->SetExpansionState(Panel::MINIMIZED);
576   bounds = gfx::Rect(10, 20, 300, 400);
577   panel->SetPanelBounds(bounds);
578   EXPECT_EQ(saved_restored_height, panel->GetRestoredBounds().height());
579
580   panel->SetExpansionState(Panel::TITLE_ONLY);
581   bounds = gfx::Rect(20, 30, 100, 200);
582   panel->SetPanelBounds(bounds);
583   EXPECT_EQ(saved_restored_height, panel->GetRestoredBounds().height());
584
585   panel->SetExpansionState(Panel::EXPANDED);
586   bounds = gfx::Rect(40, 60, 300, 400);
587   panel->SetPanelBounds(bounds);
588   EXPECT_EQ(saved_restored_height, panel->GetRestoredBounds().height());
589   panel->set_full_size(bounds.size());
590   EXPECT_NE(saved_restored_height, panel->GetRestoredBounds().height());
591
592   panel->Close();
593 }
594
595 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MinimizeRestore) {
596   // Test with one panel.
597   CreatePanelWithBounds("PanelTest1", gfx::Rect(0, 0, 100, 100));
598   TestMinimizeRestore();
599
600   PanelManager::GetInstance()->CloseAll();
601 }
602
603 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MinimizeRestoreTwoPanels) {
604   // Test with two panels.
605   CreatePanelWithBounds("PanelTest1", gfx::Rect(0, 0, 100, 100));
606   CreatePanelWithBounds("PanelTest2", gfx::Rect(0, 0, 110, 110));
607   TestMinimizeRestore();
608
609   PanelManager::GetInstance()->CloseAll();
610 }
611
612 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MinimizeRestoreThreePanels) {
613   // Test with three panels.
614   CreatePanelWithBounds("PanelTest1", gfx::Rect(0, 0, 100, 100));
615   CreatePanelWithBounds("PanelTest2", gfx::Rect(0, 0, 110, 110));
616   CreatePanelWithBounds("PanelTest3", gfx::Rect(0, 0, 120, 120));
617   TestMinimizeRestore();
618
619   PanelManager::GetInstance()->CloseAll();
620 }
621
622 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MinimizeRestoreButtonClick) {
623   // Test with three panels.
624   Panel* panel1 = CreatePanel("PanelTest1");
625   Panel* panel2 = CreatePanel("PanelTest2");
626   Panel* panel3 = CreatePanel("PanelTest3");
627   EXPECT_FALSE(panel1->IsMinimized());
628   EXPECT_FALSE(panel2->IsMinimized());
629   EXPECT_FALSE(panel3->IsMinimized());
630
631   // Click restore button on an expanded panel. Expect no change.
632   panel1->OnRestoreButtonClicked(panel::NO_MODIFIER);
633   EXPECT_FALSE(panel1->IsMinimized());
634   EXPECT_FALSE(panel2->IsMinimized());
635   EXPECT_FALSE(panel3->IsMinimized());
636
637   // Click minimize button on an expanded panel. Only that panel will minimize.
638   panel1->OnMinimizeButtonClicked(panel::NO_MODIFIER);
639   EXPECT_TRUE(panel1->IsMinimized());
640   EXPECT_FALSE(panel2->IsMinimized());
641   EXPECT_FALSE(panel3->IsMinimized());
642
643   // Click minimize button on a minimized panel. Expect no change.
644   panel1->OnMinimizeButtonClicked(panel::NO_MODIFIER);
645   EXPECT_TRUE(panel1->IsMinimized());
646   EXPECT_FALSE(panel2->IsMinimized());
647   EXPECT_FALSE(panel3->IsMinimized());
648
649   // Minimize all panels by clicking minimize button on an expanded panel
650   // with the apply-all modifier.
651   panel2->OnMinimizeButtonClicked(panel::APPLY_TO_ALL);
652   EXPECT_TRUE(panel1->IsMinimized());
653   EXPECT_TRUE(panel2->IsMinimized());
654   EXPECT_TRUE(panel3->IsMinimized());
655
656   // Click restore button on a minimized panel. Only that panel will restore.
657   panel2->OnRestoreButtonClicked(panel::NO_MODIFIER);
658   EXPECT_TRUE(panel1->IsMinimized());
659   EXPECT_FALSE(panel2->IsMinimized());
660   EXPECT_TRUE(panel3->IsMinimized());
661
662   // Restore all panels by clicking restore button on a minimized panel.
663   panel3->OnRestoreButtonClicked(panel::APPLY_TO_ALL);
664   EXPECT_FALSE(panel1->IsMinimized());
665   EXPECT_FALSE(panel2->IsMinimized());
666   EXPECT_FALSE(panel3->IsMinimized());
667 }
668
669 // http://crbug.com/243891 flaky on Linux
670 #if defined(OS_LINUX)
671 #define MAYBE_RestoreAllWithTitlebarClick DISABLED_RestoreAllWithTitlebarClick
672 #else
673 #define MAYBE_RestoreAllWithTitlebarClick RestoreAllWithTitlebarClick
674 #endif
675 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_RestoreAllWithTitlebarClick) {
676   // Test with three panels.
677   Panel* panel1 = CreatePanel("PanelTest1");
678   Panel* panel2 = CreatePanel("PanelTest2");
679   Panel* panel3 = CreatePanel("PanelTest3");
680   EXPECT_FALSE(panel1->IsMinimized());
681   EXPECT_FALSE(panel2->IsMinimized());
682   EXPECT_FALSE(panel3->IsMinimized());
683
684   scoped_ptr<NativePanelTesting> test_panel1(
685       CreateNativePanelTesting(panel1));
686   scoped_ptr<NativePanelTesting> test_panel2(
687       CreateNativePanelTesting(panel2));
688   scoped_ptr<NativePanelTesting> test_panel3(
689       CreateNativePanelTesting(panel3));
690
691   // Click on an expanded panel's titlebar using the apply-all modifier.
692   // Verify expansion state is unchanged.
693   test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
694                                             panel::APPLY_TO_ALL);
695   test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
696   EXPECT_FALSE(panel1->IsMinimized());
697   EXPECT_FALSE(panel2->IsMinimized());
698   EXPECT_FALSE(panel3->IsMinimized());
699
700   // Click on a minimized panel's titlebar using the apply-all modifier.
701   panel1->Minimize();
702   panel2->Minimize();
703   panel3->Minimize();
704   EXPECT_TRUE(panel1->IsMinimized());
705   EXPECT_TRUE(panel2->IsMinimized());
706   EXPECT_TRUE(panel3->IsMinimized());
707
708   // Nothing changes until mouse is released.
709   test_panel1->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin(),
710                                             panel::APPLY_TO_ALL);
711   EXPECT_TRUE(panel1->IsMinimized());
712   EXPECT_TRUE(panel2->IsMinimized());
713   EXPECT_TRUE(panel3->IsMinimized());
714   // Verify all panels restored when mouse is released.
715   test_panel1->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
716   EXPECT_FALSE(panel1->IsMinimized());
717   EXPECT_FALSE(panel2->IsMinimized());
718   EXPECT_FALSE(panel3->IsMinimized());
719
720   // Minimize a single panel. Then click on expanded panel with apply-all
721   // modifier. Verify nothing changes.
722   panel1->Minimize();
723   EXPECT_TRUE(panel1->IsMinimized());
724   EXPECT_FALSE(panel2->IsMinimized());
725   EXPECT_FALSE(panel3->IsMinimized());
726
727   test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
728                                             panel::APPLY_TO_ALL);
729   test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
730   EXPECT_TRUE(panel1->IsMinimized());
731   EXPECT_FALSE(panel2->IsMinimized());
732   EXPECT_FALSE(panel3->IsMinimized());
733
734   // Minimize another panel. Then click on a minimized panel with apply-all
735   // modifier to restore all panels.
736   panel2->Minimize();
737   EXPECT_TRUE(panel1->IsMinimized());
738   EXPECT_TRUE(panel2->IsMinimized());
739   EXPECT_FALSE(panel3->IsMinimized());
740
741   test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
742                                             panel::APPLY_TO_ALL);
743   test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
744   EXPECT_FALSE(panel1->IsMinimized());
745   EXPECT_FALSE(panel2->IsMinimized());
746   EXPECT_FALSE(panel3->IsMinimized());
747
748   // Click on the single minimized panel. Verify all are restored.
749   panel1->Minimize();
750   EXPECT_TRUE(panel1->IsMinimized());
751   EXPECT_FALSE(panel2->IsMinimized());
752   EXPECT_FALSE(panel3->IsMinimized());
753
754   test_panel1->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin(),
755                                             panel::APPLY_TO_ALL);
756   test_panel1->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
757   EXPECT_FALSE(panel1->IsMinimized());
758   EXPECT_FALSE(panel2->IsMinimized());
759   EXPECT_FALSE(panel3->IsMinimized());
760
761   // Click on the single expanded panel. Verify nothing changes.
762   panel1->Minimize();
763   panel3->Minimize();
764   EXPECT_TRUE(panel1->IsMinimized());
765   EXPECT_FALSE(panel2->IsMinimized());
766   EXPECT_TRUE(panel3->IsMinimized());
767
768   test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
769                                             panel::APPLY_TO_ALL);
770   test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
771   EXPECT_TRUE(panel1->IsMinimized());
772   EXPECT_FALSE(panel2->IsMinimized());
773   EXPECT_TRUE(panel3->IsMinimized());
774
775   // Hover over a minimized panel and click on the titlebar while it is in
776   // title-only mode. Should restore all panels.
777   panel2->Minimize();
778   EXPECT_TRUE(panel1->IsMinimized());
779   EXPECT_TRUE(panel2->IsMinimized());
780   EXPECT_TRUE(panel3->IsMinimized());
781
782   MoveMouseAndWaitForExpansionStateChange(panel2, panel2->GetBounds().origin());
783   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
784   EXPECT_EQ(Panel::TITLE_ONLY, panel2->expansion_state());
785   EXPECT_EQ(Panel::TITLE_ONLY, panel3->expansion_state());
786
787   test_panel3->PressLeftMouseButtonTitlebar(panel3->GetBounds().origin(),
788                                             panel::APPLY_TO_ALL);
789   test_panel3->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
790   EXPECT_FALSE(panel1->IsMinimized());
791   EXPECT_FALSE(panel2->IsMinimized());
792   EXPECT_FALSE(panel3->IsMinimized());
793
794   // Draw attention to a minimized panel. Click on a minimized panel that is
795   // not drawing attention. Verify restore all applies without affecting
796   // draw attention.
797   panel1->Minimize();
798   panel2->Minimize();
799   panel3->Minimize();
800   EXPECT_TRUE(panel1->IsMinimized());
801   EXPECT_TRUE(panel2->IsMinimized());
802   EXPECT_TRUE(panel3->IsMinimized());
803
804   panel1->FlashFrame(true);
805   EXPECT_TRUE(panel1->IsDrawingAttention());
806
807   test_panel2->PressLeftMouseButtonTitlebar(panel2->GetBounds().origin(),
808                                             panel::APPLY_TO_ALL);
809   test_panel2->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
810   EXPECT_FALSE(panel1->IsMinimized());
811   EXPECT_FALSE(panel2->IsMinimized());
812   EXPECT_FALSE(panel3->IsMinimized());
813   EXPECT_TRUE(panel1->IsDrawingAttention());
814
815   // Restore all panels by clicking on the minimized panel that is drawing
816   // attention. Verify restore all applies and clears draw attention.
817   panel1->Minimize();
818   panel2->Minimize();
819   panel3->Minimize();
820   EXPECT_TRUE(panel1->IsMinimized());
821   EXPECT_TRUE(panel2->IsMinimized());
822   EXPECT_TRUE(panel3->IsMinimized());
823
824   test_panel1->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin(),
825                                             panel::APPLY_TO_ALL);
826   test_panel1->ReleaseMouseButtonTitlebar(panel::APPLY_TO_ALL);
827   EXPECT_FALSE(panel1->IsMinimized());
828   EXPECT_FALSE(panel2->IsMinimized());
829   EXPECT_FALSE(panel3->IsMinimized());
830   EXPECT_FALSE(panel1->IsDrawingAttention());
831
832   PanelManager::GetInstance()->CloseAll();
833 }
834
835 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
836                        MinimizeRestoreOnAutoHidingDesktopBar) {
837   PanelManager* panel_manager = PanelManager::GetInstance();
838   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
839   int expected_bottom_on_expanded = docked_collection->work_area().bottom();
840   int expected_bottom_on_title_only = expected_bottom_on_expanded;
841   int expected_bottom_on_minimized = expected_bottom_on_expanded;
842
843   // Turn on auto-hiding.
844   static const int bottom_bar_thickness = 40;
845   mock_display_settings_provider()->EnableAutoHidingDesktopBar(
846       DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM,
847       true,
848       bottom_bar_thickness);
849   expected_bottom_on_title_only -= bottom_bar_thickness;
850
851   Panel* panel = CreatePanel("1");
852   int initial_height = panel->GetBounds().height();
853
854   EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
855   EXPECT_EQ(expected_bottom_on_expanded, panel->GetBounds().bottom());
856
857   panel->Minimize();
858   WaitForBoundsAnimationFinished(panel);
859   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
860   EXPECT_EQ(panel::kMinimizedPanelHeight, panel->GetBounds().height());
861   EXPECT_EQ(expected_bottom_on_minimized, panel->GetBounds().bottom());
862
863   panel->SetExpansionState(Panel::TITLE_ONLY);
864   WaitForBoundsAnimationFinished(panel);
865   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
866   EXPECT_EQ(panel::kTitlebarHeight, panel->GetBounds().height());
867   EXPECT_EQ(expected_bottom_on_title_only, panel->GetBounds().bottom());
868
869   panel->Restore();
870   WaitForBoundsAnimationFinished(panel);
871   EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
872   EXPECT_EQ(initial_height, panel->GetBounds().height());
873   EXPECT_EQ(expected_bottom_on_expanded, panel->GetBounds().bottom());
874
875   panel->Close();
876 }
877
878 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, ChangeAutoHideTaskBarThickness) {
879   PanelManager* manager = PanelManager::GetInstance();
880   DockedPanelCollection* docked_collection = manager->docked_collection();
881   int initial_starting_right_position =
882       docked_collection->StartingRightPosition();
883
884   int bottom_bar_thickness = 20;
885   int right_bar_thickness = 30;
886   mock_display_settings_provider()->EnableAutoHidingDesktopBar(
887       DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM,
888       true,
889       bottom_bar_thickness);
890   mock_display_settings_provider()->EnableAutoHidingDesktopBar(
891       DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_RIGHT,
892       true,
893       right_bar_thickness);
894   EXPECT_EQ(initial_starting_right_position,
895             docked_collection->StartingRightPosition());
896
897   Panel* panel = CreatePanel("PanelTest");
898   panel->SetExpansionState(Panel::TITLE_ONLY);
899   WaitForBoundsAnimationFinished(panel);
900
901   EXPECT_EQ(docked_collection->work_area().bottom() - bottom_bar_thickness,
902             panel->GetBounds().bottom());
903   EXPECT_EQ(docked_collection->StartingRightPosition(),
904             panel->GetBounds().right());
905
906   initial_starting_right_position = docked_collection->StartingRightPosition();
907   int bottom_bar_thickness_delta = 10;
908   bottom_bar_thickness += bottom_bar_thickness_delta;
909   int right_bar_thickness_delta = 15;
910   right_bar_thickness += right_bar_thickness_delta;
911   mock_display_settings_provider()->SetDesktopBarThickness(
912       DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM,
913       bottom_bar_thickness);
914   mock_display_settings_provider()->SetDesktopBarThickness(
915       DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_RIGHT,
916       right_bar_thickness);
917   base::MessageLoopForUI::current()->RunUntilIdle();
918   EXPECT_EQ(initial_starting_right_position,
919             docked_collection->StartingRightPosition());
920   EXPECT_EQ(docked_collection->work_area().bottom() - bottom_bar_thickness,
921             panel->GetBounds().bottom());
922   EXPECT_EQ(docked_collection->StartingRightPosition(),
923             panel->GetBounds().right());
924
925   initial_starting_right_position = docked_collection->StartingRightPosition();
926   bottom_bar_thickness_delta = 20;
927   bottom_bar_thickness -= bottom_bar_thickness_delta;
928   right_bar_thickness_delta = 10;
929   right_bar_thickness -= right_bar_thickness_delta;
930   mock_display_settings_provider()->SetDesktopBarThickness(
931       DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM,
932       bottom_bar_thickness);
933   mock_display_settings_provider()->SetDesktopBarThickness(
934       DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_RIGHT,
935       right_bar_thickness);
936   base::MessageLoopForUI::current()->RunUntilIdle();
937   EXPECT_EQ(docked_collection->StartingRightPosition(),
938             initial_starting_right_position);
939   EXPECT_EQ(docked_collection->work_area().bottom() - bottom_bar_thickness,
940             panel->GetBounds().bottom());
941   EXPECT_EQ(docked_collection->StartingRightPosition(),
942             panel->GetBounds().right());
943
944   panel->Close();
945 }
946
947 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, ActivatePanelOrTabbedWindow) {
948   if (!WmSupportWindowActivation()) {
949     LOG(WARNING) << "Skipping test due to WM problems.";
950     return;
951   }
952
953   Panel* panel1 = CreatePanel("Panel1");
954   Panel* panel2 = CreatePanel("Panel2");
955
956   // Activate main tabbed window.
957   browser()->window()->Activate();
958   WaitForPanelActiveState(panel2, SHOW_AS_INACTIVE);
959
960   // Activate a panel.
961   panel2->Activate();
962   WaitForPanelActiveState(panel2, SHOW_AS_ACTIVE);
963
964   // Activate the main tabbed window back.
965   browser()->window()->Activate();
966   WaitForPanelActiveState(panel2, SHOW_AS_INACTIVE);
967
968   // Activate another panel.
969   panel1->Activate();
970   WaitForPanelActiveState(panel1, SHOW_AS_ACTIVE);
971   WaitForPanelActiveState(panel2, SHOW_AS_INACTIVE);
972
973   // Switch focus between panels.
974   panel2->Activate();
975   WaitForPanelActiveState(panel2, SHOW_AS_ACTIVE);
976   WaitForPanelActiveState(panel1, SHOW_AS_INACTIVE);
977
978   PanelManager::GetInstance()->CloseAll();
979 }
980
981 // TODO(jianli): To be enabled for other platforms.
982 #if defined(OS_WIN) || defined(OS_LINUX)
983 #define MAYBE_ActivateDeactivateBasic ActivateDeactivateBasic
984 #else
985 #define MAYBE_ActivateDeactivateBasic DISABLED_ActivateDeactivateBasic
986 #endif
987 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_ActivateDeactivateBasic) {
988   if (!WmSupportWindowActivation()) {
989     LOG(WARNING) << "Skipping test due to WM problems.";
990     return;
991   }
992
993   // Create an active panel.
994   Panel* panel = CreatePanel("PanelTest");
995   scoped_ptr<NativePanelTesting> native_panel_testing(
996       CreateNativePanelTesting(panel));
997
998   WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);  // doublecheck active state
999   EXPECT_TRUE(native_panel_testing->VerifyActiveState(true));
1000
1001   // Deactivate the panel.
1002   panel->Deactivate();
1003   WaitForPanelActiveState(panel, SHOW_AS_INACTIVE);
1004
1005   // On GTK there is no way to deactivate a window. So the Deactivate() call
1006   // above does not actually deactivate the window, but simply lowers it.
1007 #if !defined(OS_LINUX)
1008   EXPECT_TRUE(native_panel_testing->VerifyActiveState(false));
1009 #endif
1010
1011   // This test does not reactivate the panel because the panel might not be
1012   // reactivated programmatically once it is deactivated.
1013 }
1014
1015 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, ActivateDeactivateMultiple) {
1016   if (!WmSupportWindowActivation()) {
1017     LOG(WARNING) << "Skipping test due to WM problems.";
1018     return;
1019   }
1020
1021   BrowserWindow* tabbed_window = browser()->window();
1022
1023   // Create 4 panels in the following screen layout:
1024   //    P3  P2  P1  P0
1025   const int kNumPanels = 4;
1026   for (int i = 0; i < kNumPanels; ++i)
1027     CreatePanelWithBounds(MakePanelName(i), gfx::Rect(0, 0, 100, 100));
1028   const std::vector<Panel*>& panels = PanelManager::GetInstance()->panels();
1029
1030   std::vector<bool> expected_active_states;
1031   std::vector<bool> last_active_states;
1032
1033   // The last created panel, P3, should be active.
1034   expected_active_states = ProduceExpectedActiveStates(3);
1035   EXPECT_EQ(expected_active_states, GetAllPanelActiveStates());
1036   EXPECT_FALSE(tabbed_window->IsActive());
1037
1038   // Activating P1 should cause P3 to lose focus.
1039   panels[1]->Activate();
1040   last_active_states = expected_active_states;
1041   expected_active_states = ProduceExpectedActiveStates(1);
1042   WaitForPanelActiveStates(last_active_states, expected_active_states);
1043   EXPECT_EQ(expected_active_states, GetAllPanelActiveStates());
1044
1045   // Minimizing inactive panel P2 should not affect other panels' active states.
1046   panels[2]->SetExpansionState(Panel::MINIMIZED);
1047   EXPECT_EQ(expected_active_states, GetAllPanelActiveStates());
1048   EXPECT_FALSE(tabbed_window->IsActive());
1049 }
1050
1051 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DrawAttentionBasic) {
1052   Panel* panel = CreateInactivePanel("P1");
1053   scoped_ptr<NativePanelTesting> native_panel_testing(
1054       CreateNativePanelTesting(panel));
1055
1056   // Test that the attention is drawn when the expanded panel is not in focus.
1057   EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
1058   EXPECT_FALSE(panel->IsActive());
1059   EXPECT_FALSE(panel->IsDrawingAttention());
1060   panel->FlashFrame(true);
1061   EXPECT_TRUE(panel->IsDrawingAttention());
1062   EXPECT_TRUE(native_panel_testing->VerifyDrawingAttention());
1063
1064   // Stop drawing attention.
1065   panel->FlashFrame(false);
1066   EXPECT_FALSE(panel->IsDrawingAttention());
1067   EXPECT_FALSE(native_panel_testing->VerifyDrawingAttention());
1068
1069   // Draw attention, then minimize. Titlebar should remain visible.
1070   panel->FlashFrame(true);
1071   EXPECT_TRUE(panel->IsDrawingAttention());
1072
1073   panel->Minimize();
1074   EXPECT_TRUE(panel->IsDrawingAttention());
1075   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
1076
1077   // Stop drawing attention. Titlebar should no longer be visible.
1078   panel->FlashFrame(false);
1079   EXPECT_FALSE(panel->IsDrawingAttention());
1080   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
1081
1082   panel->Close();
1083 }
1084
1085 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DrawAttentionWhileMinimized) {
1086   Panel* panel1 = CreateInactivePanel("P1");
1087   Panel* panel2 = CreateInactivePanel("P2");
1088
1089   scoped_ptr<NativePanelTesting> native_panel1_testing(
1090       CreateNativePanelTesting(panel1));
1091
1092   // Test that the attention is drawn and the title-bar is brought up when the
1093   // minimized panel is drawing attention.
1094   panel1->Minimize();
1095   EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
1096   panel1->FlashFrame(true);
1097   EXPECT_TRUE(panel1->IsDrawingAttention());
1098   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1099   EXPECT_TRUE(native_panel1_testing->VerifyDrawingAttention());
1100
1101   // Test that we cannot bring up other minimized panel if the mouse is over
1102   // the panel that draws attension.
1103   panel2->Minimize();
1104   gfx::Point hover_point(panel1->GetBounds().origin());
1105   MoveMouse(hover_point);
1106   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1107   EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
1108
1109   // Test that we cannot bring down the panel that is drawing the attention.
1110   hover_point.set_y(hover_point.y() - 200);
1111   MoveMouse(hover_point);
1112   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1113
1114   // Test that the attention is cleared when activated.
1115   panel1->Activate();
1116   WaitForPanelActiveState(panel1, SHOW_AS_ACTIVE);
1117   EXPECT_FALSE(panel1->IsDrawingAttention());
1118   EXPECT_EQ(Panel::EXPANDED, panel1->expansion_state());
1119   EXPECT_FALSE(native_panel1_testing->VerifyDrawingAttention());
1120
1121   PanelManager::GetInstance()->CloseAll();
1122 }
1123
1124 // Verify that minimized state of a panel is correct after draw attention
1125 // is stopped when there are other minimized panels.
1126 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, StopDrawingAttentionWhileMinimized) {
1127   Panel* panel1 = CreateInactivePanel("P1");
1128   Panel* panel2 = CreateInactivePanel("P2");
1129
1130   panel1->Minimize();
1131   EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
1132   panel2->Minimize();
1133   EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
1134
1135   // Verify panel returns to minimized state when no longer drawing attention.
1136   panel1->FlashFrame(true);
1137   EXPECT_TRUE(panel1->IsDrawingAttention());
1138   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1139
1140   panel1->FlashFrame(false);
1141   EXPECT_FALSE(panel1->IsDrawingAttention());
1142   EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
1143
1144   // Hover over other minimized panel to bring up titlebars.
1145   gfx::Point hover_point(panel2->GetBounds().origin());
1146   MoveMouseAndWaitForExpansionStateChange(panel1, hover_point);
1147   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1148   EXPECT_EQ(Panel::TITLE_ONLY, panel2->expansion_state());
1149
1150   // Verify panel keeps titlebar visible when no longer drawing attention
1151   // if titlebars are up.
1152   panel1->FlashFrame(true);
1153   EXPECT_TRUE(panel1->IsDrawingAttention());
1154   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1155
1156   panel1->FlashFrame(false);
1157   EXPECT_FALSE(panel1->IsDrawingAttention());
1158   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1159
1160   // Move mouse away. All panels should return to minimized state.
1161   hover_point.set_y(hover_point.y() - 200);
1162   MoveMouseAndWaitForExpansionStateChange(panel1, hover_point);
1163   EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
1164   EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
1165
1166   // Verify minimized panel that is drawing attention stays in title-only mode
1167   // after attention is cleared if mouse is in the titlebar area.
1168   panel1->FlashFrame(true);
1169   EXPECT_TRUE(panel1->IsDrawingAttention());
1170   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1171
1172   gfx::Point hover_point_in_panel(panel1->GetBounds().origin());
1173   MoveMouse(hover_point_in_panel);
1174
1175   panel1->FlashFrame(false);
1176   EXPECT_FALSE(panel1->IsDrawingAttention());
1177   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1178   EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
1179
1180   // Typical user scenario will detect the mouse in the panel
1181   // after attention is cleared, causing titles to pop up, so
1182   // we simulate that here.
1183   MoveMouseAndWaitForExpansionStateChange(panel2, hover_point_in_panel);
1184   EXPECT_EQ(Panel::TITLE_ONLY, panel1->expansion_state());
1185   EXPECT_EQ(Panel::TITLE_ONLY, panel2->expansion_state());
1186
1187   // Move mouse away and panels should go back to fully minimized state.
1188   MoveMouseAndWaitForExpansionStateChange(panel1, hover_point);
1189   EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
1190   EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
1191
1192   PanelManager::GetInstance()->CloseAll();
1193 }
1194
1195 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DrawAttentionWhenActive) {
1196   // Create an active panel.
1197   Panel* panel = CreatePanel("P1");
1198   scoped_ptr<NativePanelTesting> native_panel_testing(
1199       CreateNativePanelTesting(panel));
1200
1201   // Test that the attention should not be drawn if the expanded panel is in
1202   // focus.
1203   panel->FlashFrame(true);
1204   EXPECT_FALSE(panel->IsDrawingAttention());
1205   EXPECT_FALSE(native_panel_testing->VerifyDrawingAttention());
1206
1207   panel->Close();
1208 }
1209
1210 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DrawAttentionResetOnActivate) {
1211   Panel* panel = CreateInactivePanel("P1");
1212   scoped_ptr<NativePanelTesting> native_panel_testing(
1213       CreateNativePanelTesting(panel));
1214
1215   panel->FlashFrame(true);
1216   EXPECT_TRUE(panel->IsDrawingAttention());
1217   EXPECT_TRUE(native_panel_testing->VerifyDrawingAttention());
1218
1219   // Test that the attention is cleared when panel gets focus.
1220   panel->Activate();
1221   WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);
1222   EXPECT_FALSE(panel->IsDrawingAttention());
1223   EXPECT_FALSE(native_panel_testing->VerifyDrawingAttention());
1224
1225   panel->Close();
1226 }
1227
1228 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1229                        DrawAttentionMinimizedNotResetOnActivate) {
1230   Panel* panel = CreateInactivePanel("P1");
1231
1232   panel->Minimize();
1233   EXPECT_TRUE(panel->IsMinimized());
1234   panel->FlashFrame(true);
1235   EXPECT_TRUE(panel->IsDrawingAttention());
1236
1237   // Simulate panel being activated while minimized. Cannot call
1238   // Activate() as that expands the panel.
1239   panel->OnActiveStateChanged(true);
1240   EXPECT_TRUE(panel->IsDrawingAttention());  // Unchanged.
1241
1242   // Unminimize panel to show that attention would have been cleared
1243   // if panel had not been minimized.
1244   panel->Restore();
1245   EXPECT_FALSE(panel->IsMinimized());
1246   EXPECT_TRUE(panel->IsDrawingAttention());  // Unchanged.
1247
1248   panel->OnActiveStateChanged(true);
1249   EXPECT_FALSE(panel->IsDrawingAttention());  // Attention cleared.
1250
1251   panel->Close();
1252 }
1253
1254 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DrawAttentionResetOnClick) {
1255   Panel* panel = CreateInactivePanel("P1");
1256   scoped_ptr<NativePanelTesting> native_panel_testing(
1257       CreateNativePanelTesting(panel));
1258
1259   panel->FlashFrame(true);
1260   EXPECT_TRUE(panel->IsDrawingAttention());
1261   EXPECT_TRUE(native_panel_testing->VerifyDrawingAttention());
1262
1263   // Test that the attention is cleared when panel gets focus.
1264   native_panel_testing->PressLeftMouseButtonTitlebar(
1265       panel->GetBounds().origin());
1266   native_panel_testing->ReleaseMouseButtonTitlebar();
1267
1268   WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);
1269   EXPECT_FALSE(panel->IsDrawingAttention());
1270   EXPECT_FALSE(native_panel_testing->VerifyDrawingAttention());
1271
1272   panel->Close();
1273 }
1274
1275 // http://crbug.com/175760; several panel tests failing regularly on mac.
1276 #if defined(OS_MACOSX)
1277 #define MAYBE_MinimizeImmediatelyAfterRestore \
1278   DISABLED_MinimizeImmediatelyAfterRestore
1279 #else
1280 #define MAYBE_MinimizeImmediatelyAfterRestore MinimizeImmediatelyAfterRestore
1281 #endif
1282 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1283                        MAYBE_MinimizeImmediatelyAfterRestore) {
1284   CreatePanelParams params("Panel Test", gfx::Rect(), SHOW_AS_ACTIVE);
1285   Panel* panel = CreatePanelWithParams(params);
1286   scoped_ptr<NativePanelTesting> native_panel_testing(
1287       CreateNativePanelTesting(panel));
1288
1289   PanelActiveStateObserver signal(panel, false);
1290   panel->Minimize();  // this should deactivate.
1291   signal.Wait();
1292   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
1293
1294   panel->Restore();
1295   EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
1296
1297   // Verify that minimizing a panel right after expansion works.
1298   panel->Minimize();
1299   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
1300
1301   panel->Close();
1302 }
1303
1304 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, FocusLostOnMinimize) {
1305   CreatePanelParams params("Initially Active", gfx::Rect(), SHOW_AS_ACTIVE);
1306   Panel* panel = CreatePanelWithParams(params);
1307   EXPECT_EQ(Panel::EXPANDED, panel->expansion_state());
1308
1309   PanelActiveStateObserver signal(panel, false);
1310   panel->Minimize();
1311   signal.Wait();
1312   panel->Close();
1313 }
1314
1315 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, CreateInactiveSwitchToActive) {
1316   Panel* panel = CreateInactivePanel("1");
1317
1318   panel->Activate();
1319   WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);
1320
1321   panel->Close();
1322 }
1323
1324 // TODO(dimich): try/enable on other platforms. See bug 103253 for details on
1325 // why this is disabled on windows.
1326 #if defined(OS_MACOSX)
1327 #define MAYBE_MinimizeTwoPanelsWithoutTabbedWindow \
1328     MinimizeTwoPanelsWithoutTabbedWindow
1329 #else
1330 #define MAYBE_MinimizeTwoPanelsWithoutTabbedWindow \
1331     DISABLED_MinimizeTwoPanelsWithoutTabbedWindow
1332 #endif
1333
1334 // When there are 2 panels and no chrome window, minimizing one panel does
1335 // not expand/focuses another.
1336 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1337                        MAYBE_MinimizeTwoPanelsWithoutTabbedWindow) {
1338   CreatePanelParams params("Initially Inactive", gfx::Rect(), SHOW_AS_INACTIVE);
1339   Panel* panel1 = CreatePanelWithParams(params);
1340   Panel* panel2 = CreatePanelWithParams(params);
1341
1342   // Close main tabbed window.
1343   content::WindowedNotificationObserver signal(
1344       chrome::NOTIFICATION_BROWSER_CLOSED,
1345       content::Source<Browser>(browser()));
1346   chrome::CloseWindow(browser());
1347   signal.Wait();
1348
1349   EXPECT_EQ(Panel::EXPANDED, panel1->expansion_state());
1350   EXPECT_EQ(Panel::EXPANDED, panel2->expansion_state());
1351   panel1->Activate();
1352   WaitForPanelActiveState(panel1, SHOW_AS_ACTIVE);
1353
1354   panel1->SetExpansionState(Panel::MINIMIZED);
1355   base::MessageLoop::current()->RunUntilIdle();
1356   WaitForPanelActiveState(panel1, SHOW_AS_INACTIVE);
1357   EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
1358
1359   panel2->SetExpansionState(Panel::MINIMIZED);
1360   base::MessageLoop::current()->RunUntilIdle();
1361   WaitForPanelActiveState(panel2, SHOW_AS_INACTIVE);
1362   EXPECT_EQ(Panel::MINIMIZED, panel2->expansion_state());
1363
1364   // Verify that panel1 is still minimized and not active.
1365   WaitForPanelActiveState(panel1, SHOW_AS_INACTIVE);
1366   EXPECT_EQ(Panel::MINIMIZED, panel1->expansion_state());
1367
1368   // Another check for the same.
1369   EXPECT_FALSE(panel1->IsActive());
1370   EXPECT_FALSE(panel2->IsActive());
1371
1372   panel1->Close();
1373   panel2->Close();
1374 }
1375
1376 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1377                        NonExtensionDomainPanelsCloseOnUninstall) {
1378   // Create a test extension.
1379   base::DictionaryValue empty_value;
1380   scoped_refptr<extensions::Extension> extension =
1381       CreateExtension(FILE_PATH_LITERAL("TestExtension"),
1382                       extensions::Manifest::INTERNAL, empty_value);
1383   std::string extension_app_name =
1384       web_app::GenerateApplicationNameFromExtensionId(extension->id());
1385
1386   PanelManager* panel_manager = PanelManager::GetInstance();
1387   EXPECT_EQ(0, panel_manager->num_panels());
1388
1389   // Create a panel with the extension as host.
1390   CreatePanelParams params(extension_app_name, gfx::Rect(), SHOW_AS_ACTIVE);
1391   std::string extension_domain_url(extensions::kExtensionScheme);
1392   extension_domain_url += "://";
1393   extension_domain_url += extension->id();
1394   extension_domain_url += "/hello.html";
1395   params.url = GURL(extension_domain_url);
1396   Panel* panel = CreatePanelWithParams(params);
1397   EXPECT_EQ(1, panel_manager->num_panels());
1398
1399   // Create a panel with a non-extension host.
1400   CreatePanelParams params1(extension_app_name, gfx::Rect(), SHOW_AS_ACTIVE);
1401   params1.url = GURL(url::kAboutBlankURL);
1402   Panel* panel1 = CreatePanelWithParams(params1);
1403   EXPECT_EQ(2, panel_manager->num_panels());
1404
1405   // Create another extension and a panel from that extension.
1406   scoped_refptr<extensions::Extension> extension_other =
1407       CreateExtension(FILE_PATH_LITERAL("TestExtensionOther"),
1408                       extensions::Manifest::INTERNAL, empty_value);
1409   std::string extension_app_name_other =
1410       web_app::GenerateApplicationNameFromExtensionId(extension_other->id());
1411   Panel* panel_other = CreatePanel(extension_app_name_other);
1412
1413   content::WindowedNotificationObserver signal(
1414       chrome::NOTIFICATION_PANEL_CLOSED,
1415       content::Source<Panel>(panel));
1416   content::WindowedNotificationObserver signal1(
1417       chrome::NOTIFICATION_PANEL_CLOSED,
1418       content::Source<Panel>(panel1));
1419
1420   // Send unload notification on the first extension.
1421   extensions::UnloadedExtensionInfo details(
1422       extension.get(), extensions::UnloadedExtensionInfo::REASON_UNINSTALL);
1423   content::NotificationService::current()->Notify(
1424       extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
1425       content::Source<Profile>(browser()->profile()),
1426       content::Details<extensions::UnloadedExtensionInfo>(&details));
1427
1428   // Wait for the panels opened by the first extension to close.
1429   signal.Wait();
1430   signal1.Wait();
1431
1432   // Verify that the panel that's left is the panel from the second extension.
1433   EXPECT_EQ(panel_other, panel_manager->panels()[0]);
1434   panel_other->Close();
1435 }
1436
1437 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, OnBeforeUnloadOnClose) {
1438   PanelManager* panel_manager = PanelManager::GetInstance();
1439   EXPECT_EQ(0, panel_manager->num_panels()); // No panels initially.
1440
1441   const base::string16 title_first_close = base::UTF8ToUTF16("TitleFirstClose");
1442   const base::string16 title_second_close =
1443       base::UTF8ToUTF16("TitleSecondClose");
1444
1445   // Create a test panel with web contents loaded.
1446   CreatePanelParams params("PanelTest1", gfx::Rect(0, 0, 300, 300),
1447                            SHOW_AS_ACTIVE);
1448   params.url = ui_test_utils::GetTestUrl(
1449       base::FilePath(kTestDir),
1450       base::FilePath(FILE_PATH_LITERAL("onbeforeunload.html")));
1451   Panel* panel = CreatePanelWithParams(params);
1452   EXPECT_EQ(1, panel_manager->num_panels());
1453
1454   // Close panel and verify it closes despite having a onbeforeunload handler.
1455   CloseWindowAndWait(panel);
1456   EXPECT_EQ(0, panel_manager->num_panels());
1457 }
1458
1459 // http://crbug.com/175760; several panel tests failing regularly on mac.
1460 #if defined(OS_MACOSX)
1461 #define MAYBE_SizeClamping DISABLED_SizeClamping
1462 #else
1463 #define MAYBE_SizeClamping SizeClamping
1464 #endif
1465 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_SizeClamping) {
1466   // Using '0' sizes is equivalent of not providing sizes in API and causes
1467   // minimum sizes to be applied to facilitate auto-sizing.
1468   CreatePanelParams params("Panel", gfx::Rect(), SHOW_AS_ACTIVE);
1469   Panel* panel = CreatePanelWithParams(params);
1470   EXPECT_EQ(panel->min_size().width(), panel->GetBounds().width());
1471   EXPECT_EQ(panel->min_size().height(), panel->GetBounds().height());
1472   int reasonable_width = panel->min_size().width() + 10;
1473   int reasonable_height = panel->min_size().height() + 20;
1474
1475   panel->Close();
1476
1477   // Using reasonable actual sizes should avoid clamping.
1478   CreatePanelParams params1("Panel1",
1479                             gfx::Rect(0, 0,
1480                                       reasonable_width, reasonable_height),
1481                             SHOW_AS_ACTIVE);
1482   panel = CreatePanelWithParams(params1);
1483   EXPECT_EQ(reasonable_width, panel->GetBounds().width());
1484   EXPECT_EQ(reasonable_height, panel->GetBounds().height());
1485   panel->Close();
1486
1487   // Using just one size should auto-compute some reasonable other size.
1488   int given_height = 200;
1489   CreatePanelParams params2("Panel2", gfx::Rect(0, 0, 0, given_height),
1490                             SHOW_AS_ACTIVE);
1491   panel = CreatePanelWithParams(params2);
1492   EXPECT_GT(panel->GetBounds().width(), 0);
1493   EXPECT_EQ(given_height, panel->GetBounds().height());
1494   panel->Close();
1495 }
1496
1497 // http://crbug.com/175760; several panel tests failing regularly on mac.
1498 // http://crbug.com/179890; TightAutosizeAroundSingleLine broken on Windows by
1499 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1500                        DISABLED_TightAutosizeAroundSingleLine) {
1501   PanelManager::GetInstance()->enable_auto_sizing(true);
1502   // Using 0 sizes triggers auto-sizing.
1503   CreatePanelParams params("Panel", gfx::Rect(), SHOW_AS_ACTIVE);
1504   params.url = GURL("data:text/html;charset=utf-8,<!doctype html><body>");
1505   Panel* panel = CreatePanelWithParams(params);
1506
1507   // Ensure panel has auto resized to original web content size.
1508   WaitForStableInitialSize initial_resize(panel);
1509   initial_resize.Wait();
1510
1511   int initial_width = panel->GetBounds().width();
1512   int initial_height = panel->GetBounds().height();
1513
1514   // Inject some HTML content into the panel.
1515   WaitForAutoResizeWider enlarge(panel);
1516   EXPECT_TRUE(content::ExecuteScript(
1517       panel->GetWebContents(),
1518       "document.body.innerHTML ="
1519       "    '<nobr>line of text and a <button>Button</button>';"));
1520   enlarge.Wait();
1521
1522   // The panel should have become larger in both dimensions (the minimums
1523   // has to be set to be smaller then a simple 1-line content, so the autosize
1524   // can work correctly.
1525   EXPECT_GT(panel->GetBounds().width(), initial_width);
1526   EXPECT_GT(panel->GetBounds().height(), initial_height);
1527
1528   panel->Close();
1529 }
1530
1531 // http://crbug.com/175760; several panel tests failing regularly on mac.
1532 #if defined(OS_MACOSX)
1533 #define MAYBE_DefaultMaxSizeOnDisplaySettingsChange \
1534         DISABLED_DefaultMaxSizeOnDisplaySettingsChange
1535 #else
1536 #define MAYBE_DefaultMaxSizeOnDisplaySettingsChange \
1537         DefaultMaxSizeOnDisplaySettingsChange
1538 #endif
1539 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1540                        MAYBE_DefaultMaxSizeOnDisplaySettingsChange) {
1541   Panel* panel = CreatePanelWithBounds("1", gfx::Rect(0, 0, 240, 220));
1542
1543   gfx::Size old_max_size = panel->max_size();
1544   gfx::Size old_full_size = panel->full_size();
1545
1546   // Shrink the work area. Expect max size and full size become smaller.
1547   gfx::Rect smaller_work_area(0, 0, 500, 300);
1548   mock_display_settings_provider()->SetPrimaryDisplay(
1549       smaller_work_area, smaller_work_area);
1550   EXPECT_GT(old_max_size.width(), panel->max_size().width());
1551   EXPECT_GT(old_max_size.height(), panel->max_size().height());
1552   EXPECT_GT(smaller_work_area.width(), panel->max_size().width());
1553   EXPECT_GT(smaller_work_area.height(), panel->max_size().height());
1554   EXPECT_GT(old_full_size.width(), panel->full_size().width());
1555   EXPECT_GT(old_full_size.height(), panel->full_size().height());
1556   EXPECT_GE(panel->max_size().width(), panel->full_size().width());
1557   EXPECT_GE(panel->max_size().height(), panel->full_size().height());
1558
1559   panel->Close();
1560 }
1561
1562 // http://crbug.com/175760; several panel tests failing regularly on mac.
1563 #if defined(OS_MACOSX)
1564 #define MAYBE_CustomMaxSizeOnDisplaySettingsChange \
1565         DISABLED_CustomMaxSizeOnDisplaySettingsChange
1566 #else
1567 #define MAYBE_CustomMaxSizeOnDisplaySettingsChange \
1568         CustomMaxSizeOnDisplaySettingsChange
1569 #endif
1570 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1571                        MAYBE_CustomMaxSizeOnDisplaySettingsChange) {
1572   PanelManager* panel_manager = PanelManager::GetInstance();
1573   Panel* panel = CreatePanelWithBounds("1", gfx::Rect(0, 0, 240, 220));
1574
1575   // Trigger custom max size by user resizing.
1576   gfx::Size bigger_size = gfx::Size(550, 400);
1577   gfx::Point mouse_location = panel->GetBounds().origin();
1578   panel_manager->StartResizingByMouse(panel,
1579                                       mouse_location,
1580                                       HTTOPLEFT);
1581   mouse_location.Offset(panel->GetBounds().width() - bigger_size.width(),
1582                         panel->GetBounds().height() - bigger_size.height());
1583   panel_manager->ResizeByMouse(mouse_location);
1584   panel_manager->EndResizingByMouse(false);
1585
1586   gfx::Size old_max_size = panel->max_size();
1587   EXPECT_EQ(bigger_size, old_max_size);
1588   gfx::Size old_full_size = panel->full_size();
1589   EXPECT_EQ(bigger_size, old_full_size);
1590
1591   // Shrink the work area. Expect max size and full size become smaller.
1592   gfx::Rect smaller_work_area(0, 0, 500, 300);
1593   mock_display_settings_provider()->SetPrimaryDisplay(
1594       smaller_work_area, smaller_work_area);
1595   EXPECT_GT(old_max_size.width(), panel->max_size().width());
1596   EXPECT_GT(old_max_size.height(), panel->max_size().height());
1597   EXPECT_GE(smaller_work_area.width(), panel->max_size().width());
1598   EXPECT_EQ(smaller_work_area.height(), panel->max_size().height());
1599   EXPECT_GT(old_full_size.width(), panel->full_size().width());
1600   EXPECT_GT(old_full_size.height(), panel->full_size().height());
1601   EXPECT_GE(panel->max_size().width(), panel->full_size().width());
1602   EXPECT_GE(panel->max_size().height(), panel->full_size().height());
1603   EXPECT_EQ(smaller_work_area.height(), panel->full_size().height());
1604
1605   panel->Close();
1606 }
1607
1608 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DevTools) {
1609   // Create a test panel with web contents loaded.
1610   CreatePanelParams params("1", gfx::Rect(0, 0, 200, 220), SHOW_AS_ACTIVE);
1611   GURL url(ui_test_utils::GetTestUrl(
1612       base::FilePath(kTestDir),
1613       base::FilePath(FILE_PATH_LITERAL("update-preferred-size.html"))));
1614   params.url = url;
1615   Panel* panel = CreatePanelWithParams(params);
1616
1617   // Open devtools.
1618   size_t num_browsers = 1;
1619   EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
1620                               browser()->profile(),
1621                               browser()->host_desktop_type()));
1622   content::WindowedNotificationObserver signal(
1623       chrome::NOTIFICATION_BROWSER_WINDOW_READY,
1624       content::NotificationService::AllSources());
1625   EXPECT_TRUE(panel->ExecuteCommandIfEnabled(IDC_DEV_TOOLS));
1626   signal.Wait();
1627
1628   // Check that the new browser window that opened is dev tools window.
1629   ++num_browsers;
1630   EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
1631                               browser()->profile(),
1632                               browser()->host_desktop_type()));
1633   for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) {
1634     if (*iter == browser())
1635       continue;
1636     ASSERT_TRUE((*iter)->is_devtools());
1637   }
1638
1639   panel->Close();
1640 }
1641
1642 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DevToolsConsole) {
1643   // Create a test panel with web contents loaded.
1644   CreatePanelParams params("1", gfx::Rect(0, 0, 200, 220), SHOW_AS_ACTIVE);
1645   GURL url(ui_test_utils::GetTestUrl(
1646       base::FilePath(kTestDir),
1647       base::FilePath(FILE_PATH_LITERAL("update-preferred-size.html"))));
1648   params.url = url;
1649   Panel* panel = CreatePanelWithParams(params);
1650
1651   // Open devtools console.
1652   size_t num_browsers = 1;
1653   EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
1654                               browser()->profile(),
1655                               browser()->host_desktop_type()));
1656   content::WindowedNotificationObserver signal(
1657       chrome::NOTIFICATION_BROWSER_WINDOW_READY,
1658       content::NotificationService::AllSources());
1659   EXPECT_TRUE(panel->ExecuteCommandIfEnabled(IDC_DEV_TOOLS_CONSOLE));
1660   signal.Wait();
1661
1662   // Check that the new browser window that opened is dev tools window.
1663   ++num_browsers;
1664   EXPECT_EQ(num_browsers, chrome::GetBrowserCount(
1665                               browser()->profile(),
1666                               browser()->host_desktop_type()));
1667   for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) {
1668     if (*iter == browser())
1669       continue;
1670     ASSERT_TRUE((*iter)->is_devtools());
1671   }
1672
1673   panel->Close();
1674 }
1675
1676 #if defined(OS_WIN)
1677 #define MAYBE_Accelerator Accelerator
1678 #else
1679 #define MAYBE_Accelerator DISABLED_Accelerator
1680 #endif
1681 IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_Accelerator) {
1682   PanelManager* panel_manager = PanelManager::GetInstance();
1683
1684   // Create a test panel with web contents loaded.
1685   CreatePanelParams params("1", gfx::Rect(), SHOW_AS_ACTIVE);
1686   GURL url(ui_test_utils::GetTestUrl(
1687       base::FilePath(kTestDir),
1688       base::FilePath(FILE_PATH_LITERAL("update-preferred-size.html"))));
1689   params.url = url;
1690   Panel* panel = CreatePanelWithParams(params);
1691   EXPECT_EQ(1, panel_manager->num_panels());
1692
1693   // Close the panel by acclerator.
1694   content::WindowedNotificationObserver signal(
1695       chrome::NOTIFICATION_PANEL_CLOSED,
1696       content::Source<Panel>(panel));
1697 #if defined(USE_AURA)
1698   double now = ui::EventTimeForNow().InSecondsF();
1699   content::NativeWebKeyboardEvent key_event(
1700       ui::ET_KEY_PRESSED,
1701       false,
1702       ui::VKEY_W,
1703       ui::EF_CONTROL_DOWN,
1704       now);
1705 #elif defined(OS_WIN)
1706   ::MSG key_msg = { NULL, WM_KEYDOWN, ui::VKEY_W, 0 };
1707   content::NativeWebKeyboardEvent key_event(key_msg);
1708   key_event.modifiers = content::NativeWebKeyboardEvent::ControlKey;
1709 #else
1710   content::NativeWebKeyboardEvent key_event;
1711 #endif
1712   panel->HandleKeyboardEvent(key_event);
1713   signal.Wait();
1714   EXPECT_EQ(0, panel_manager->num_panels());
1715 }
1716
1717 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1718                        HideDockedPanelCreatedBeforeFullScreenMode) {
1719   // Create a docked panel.
1720   Panel* panel = CreatePanel("PanelTest");
1721   scoped_ptr<NativePanelTesting> panel_testing(CreateNativePanelTesting(panel));
1722
1723   // Panel should be visible at first.
1724   EXPECT_TRUE(panel_testing->IsWindowVisible());
1725
1726   // Panel should become hidden when entering full-screen mode.
1727   mock_display_settings_provider()->EnableFullScreenMode(true);
1728   EXPECT_FALSE(panel_testing->IsWindowVisible());
1729
1730   // Panel should become visible when leaving full-screen mode.
1731   mock_display_settings_provider()->EnableFullScreenMode(false);
1732   EXPECT_TRUE(panel_testing->IsWindowVisible());
1733
1734   PanelManager::GetInstance()->CloseAll();
1735 }
1736
1737 IN_PROC_BROWSER_TEST_F(PanelBrowserTest,
1738                        HideDockedPanelCreatedOnFullScreenMode) {
1739   // Enable full-screen mode first.
1740   mock_display_settings_provider()->EnableFullScreenMode(true);
1741
1742   // Create a docked panel without waiting for it to be shown since it is not
1743   // supposed to be shown on full-screen mode.
1744   CreatePanelParams params("1", gfx::Rect(0, 0, 250, 200), SHOW_AS_ACTIVE);
1745   params.wait_for_fully_created = false;
1746   Panel* panel = CreatePanelWithParams(params);
1747   scoped_ptr<NativePanelTesting> panel_testing(
1748       CreateNativePanelTesting(panel));
1749
1750   // Panel should not be shown on full-screen mode.
1751   EXPECT_FALSE(panel_testing->IsWindowVisible());
1752
1753   // Panel should become visible when leaving full-screen mode.
1754   mock_display_settings_provider()->EnableFullScreenMode(false);
1755   EXPECT_TRUE(panel_testing->IsWindowVisible());
1756
1757   PanelManager::GetInstance()->CloseAll();
1758 }
1759
1760 class PanelExtensionApiTest : public ExtensionApiTest {
1761  protected:
1762   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1763     ExtensionApiTest::SetUpCommandLine(command_line);
1764     command_line->AppendSwitch(switches::kEnablePanels);
1765   }
1766 };
1767
1768 #if defined(OS_LINUX) || (!defined(OS_WIN) && defined(USE_AURA)) || \
1769     defined(OS_MACOSX)
1770 // Focus test fails if there is no window manager on Linux.
1771 // Aura panels have different behavior that do not apply to this test.
1772 #define MAYBE_FocusChangeEventOnMinimize DISABLED_FocusChangeEventOnMinimize
1773 #else
1774 #define MAYBE_FocusChangeEventOnMinimize FocusChangeEventOnMinimize
1775 #endif
1776 IN_PROC_BROWSER_TEST_F(PanelExtensionApiTest,
1777                        MAYBE_FocusChangeEventOnMinimize) {
1778   // This is needed so the subsequently created panels can be activated.
1779   // On a Mac, it transforms background-only test process into foreground one.
1780   ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
1781   ASSERT_TRUE(RunExtensionTest("panels/focus_change_on_minimize")) << message_;
1782 }