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