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