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