1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ui/app_list/views/app_list_view.h" 6 7#include "base/command_line.h" 8#include "base/run_loop.h" 9#include "base/strings/string_util.h" 10#include "base/strings/utf_string_conversions.h" 11#include "testing/gtest/include/gtest/gtest.h" 12#include "ui/app_list/app_list_switches.h" 13#include "ui/app_list/pagination_model.h" 14#include "ui/app_list/search_box_model.h" 15#include "ui/app_list/test/app_list_test_model.h" 16#include "ui/app_list/test/app_list_test_view_delegate.h" 17#include "ui/app_list/views/app_list_folder_view.h" 18#include "ui/app_list/views/app_list_main_view.h" 19#include "ui/app_list/views/apps_container_view.h" 20#include "ui/app_list/views/apps_grid_view.h" 21#include "ui/app_list/views/contents_switcher_view.h" 22#include "ui/app_list/views/contents_view.h" 23#include "ui/app_list/views/search_box_view.h" 24#include "ui/app_list/views/search_result_list_view.h" 25#include "ui/app_list/views/start_page_view.h" 26#include "ui/app_list/views/test/apps_grid_view_test_api.h" 27#include "ui/app_list/views/tile_item_view.h" 28#include "ui/views/controls/textfield/textfield.h" 29#include "ui/views/test/views_test_base.h" 30#include "ui/views/views_delegate.h" 31#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" 32 33namespace app_list { 34namespace test { 35 36namespace { 37 38enum TestType { 39 TEST_TYPE_START = 0, 40 NORMAL = TEST_TYPE_START, 41 LANDSCAPE, 42 EXPERIMENTAL, 43 TEST_TYPE_END, 44}; 45 46bool IsViewAtOrigin(views::View* view) { 47 return view->bounds().origin().IsOrigin(); 48} 49 50size_t GetVisibleTileItemViews(const std::vector<TileItemView*>& tiles) { 51 size_t count = 0; 52 for (std::vector<TileItemView*>::const_iterator it = tiles.begin(); 53 it != tiles.end(); 54 ++it) { 55 if ((*it)->visible()) 56 count++; 57 } 58 return count; 59} 60 61// Choose a set that is 3 regular app list pages and 2 landscape app list pages. 62const int kInitialItems = 34; 63 64class TestTileSearchResult : public SearchResult { 65 public: 66 TestTileSearchResult() { set_display_type(DISPLAY_TILE); } 67 virtual ~TestTileSearchResult() {} 68 69 private: 70 DISALLOW_COPY_AND_ASSIGN(TestTileSearchResult); 71}; 72 73// Allows the same tests to run with different contexts: either an Ash-style 74// root window or a desktop window tree host. 75class AppListViewTestContext { 76 public: 77 AppListViewTestContext(int test_type, gfx::NativeView parent); 78 ~AppListViewTestContext(); 79 80 // Test displaying the app list and performs a standard set of checks on its 81 // top level views. Then closes the window. 82 void RunDisplayTest(); 83 84 // Hides and reshows the app list with a folder open, expecting the main grid 85 // view to be shown. 86 void RunReshowWithOpenFolderTest(); 87 88 // Tests displaying of the experimental app list and shows the start page. 89 void RunStartPageTest(); 90 91 // Tests switching rapidly between multiple pages of the launcher. 92 void RunPageSwitchingAnimationTest(); 93 94 // Tests changing the App List profile. 95 void RunProfileChangeTest(); 96 97 // Tests displaying of the search results. 98 void RunSearchResultsTest(); 99 100 // A standard set of checks on a view, e.g., ensuring it is drawn and visible. 101 static void CheckView(views::View* subview); 102 103 // Invoked when the Widget is closing, and the view it contains is about to 104 // be torn down. This only occurs in a run loop and will be used as a signal 105 // to quit. 106 void NativeWidgetClosing() { 107 view_ = NULL; 108 run_loop_->Quit(); 109 } 110 111 // Whether the experimental "landscape" app launcher UI is being tested. 112 bool is_landscape() const { 113 return test_type_ == LANDSCAPE || test_type_ == EXPERIMENTAL; 114 } 115 116 private: 117 // Switches the active launcher page in the contents view and lays out to 118 // ensure all launcher pages are in the correct position. 119 void ShowContentsViewPageAndVerify(int index); 120 121 // Shows the app list and waits until a paint occurs. 122 void Show(); 123 124 // Closes the app list. This sets |view_| to NULL. 125 void Close(); 126 127 // Gets the PaginationModel owned by |view_|. 128 PaginationModel* GetPaginationModel(); 129 130 const TestType test_type_; 131 scoped_ptr<base::RunLoop> run_loop_; 132 app_list::AppListView* view_; // Owned by native widget. 133 scoped_ptr<app_list::test::AppListTestViewDelegate> delegate_; 134 135 DISALLOW_COPY_AND_ASSIGN(AppListViewTestContext); 136}; 137 138// Extend the regular AppListTestViewDelegate to communicate back to the test 139// context. Note the test context doesn't simply inherit this, because the 140// delegate is owned by the view. 141class UnitTestViewDelegate : public app_list::test::AppListTestViewDelegate { 142 public: 143 UnitTestViewDelegate(AppListViewTestContext* parent) : parent_(parent) {} 144 145 // Overridden from app_list::AppListViewDelegate: 146 virtual bool ShouldCenterWindow() const OVERRIDE { 147 return app_list::switches::IsCenteredAppListEnabled(); 148 } 149 150 // Overridden from app_list::test::AppListTestViewDelegate: 151 virtual void ViewClosing() OVERRIDE { parent_->NativeWidgetClosing(); } 152 153 private: 154 AppListViewTestContext* parent_; 155 156 DISALLOW_COPY_AND_ASSIGN(UnitTestViewDelegate); 157}; 158 159AppListViewTestContext::AppListViewTestContext(int test_type, 160 gfx::NativeView parent) 161 : test_type_(static_cast<TestType>(test_type)) { 162 switch (test_type_) { 163 case NORMAL: 164 break; 165 case LANDSCAPE: 166 base::CommandLine::ForCurrentProcess()->AppendSwitch( 167 switches::kEnableCenteredAppList); 168 break; 169 case EXPERIMENTAL: 170 base::CommandLine::ForCurrentProcess()->AppendSwitch( 171 switches::kEnableExperimentalAppList); 172 break; 173 default: 174 NOTREACHED(); 175 break; 176 } 177 178 delegate_.reset(new UnitTestViewDelegate(this)); 179 view_ = new app_list::AppListView(delegate_.get()); 180 181 // Initialize centered around a point that ensures the window is wholly shown. 182 view_->InitAsBubbleAtFixedLocation(parent, 183 0, 184 gfx::Point(300, 300), 185 views::BubbleBorder::FLOAT, 186 false /* border_accepts_events */); 187} 188 189AppListViewTestContext::~AppListViewTestContext() { 190 // The view observes the PaginationModel which is about to get destroyed, so 191 // if the view is not already deleted by the time this destructor is called, 192 // there will be problems. 193 EXPECT_FALSE(view_); 194} 195 196// static 197void AppListViewTestContext::CheckView(views::View* subview) { 198 ASSERT_TRUE(subview); 199 EXPECT_TRUE(subview->parent()); 200 EXPECT_TRUE(subview->visible()); 201 EXPECT_TRUE(subview->IsDrawn()); 202} 203 204void AppListViewTestContext::ShowContentsViewPageAndVerify(int index) { 205 ContentsView* contents_view = view_->app_list_main_view()->contents_view(); 206 contents_view->SetActivePage(index); 207 contents_view->Layout(); 208 for (int i = 0; i < contents_view->NumLauncherPages(); ++i) { 209 EXPECT_EQ(i == index, IsViewAtOrigin(contents_view->GetPageView(i))); 210 } 211} 212 213void AppListViewTestContext::Show() { 214 view_->GetWidget()->Show(); 215 run_loop_.reset(new base::RunLoop); 216 view_->SetNextPaintCallback(run_loop_->QuitClosure()); 217 run_loop_->Run(); 218 219 EXPECT_TRUE(view_->GetWidget()->IsVisible()); 220} 221 222void AppListViewTestContext::Close() { 223 view_->GetWidget()->Close(); 224 run_loop_.reset(new base::RunLoop); 225 run_loop_->Run(); 226 227 // |view_| should have been deleted and set to NULL via ViewClosing(). 228 EXPECT_FALSE(view_); 229} 230 231PaginationModel* AppListViewTestContext::GetPaginationModel() { 232 return view_->GetAppsPaginationModel(); 233} 234 235void AppListViewTestContext::RunDisplayTest() { 236 EXPECT_FALSE(view_->GetWidget()->IsVisible()); 237 EXPECT_EQ(-1, GetPaginationModel()->total_pages()); 238 delegate_->GetTestModel()->PopulateApps(kInitialItems); 239 240 Show(); 241 242 // Explicitly enforce the exact dimensions of the app list. Feel free to 243 // change these if you need to (they are just here to prevent against 244 // accidental changes to the window size). 245 switch (test_type_) { 246 case NORMAL: 247 EXPECT_EQ("400x500", view_->bounds().size().ToString()); 248 break; 249 case LANDSCAPE: 250 // NOTE: Height should not exceed 402, because otherwise there might not 251 // be enough space to accomodate the virtual keyboard. (LANDSCAPE mode is 252 // enabled by default when the virtual keyboard is enabled.) 253 EXPECT_EQ("576x402", view_->bounds().size().ToString()); 254 break; 255 case EXPERIMENTAL: 256 EXPECT_EQ("768x560", view_->bounds().size().ToString()); 257 break; 258 default: 259 NOTREACHED(); 260 break; 261 } 262 263 if (is_landscape()) 264 EXPECT_EQ(2, GetPaginationModel()->total_pages()); 265 else 266 EXPECT_EQ(3, GetPaginationModel()->total_pages()); 267 EXPECT_EQ(0, GetPaginationModel()->selected_page()); 268 269 // Checks on the main view. 270 AppListMainView* main_view = view_->app_list_main_view(); 271 EXPECT_NO_FATAL_FAILURE(CheckView(main_view)); 272 EXPECT_NO_FATAL_FAILURE(CheckView(main_view->contents_view())); 273 274 EXPECT_TRUE(main_view->contents_view()->IsNamedPageActive( 275 test_type_ == EXPERIMENTAL ? ContentsView::NAMED_PAGE_START 276 : ContentsView::NAMED_PAGE_APPS)); 277 278 Close(); 279} 280 281void AppListViewTestContext::RunReshowWithOpenFolderTest() { 282 EXPECT_FALSE(view_->GetWidget()->IsVisible()); 283 EXPECT_EQ(-1, GetPaginationModel()->total_pages()); 284 285 AppListTestModel* model = delegate_->GetTestModel(); 286 model->PopulateApps(kInitialItems); 287 const std::string folder_id = 288 model->MergeItems(model->top_level_item_list()->item_at(0)->id(), 289 model->top_level_item_list()->item_at(1)->id()); 290 291 AppListFolderItem* folder_item = model->FindFolderItem(folder_id); 292 EXPECT_TRUE(folder_item); 293 294 Show(); 295 296 // The main grid view should be showing initially. 297 AppListMainView* main_view = view_->app_list_main_view(); 298 AppsContainerView* container_view = 299 main_view->contents_view()->apps_container_view(); 300 EXPECT_NO_FATAL_FAILURE(CheckView(main_view)); 301 EXPECT_NO_FATAL_FAILURE(CheckView(container_view->apps_grid_view())); 302 EXPECT_FALSE(container_view->app_list_folder_view()->visible()); 303 304 AppsGridViewTestApi test_api(container_view->apps_grid_view()); 305 test_api.PressItemAt(0); 306 307 // After pressing the folder item, the folder view should be showing. 308 EXPECT_NO_FATAL_FAILURE(CheckView(main_view)); 309 EXPECT_NO_FATAL_FAILURE(CheckView(container_view->app_list_folder_view())); 310 EXPECT_FALSE(container_view->apps_grid_view()->visible()); 311 312 view_->GetWidget()->Hide(); 313 EXPECT_FALSE(view_->GetWidget()->IsVisible()); 314 315 Show(); 316 317 // The main grid view should be showing after a reshow. 318 EXPECT_NO_FATAL_FAILURE(CheckView(main_view)); 319 EXPECT_NO_FATAL_FAILURE(CheckView(container_view->apps_grid_view())); 320 EXPECT_FALSE(container_view->app_list_folder_view()->visible()); 321 322 Close(); 323} 324 325void AppListViewTestContext::RunStartPageTest() { 326 EXPECT_FALSE(view_->GetWidget()->IsVisible()); 327 EXPECT_EQ(-1, GetPaginationModel()->total_pages()); 328 AppListTestModel* model = delegate_->GetTestModel(); 329 model->PopulateApps(3); 330 331 Show(); 332 333 AppListMainView* main_view = view_->app_list_main_view(); 334 StartPageView* start_page_view = 335 main_view->contents_view()->start_page_view(); 336 // Checks on the main view. 337 EXPECT_NO_FATAL_FAILURE(CheckView(main_view)); 338 EXPECT_NO_FATAL_FAILURE(CheckView(main_view->contents_view())); 339 if (test_type_ == EXPERIMENTAL) { 340 EXPECT_NO_FATAL_FAILURE(CheckView(start_page_view)); 341 342 // Show the start page view. 343 ContentsView* contents_view = main_view->contents_view(); 344 ShowContentsViewPageAndVerify(contents_view->GetPageIndexForNamedPage( 345 ContentsView::NAMED_PAGE_START)); 346 EXPECT_FALSE(main_view->search_box_view()->visible()); 347 348 gfx::Size view_size(view_->GetPreferredSize()); 349 ShowContentsViewPageAndVerify( 350 contents_view->GetPageIndexForNamedPage(ContentsView::NAMED_PAGE_APPS)); 351 EXPECT_TRUE(main_view->search_box_view()->visible()); 352 353 // Hiding and showing the search box should not affect the app list's 354 // preferred size. This is a regression test for http://crbug.com/386912. 355 EXPECT_EQ(view_size.ToString(), view_->GetPreferredSize().ToString()); 356 357 // Check tiles hide and show on deletion and addition. 358 model->results()->Add(new TestTileSearchResult()); 359 start_page_view->UpdateForTesting(); 360 EXPECT_EQ(1u, GetVisibleTileItemViews(start_page_view->tile_views())); 361 model->results()->DeleteAll(); 362 start_page_view->UpdateForTesting(); 363 EXPECT_EQ(0u, GetVisibleTileItemViews(start_page_view->tile_views())); 364 } else { 365 EXPECT_EQ(NULL, start_page_view); 366 } 367 368 Close(); 369} 370 371void AppListViewTestContext::RunPageSwitchingAnimationTest() { 372 if (test_type_ == EXPERIMENTAL) { 373 Show(); 374 375 AppListMainView* main_view = view_->app_list_main_view(); 376 // Checks on the main view. 377 EXPECT_NO_FATAL_FAILURE(CheckView(main_view)); 378 EXPECT_NO_FATAL_FAILURE(CheckView(main_view->contents_view())); 379 380 ContentsView* contents_view = main_view->contents_view(); 381 // Pad the ContentsView with blank pages so we have at least 3 views. 382 while (contents_view->NumLauncherPages() < 3) 383 contents_view->AddBlankPageForTesting(); 384 385 contents_view->SetActivePage(0); 386 contents_view->Layout(); 387 EXPECT_TRUE(IsViewAtOrigin(contents_view->GetPageView(0))); 388 EXPECT_FALSE(IsViewAtOrigin(contents_view->GetPageView(1))); 389 EXPECT_FALSE(IsViewAtOrigin(contents_view->GetPageView(2))); 390 391 // Change pages. View should not have moved without Layout(). 392 contents_view->SetActivePage(1); 393 EXPECT_TRUE(IsViewAtOrigin(contents_view->GetPageView(0))); 394 EXPECT_FALSE(IsViewAtOrigin(contents_view->GetPageView(1))); 395 EXPECT_FALSE(IsViewAtOrigin(contents_view->GetPageView(2))); 396 397 // Change to a third page. This queues up the second animation behind the 398 // first. 399 contents_view->SetActivePage(2); 400 EXPECT_TRUE(IsViewAtOrigin(contents_view->GetPageView(0))); 401 EXPECT_FALSE(IsViewAtOrigin(contents_view->GetPageView(1))); 402 EXPECT_FALSE(IsViewAtOrigin(contents_view->GetPageView(2))); 403 404 // Call Layout(). Should jump to the third page. 405 contents_view->Layout(); 406 EXPECT_FALSE(IsViewAtOrigin(contents_view->GetPageView(0))); 407 EXPECT_FALSE(IsViewAtOrigin(contents_view->GetPageView(1))); 408 EXPECT_TRUE(IsViewAtOrigin(contents_view->GetPageView(2))); 409 } 410 411 Close(); 412} 413 414void AppListViewTestContext::RunProfileChangeTest() { 415 EXPECT_FALSE(view_->GetWidget()->IsVisible()); 416 EXPECT_EQ(-1, GetPaginationModel()->total_pages()); 417 delegate_->GetTestModel()->PopulateApps(kInitialItems); 418 419 Show(); 420 421 if (is_landscape()) 422 EXPECT_EQ(2, GetPaginationModel()->total_pages()); 423 else 424 EXPECT_EQ(3, GetPaginationModel()->total_pages()); 425 426 // Change the profile. The original model needs to be kept alive for 427 // observers to unregister themselves. 428 scoped_ptr<AppListTestModel> original_test_model( 429 delegate_->ReleaseTestModel()); 430 delegate_->set_next_profile_app_count(1); 431 432 // The original ContentsView is destroyed here. 433 view_->SetProfileByPath(base::FilePath()); 434 EXPECT_EQ(1, GetPaginationModel()->total_pages()); 435 436 StartPageView* start_page_view = 437 view_->app_list_main_view()->contents_view()->start_page_view(); 438 ContentsSwitcherView* contents_switcher_view = 439 view_->app_list_main_view()->contents_switcher_view(); 440 if (test_type_ == EXPERIMENTAL) { 441 EXPECT_NO_FATAL_FAILURE(CheckView(contents_switcher_view)); 442 EXPECT_EQ(view_->app_list_main_view()->contents_view(), 443 contents_switcher_view->contents_view()); 444 EXPECT_NO_FATAL_FAILURE(CheckView(start_page_view)); 445 } else { 446 EXPECT_EQ(NULL, contents_switcher_view); 447 EXPECT_EQ(NULL, start_page_view); 448 } 449 450 // New model updates should be processed by the start page view. 451 delegate_->GetTestModel()->results()->Add(new TestTileSearchResult()); 452 if (test_type_ == EXPERIMENTAL) { 453 start_page_view->UpdateForTesting(); 454 EXPECT_EQ(1u, GetVisibleTileItemViews(start_page_view->tile_views())); 455 } 456 457 // Old model updates should be ignored. 458 original_test_model->results()->Add(new TestTileSearchResult()); 459 original_test_model->results()->Add(new TestTileSearchResult()); 460 if (test_type_ == EXPERIMENTAL) { 461 start_page_view->UpdateForTesting(); 462 EXPECT_EQ(1u, GetVisibleTileItemViews(start_page_view->tile_views())); 463 } 464 465 Close(); 466} 467 468void AppListViewTestContext::RunSearchResultsTest() { 469 EXPECT_FALSE(view_->GetWidget()->IsVisible()); 470 EXPECT_EQ(-1, GetPaginationModel()->total_pages()); 471 AppListTestModel* model = delegate_->GetTestModel(); 472 model->PopulateApps(3); 473 474 Show(); 475 476 AppListMainView* main_view = view_->app_list_main_view(); 477 ContentsView* contents_view = main_view->contents_view(); 478 ShowContentsViewPageAndVerify( 479 contents_view->GetPageIndexForNamedPage(ContentsView::NAMED_PAGE_APPS)); 480 EXPECT_TRUE(main_view->search_box_view()->visible()); 481 482 // Show the search results. 483 contents_view->ShowSearchResults(true); 484 contents_view->Layout(); 485 EXPECT_TRUE(contents_view->IsShowingSearchResults()); 486 EXPECT_TRUE(main_view->search_box_view()->visible()); 487 488 if (test_type_ == EXPERIMENTAL) { 489 EXPECT_TRUE( 490 contents_view->IsNamedPageActive(ContentsView::NAMED_PAGE_START)); 491 EXPECT_TRUE(IsViewAtOrigin(contents_view->start_page_view())); 492 } else { 493 EXPECT_TRUE(contents_view->IsNamedPageActive( 494 ContentsView::NAMED_PAGE_SEARCH_RESULTS)); 495 EXPECT_TRUE(IsViewAtOrigin(contents_view->search_results_view())); 496 } 497 498 // Hide the search results. 499 contents_view->ShowSearchResults(false); 500 contents_view->Layout(); 501 EXPECT_FALSE(contents_view->IsShowingSearchResults()); 502 503 // Check that we return to the page that we were on before the search. 504 EXPECT_TRUE(contents_view->IsNamedPageActive(ContentsView::NAMED_PAGE_APPS)); 505 EXPECT_TRUE(IsViewAtOrigin(contents_view->apps_container_view())); 506 EXPECT_TRUE(main_view->search_box_view()->visible()); 507 508 if (test_type_ == EXPERIMENTAL) { 509 ShowContentsViewPageAndVerify(contents_view->GetPageIndexForNamedPage( 510 ContentsView::NAMED_PAGE_START)); 511 512 // Check that typing into the dummy search box triggers the search page. 513 base::string16 search_text = base::UTF8ToUTF16("test"); 514 SearchBoxView* dummy_search_box = 515 contents_view->start_page_view()->dummy_search_box_view(); 516 EXPECT_TRUE(dummy_search_box->IsDrawn()); 517 dummy_search_box->search_box()->InsertText(search_text); 518 contents_view->Layout(); 519 // Check that the current search is using |search_text|. 520 EXPECT_EQ(search_text, delegate_->GetTestModel()->search_box()->text()); 521 EXPECT_TRUE(contents_view->IsShowingSearchResults()); 522 EXPECT_FALSE(dummy_search_box->IsDrawn()); 523 EXPECT_TRUE(main_view->search_box_view()->visible()); 524 EXPECT_EQ(search_text, main_view->search_box_view()->search_box()->text()); 525 EXPECT_TRUE( 526 contents_view->IsNamedPageActive(ContentsView::NAMED_PAGE_START)); 527 EXPECT_TRUE(IsViewAtOrigin(contents_view->start_page_view())); 528 529 // Check that typing into the real search box triggers the search page. 530 ShowContentsViewPageAndVerify( 531 contents_view->GetPageIndexForNamedPage(ContentsView::NAMED_PAGE_APPS)); 532 EXPECT_TRUE(IsViewAtOrigin(contents_view->apps_container_view())); 533 534 base::string16 new_search_text = base::UTF8ToUTF16("apple"); 535 main_view->search_box_view()->search_box()->SetText(base::string16()); 536 main_view->search_box_view()->search_box()->InsertText(new_search_text); 537 // Check that the current search is using |search_text|. 538 EXPECT_EQ(new_search_text, delegate_->GetTestModel()->search_box()->text()); 539 EXPECT_EQ(new_search_text, 540 main_view->search_box_view()->search_box()->text()); 541 EXPECT_TRUE(contents_view->IsShowingSearchResults()); 542 EXPECT_FALSE(dummy_search_box->IsDrawn()); 543 EXPECT_TRUE(main_view->search_box_view()->visible()); 544 EXPECT_TRUE(dummy_search_box->search_box()->text().empty()); 545 546 // Check that the dummy search box is clear when reshowing the start page. 547 ShowContentsViewPageAndVerify( 548 contents_view->GetPageIndexForNamedPage(ContentsView::NAMED_PAGE_APPS)); 549 ShowContentsViewPageAndVerify(contents_view->GetPageIndexForNamedPage( 550 ContentsView::NAMED_PAGE_START)); 551 EXPECT_TRUE(dummy_search_box->IsDrawn()); 552 EXPECT_TRUE(dummy_search_box->search_box()->text().empty()); 553 } 554 555 Close(); 556} 557 558class AppListViewTestAura : public views::ViewsTestBase, 559 public ::testing::WithParamInterface<int> { 560 public: 561 AppListViewTestAura() {} 562 virtual ~AppListViewTestAura() {} 563 564 // testing::Test overrides: 565 virtual void SetUp() OVERRIDE { 566 views::ViewsTestBase::SetUp(); 567 568 // On Ash (only) the app list is placed into an aura::Window "container", 569 // which is also used to determine the context. In tests, use the ash root 570 // window as the parent. This only works on aura where the root window is a 571 // NativeView as well as a NativeWindow. 572 gfx::NativeView container = NULL; 573#if defined(USE_AURA) 574 container = GetContext(); 575#endif 576 577 test_context_.reset(new AppListViewTestContext(GetParam(), container)); 578 } 579 580 virtual void TearDown() OVERRIDE { 581 test_context_.reset(); 582 views::ViewsTestBase::TearDown(); 583 } 584 585 protected: 586 scoped_ptr<AppListViewTestContext> test_context_; 587 588 private: 589 DISALLOW_COPY_AND_ASSIGN(AppListViewTestAura); 590}; 591 592class AppListViewTestDesktop : public views::ViewsTestBase, 593 public ::testing::WithParamInterface<int> { 594 public: 595 AppListViewTestDesktop() {} 596 virtual ~AppListViewTestDesktop() {} 597 598 // testing::Test overrides: 599 virtual void SetUp() OVERRIDE { 600 set_views_delegate(new AppListViewTestViewsDelegate(this)); 601 views::ViewsTestBase::SetUp(); 602 test_context_.reset(new AppListViewTestContext(GetParam(), NULL)); 603 } 604 605 virtual void TearDown() OVERRIDE { 606 test_context_.reset(); 607 views::ViewsTestBase::TearDown(); 608 } 609 610 protected: 611 scoped_ptr<AppListViewTestContext> test_context_; 612 613 private: 614 class AppListViewTestViewsDelegate : public views::TestViewsDelegate { 615 public: 616 AppListViewTestViewsDelegate(AppListViewTestDesktop* parent) 617 : parent_(parent) {} 618 619 // Overridden from views::ViewsDelegate: 620 virtual void OnBeforeWidgetInit( 621 views::Widget::InitParams* params, 622 views::internal::NativeWidgetDelegate* delegate) OVERRIDE; 623 624 private: 625 AppListViewTestDesktop* parent_; 626 627 DISALLOW_COPY_AND_ASSIGN(AppListViewTestViewsDelegate); 628 }; 629 630 DISALLOW_COPY_AND_ASSIGN(AppListViewTestDesktop); 631}; 632 633void AppListViewTestDesktop::AppListViewTestViewsDelegate::OnBeforeWidgetInit( 634 views::Widget::InitParams* params, 635 views::internal::NativeWidgetDelegate* delegate) { 636// Mimic the logic in ChromeViewsDelegate::OnBeforeWidgetInit(). Except, for 637// ChromeOS, use the root window from the AuraTestHelper rather than depending 638// on ash::Shell:GetPrimaryRootWindow(). Also assume non-ChromeOS is never the 639// Ash desktop, as that is covered by AppListViewTestAura. 640#if defined(OS_CHROMEOS) 641 if (!params->parent && !params->context) 642 params->context = parent_->GetContext(); 643#elif defined(USE_AURA) 644 if (params->parent == NULL && params->context == NULL && !params->child) 645 params->native_widget = new views::DesktopNativeWidgetAura(delegate); 646#endif 647} 648 649} // namespace 650 651// Tests showing the app list with basic test model in an ash-style root window. 652TEST_P(AppListViewTestAura, Display) { 653 EXPECT_NO_FATAL_FAILURE(test_context_->RunDisplayTest()); 654} 655 656// Tests showing the app list on the desktop. Note on ChromeOS, this will still 657// use the regular root window. 658TEST_P(AppListViewTestDesktop, Display) { 659 EXPECT_NO_FATAL_FAILURE(test_context_->RunDisplayTest()); 660} 661 662// Tests that the main grid view is shown after hiding and reshowing the app 663// list with a folder view open. This is a regression test for crbug.com/357058. 664TEST_P(AppListViewTestAura, ReshowWithOpenFolder) { 665 EXPECT_NO_FATAL_FAILURE(test_context_->RunReshowWithOpenFolderTest()); 666} 667 668TEST_P(AppListViewTestDesktop, ReshowWithOpenFolder) { 669 EXPECT_NO_FATAL_FAILURE(test_context_->RunReshowWithOpenFolderTest()); 670} 671 672// Tests that the start page view operates correctly. 673TEST_P(AppListViewTestAura, StartPageTest) { 674 EXPECT_NO_FATAL_FAILURE(test_context_->RunStartPageTest()); 675} 676 677TEST_P(AppListViewTestDesktop, StartPageTest) { 678 EXPECT_NO_FATAL_FAILURE(test_context_->RunStartPageTest()); 679} 680 681// Tests that the start page view operates correctly. 682TEST_P(AppListViewTestAura, PageSwitchingAnimationTest) { 683 EXPECT_NO_FATAL_FAILURE(test_context_->RunPageSwitchingAnimationTest()); 684} 685 686TEST_P(AppListViewTestDesktop, PageSwitchingAnimationTest) { 687 EXPECT_NO_FATAL_FAILURE(test_context_->RunPageSwitchingAnimationTest()); 688} 689 690// Tests that the profile changes operate correctly. 691TEST_P(AppListViewTestAura, ProfileChangeTest) { 692 EXPECT_NO_FATAL_FAILURE(test_context_->RunProfileChangeTest()); 693} 694 695TEST_P(AppListViewTestDesktop, ProfileChangeTest) { 696 EXPECT_NO_FATAL_FAILURE(test_context_->RunProfileChangeTest()); 697} 698 699// Tests that the correct views are displayed for showing search results. 700TEST_P(AppListViewTestAura, SearchResultsTest) { 701 EXPECT_NO_FATAL_FAILURE(test_context_->RunSearchResultsTest()); 702} 703 704TEST_P(AppListViewTestDesktop, SearchResultsTest) { 705 EXPECT_NO_FATAL_FAILURE(test_context_->RunSearchResultsTest()); 706} 707 708INSTANTIATE_TEST_CASE_P(AppListViewTestAuraInstance, 709 AppListViewTestAura, 710 ::testing::Range<int>(TEST_TYPE_START, TEST_TYPE_END)); 711 712INSTANTIATE_TEST_CASE_P(AppListViewTestDesktopInstance, 713 AppListViewTestDesktop, 714 ::testing::Range<int>(TEST_TYPE_START, TEST_TYPE_END)); 715 716} // namespace test 717} // namespace app_list 718