Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / ui / app_list / views / app_list_view_unittest.cc
bloba8fc4e06746b520f16bf260ff65c59befeab761a
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.
5 #include "ui/app_list/views/app_list_view.h"
7 #include <string>
8 #include <vector>
10 #include "base/command_line.h"
11 #include "base/run_loop.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "ui/app_list/app_list_constants.h"
16 #include "ui/app_list/app_list_switches.h"
17 #include "ui/app_list/pagination_model.h"
18 #include "ui/app_list/search_box_model.h"
19 #include "ui/app_list/test/app_list_test_model.h"
20 #include "ui/app_list/test/app_list_test_view_delegate.h"
21 #include "ui/app_list/test/test_search_result.h"
22 #include "ui/app_list/views/app_list_folder_view.h"
23 #include "ui/app_list/views/app_list_main_view.h"
24 #include "ui/app_list/views/apps_container_view.h"
25 #include "ui/app_list/views/apps_grid_view.h"
26 #include "ui/app_list/views/contents_view.h"
27 #include "ui/app_list/views/search_box_view.h"
28 #include "ui/app_list/views/search_result_page_view.h"
29 #include "ui/app_list/views/search_result_tile_item_view.h"
30 #include "ui/app_list/views/start_page_view.h"
31 #include "ui/app_list/views/test/apps_grid_view_test_api.h"
32 #include "ui/app_list/views/tile_item_view.h"
33 #include "ui/events/event_utils.h"
34 #include "ui/views/controls/textfield/textfield.h"
35 #include "ui/views/test/views_test_base.h"
36 #include "ui/views/views_delegate.h"
37 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
39 namespace app_list {
40 namespace test {
42 namespace {
44 enum TestType {
45 TEST_TYPE_START = 0,
46 NORMAL = TEST_TYPE_START,
47 LANDSCAPE,
48 EXPERIMENTAL,
49 TEST_TYPE_END,
52 template <class T>
53 size_t GetVisibleViews(const std::vector<T*>& tiles) {
54 size_t count = 0;
55 for (const auto& tile : tiles) {
56 if (tile->visible())
57 count++;
59 return count;
62 void SimulateClick(views::View* view) {
63 gfx::Point center = view->GetLocalBounds().CenterPoint();
64 view->OnMousePressed(ui::MouseEvent(
65 ui::ET_MOUSE_PRESSED, center, center, ui::EventTimeForNow(),
66 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON));
67 view->OnMouseReleased(ui::MouseEvent(
68 ui::ET_MOUSE_RELEASED, center, center, ui::EventTimeForNow(),
69 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON));
72 // Choose a set that is 3 regular app list pages and 2 landscape app list pages.
73 const int kInitialItems = 34;
75 class TestStartPageSearchResult : public TestSearchResult {
76 public:
77 TestStartPageSearchResult() { set_display_type(DISPLAY_RECOMMENDATION); }
78 ~TestStartPageSearchResult() override {}
80 private:
81 DISALLOW_COPY_AND_ASSIGN(TestStartPageSearchResult);
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();
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();
95 // Hides and reshows the app list with a folder open, expecting the main grid
96 // view to be shown.
97 void RunReshowWithOpenFolderTest();
99 // Tests that pressing the search box's back button navigates correctly.
100 void RunBackTest();
102 // Tests displaying of the experimental app list and shows the start page.
103 void RunStartPageTest();
105 // Tests switching rapidly between multiple pages of the launcher.
106 void RunPageSwitchingAnimationTest();
108 // Tests changing the App List profile.
109 void RunProfileChangeTest();
111 // Tests displaying of the search results.
112 void RunSearchResultsTest();
114 // Tests displaying the app list overlay.
115 void RunAppListOverlayTest();
117 // A standard set of checks on a view, e.g., ensuring it is drawn and visible.
118 static void CheckView(views::View* subview);
120 // Invoked when the Widget is closing, and the view it contains is about to
121 // be torn down. This only occurs in a run loop and will be used as a signal
122 // to quit.
123 void NativeWidgetClosing() {
124 view_ = NULL;
125 run_loop_->Quit();
128 // Whether the experimental "landscape" app launcher UI is being tested.
129 bool is_landscape() const {
130 return test_type_ == LANDSCAPE || test_type_ == EXPERIMENTAL;
133 private:
134 // Switches the launcher to |state| and lays out to ensure all launcher pages
135 // are in the correct position. Checks that the state is where it should be
136 // and returns false on failure.
137 bool SetAppListState(AppListModel::State state);
139 // Returns true if all of the pages are in their correct position for |state|.
140 bool IsStateShown(AppListModel::State state);
142 // Shows the app list and waits until a paint occurs.
143 void Show();
145 // Closes the app list. This sets |view_| to NULL.
146 void Close();
148 // Checks the search box widget is at |expected| in the contents view's
149 // coordinate space.
150 bool CheckSearchBoxWidget(const gfx::Rect& expected);
152 // Gets the PaginationModel owned by |view_|.
153 PaginationModel* GetPaginationModel();
155 const TestType test_type_;
156 scoped_ptr<base::RunLoop> run_loop_;
157 app_list::AppListView* view_; // Owned by native widget.
158 scoped_ptr<app_list::test::AppListTestViewDelegate> delegate_;
160 DISALLOW_COPY_AND_ASSIGN(AppListViewTestContext);
163 // Extend the regular AppListTestViewDelegate to communicate back to the test
164 // context. Note the test context doesn't simply inherit this, because the
165 // delegate is owned by the view.
166 class UnitTestViewDelegate : public app_list::test::AppListTestViewDelegate {
167 public:
168 explicit UnitTestViewDelegate(AppListViewTestContext* parent)
169 : parent_(parent) {}
171 // Overridden from app_list::AppListViewDelegate:
172 bool ShouldCenterWindow() const override {
173 return app_list::switches::IsCenteredAppListEnabled();
176 // Overridden from app_list::test::AppListTestViewDelegate:
177 void ViewClosing() override { parent_->NativeWidgetClosing(); }
179 private:
180 AppListViewTestContext* parent_;
182 DISALLOW_COPY_AND_ASSIGN(UnitTestViewDelegate);
185 AppListViewTestContext::AppListViewTestContext(int test_type,
186 gfx::NativeView parent)
187 : test_type_(static_cast<TestType>(test_type)) {
188 switch (test_type_) {
189 case NORMAL:
190 base::CommandLine::ForCurrentProcess()->AppendSwitch(
191 switches::kDisableExperimentalAppList);
192 break;
193 case LANDSCAPE:
194 base::CommandLine::ForCurrentProcess()->AppendSwitch(
195 switches::kDisableExperimentalAppList);
196 base::CommandLine::ForCurrentProcess()->AppendSwitch(
197 switches::kEnableCenteredAppList);
198 break;
199 case EXPERIMENTAL:
200 base::CommandLine::ForCurrentProcess()->AppendSwitch(
201 switches::kEnableExperimentalAppList);
202 break;
203 default:
204 NOTREACHED();
205 break;
208 delegate_.reset(new UnitTestViewDelegate(this));
209 view_ = new app_list::AppListView(delegate_.get());
211 // Initialize centered around a point that ensures the window is wholly shown.
212 view_->InitAsBubbleAtFixedLocation(parent,
214 gfx::Point(300, 300),
215 views::BubbleBorder::FLOAT,
216 false /* border_accepts_events */);
219 AppListViewTestContext::~AppListViewTestContext() {
220 // The view observes the PaginationModel which is about to get destroyed, so
221 // if the view is not already deleted by the time this destructor is called,
222 // there will be problems.
223 EXPECT_FALSE(view_);
226 // static
227 void AppListViewTestContext::CheckView(views::View* subview) {
228 ASSERT_TRUE(subview);
229 EXPECT_TRUE(subview->parent());
230 EXPECT_TRUE(subview->visible());
231 EXPECT_TRUE(subview->IsDrawn());
232 EXPECT_FALSE(subview->bounds().IsEmpty());
235 bool AppListViewTestContext::SetAppListState(AppListModel::State state) {
236 ContentsView* contents_view = view_->app_list_main_view()->contents_view();
237 contents_view->SetActiveState(state);
238 contents_view->Layout();
239 return IsStateShown(state);
242 bool AppListViewTestContext::IsStateShown(AppListModel::State state) {
243 ContentsView* contents_view = view_->app_list_main_view()->contents_view();
244 bool success = true;
245 for (int i = 0; i < contents_view->NumLauncherPages(); ++i) {
246 success = success &&
247 (contents_view->GetPageView(i)->GetPageBoundsForState(state) ==
248 contents_view->GetPageView(i)->bounds());
250 return success && state == delegate_->GetTestModel()->state();
253 void AppListViewTestContext::Show() {
254 view_->GetWidget()->Show();
255 run_loop_.reset(new base::RunLoop);
256 view_->SetNextPaintCallback(run_loop_->QuitClosure());
257 run_loop_->Run();
259 EXPECT_TRUE(view_->GetWidget()->IsVisible());
262 void AppListViewTestContext::Close() {
263 view_->GetWidget()->Close();
264 run_loop_.reset(new base::RunLoop);
265 run_loop_->Run();
267 // |view_| should have been deleted and set to NULL via ViewClosing().
268 EXPECT_FALSE(view_);
271 bool AppListViewTestContext::CheckSearchBoxWidget(const gfx::Rect& expected) {
272 ContentsView* contents_view = view_->app_list_main_view()->contents_view();
273 // Adjust for the search box view's shadow.
274 gfx::Rect expected_with_shadow =
275 view_->app_list_main_view()
276 ->search_box_view()
277 ->GetViewBoundsForSearchBoxContentsBounds(expected);
278 gfx::Point point = expected_with_shadow.origin();
279 views::View::ConvertPointToScreen(contents_view, &point);
281 return gfx::Rect(point, expected_with_shadow.size()) ==
282 view_->search_box_widget()->GetWindowBoundsInScreen();
285 PaginationModel* AppListViewTestContext::GetPaginationModel() {
286 return view_->GetAppsPaginationModel();
289 void AppListViewTestContext::RunDisplayTest() {
290 EXPECT_FALSE(view_->GetWidget()->IsVisible());
291 EXPECT_EQ(-1, GetPaginationModel()->total_pages());
292 delegate_->GetTestModel()->PopulateApps(kInitialItems);
294 Show();
296 // Explicitly enforce the exact dimensions of the app list. Feel free to
297 // change these if you need to (they are just here to prevent against
298 // accidental changes to the window size).
299 switch (test_type_) {
300 case NORMAL:
301 EXPECT_EQ("400x500", view_->bounds().size().ToString());
302 break;
303 case LANDSCAPE:
304 // NOTE: Height should not exceed 402, because otherwise there might not
305 // be enough space to accomodate the virtual keyboard. (LANDSCAPE mode is
306 // enabled by default when the virtual keyboard is enabled.)
307 EXPECT_EQ("576x402", view_->bounds().size().ToString());
308 break;
309 case EXPERIMENTAL:
310 EXPECT_EQ("768x570", view_->bounds().size().ToString());
311 break;
312 default:
313 NOTREACHED();
314 break;
317 if (is_landscape())
318 EXPECT_EQ(2, GetPaginationModel()->total_pages());
319 else
320 EXPECT_EQ(3, GetPaginationModel()->total_pages());
321 EXPECT_EQ(0, GetPaginationModel()->selected_page());
323 // Checks on the main view.
324 AppListMainView* main_view = view_->app_list_main_view();
325 EXPECT_NO_FATAL_FAILURE(CheckView(main_view));
326 EXPECT_NO_FATAL_FAILURE(CheckView(main_view->contents_view()));
328 AppListModel::State expected = test_type_ == EXPERIMENTAL
329 ? AppListModel::STATE_START
330 : AppListModel::STATE_APPS;
331 EXPECT_TRUE(main_view->contents_view()->IsStateActive(expected));
332 EXPECT_EQ(expected, delegate_->GetTestModel()->state());
334 Close();
337 void AppListViewTestContext::RunReshowWithOpenFolderTest() {
338 EXPECT_FALSE(view_->GetWidget()->IsVisible());
339 EXPECT_EQ(-1, GetPaginationModel()->total_pages());
341 AppListTestModel* model = delegate_->GetTestModel();
342 model->PopulateApps(kInitialItems);
343 const std::string folder_id =
344 model->MergeItems(model->top_level_item_list()->item_at(0)->id(),
345 model->top_level_item_list()->item_at(1)->id());
347 AppListFolderItem* folder_item = model->FindFolderItem(folder_id);
348 EXPECT_TRUE(folder_item);
350 Show();
352 // The main grid view should be showing initially.
353 AppListMainView* main_view = view_->app_list_main_view();
354 AppsContainerView* container_view =
355 main_view->contents_view()->apps_container_view();
356 EXPECT_NO_FATAL_FAILURE(CheckView(main_view));
357 EXPECT_NO_FATAL_FAILURE(CheckView(container_view->apps_grid_view()));
358 EXPECT_FALSE(container_view->app_list_folder_view()->visible());
360 AppsGridViewTestApi test_api(container_view->apps_grid_view());
361 test_api.PressItemAt(0);
363 // After pressing the folder item, the folder view should be showing.
364 EXPECT_NO_FATAL_FAILURE(CheckView(main_view));
365 EXPECT_NO_FATAL_FAILURE(CheckView(container_view->app_list_folder_view()));
366 EXPECT_FALSE(container_view->apps_grid_view()->visible());
368 view_->GetWidget()->Hide();
369 EXPECT_FALSE(view_->GetWidget()->IsVisible());
371 Show();
373 // The main grid view should be showing after a reshow.
374 EXPECT_NO_FATAL_FAILURE(CheckView(main_view));
375 EXPECT_NO_FATAL_FAILURE(CheckView(container_view->apps_grid_view()));
376 EXPECT_FALSE(container_view->app_list_folder_view()->visible());
378 Close();
381 void AppListViewTestContext::RunBackTest() {
382 if (test_type_ != EXPERIMENTAL) {
383 Close();
384 return;
387 EXPECT_FALSE(view_->GetWidget()->IsVisible());
388 EXPECT_EQ(-1, GetPaginationModel()->total_pages());
390 Show();
392 AppListMainView* main_view = view_->app_list_main_view();
393 ContentsView* contents_view = main_view->contents_view();
394 SearchBoxView* search_box_view = main_view->search_box_view();
396 // Show the apps grid.
397 SetAppListState(AppListModel::STATE_APPS);
398 EXPECT_NO_FATAL_FAILURE(CheckView(search_box_view->back_button()));
400 // The back button should return to the start page.
401 EXPECT_TRUE(contents_view->Back());
402 contents_view->Layout();
403 EXPECT_TRUE(IsStateShown(AppListModel::STATE_START));
404 EXPECT_FALSE(search_box_view->back_button()->visible());
406 // Show the apps grid again.
407 SetAppListState(AppListModel::STATE_APPS);
408 EXPECT_NO_FATAL_FAILURE(CheckView(search_box_view->back_button()));
410 // Pressing ESC should return to the start page.
411 view_->AcceleratorPressed(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
412 contents_view->Layout();
413 EXPECT_TRUE(IsStateShown(AppListModel::STATE_START));
414 EXPECT_FALSE(search_box_view->back_button()->visible());
416 // Pressing ESC from the start page should close the app list.
417 EXPECT_EQ(0, delegate_->dismiss_count());
418 view_->AcceleratorPressed(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
419 EXPECT_EQ(1, delegate_->dismiss_count());
421 // Show the search results.
422 base::string16 new_search_text = base::UTF8ToUTF16("apple");
423 search_box_view->search_box()->SetText(base::string16());
424 search_box_view->search_box()->InsertText(new_search_text);
425 contents_view->Layout();
426 EXPECT_TRUE(IsStateShown(AppListModel::STATE_SEARCH_RESULTS));
427 EXPECT_NO_FATAL_FAILURE(CheckView(search_box_view->back_button()));
429 // The back button should return to the start page.
430 EXPECT_TRUE(contents_view->Back());
431 contents_view->Layout();
432 EXPECT_TRUE(IsStateShown(AppListModel::STATE_START));
433 EXPECT_FALSE(search_box_view->back_button()->visible());
435 Close();
438 void AppListViewTestContext::RunStartPageTest() {
439 EXPECT_FALSE(view_->GetWidget()->IsVisible());
440 EXPECT_EQ(-1, GetPaginationModel()->total_pages());
441 AppListTestModel* model = delegate_->GetTestModel();
442 model->PopulateApps(3);
444 Show();
446 AppListMainView* main_view = view_->app_list_main_view();
447 StartPageView* start_page_view =
448 main_view->contents_view()->start_page_view();
449 // Checks on the main view.
450 EXPECT_NO_FATAL_FAILURE(CheckView(main_view));
451 EXPECT_NO_FATAL_FAILURE(CheckView(main_view->contents_view()));
452 if (test_type_ == EXPERIMENTAL) {
453 EXPECT_NO_FATAL_FAILURE(CheckView(start_page_view));
455 // Show the start page view.
456 EXPECT_TRUE(SetAppListState(AppListModel::STATE_START));
457 gfx::Size view_size(view_->GetPreferredSize());
459 // The "All apps" button should have its "parent background color" set
460 // to the tiles container's background color.
461 TileItemView* all_apps_button = start_page_view->all_apps_button();
462 EXPECT_TRUE(all_apps_button->visible());
463 EXPECT_EQ(kLabelBackgroundColor,
464 all_apps_button->parent_background_color());
466 // Simulate clicking the "All apps" button. Check that we navigate to the
467 // apps grid view.
468 SimulateClick(all_apps_button);
469 main_view->contents_view()->Layout();
470 EXPECT_TRUE(IsStateShown(AppListModel::STATE_APPS));
472 // Hiding and showing the search box should not affect the app list's
473 // preferred size. This is a regression test for http://crbug.com/386912.
474 EXPECT_EQ(view_size.ToString(), view_->GetPreferredSize().ToString());
476 // Check tiles hide and show on deletion and addition.
477 EXPECT_TRUE(SetAppListState(AppListModel::STATE_START));
478 model->results()->Add(new TestStartPageSearchResult());
479 start_page_view->UpdateForTesting();
480 EXPECT_EQ(1u, GetVisibleViews(start_page_view->tile_views()));
481 model->results()->DeleteAll();
482 start_page_view->UpdateForTesting();
483 EXPECT_EQ(0u, GetVisibleViews(start_page_view->tile_views()));
485 // Tiles should not update when the start page is not active but should be
486 // correct once the start page is shown.
487 EXPECT_TRUE(SetAppListState(AppListModel::STATE_APPS));
488 model->results()->Add(new TestStartPageSearchResult());
489 start_page_view->UpdateForTesting();
490 EXPECT_EQ(0u, GetVisibleViews(start_page_view->tile_views()));
491 EXPECT_TRUE(SetAppListState(AppListModel::STATE_START));
492 EXPECT_EQ(1u, GetVisibleViews(start_page_view->tile_views()));
493 } else {
494 EXPECT_EQ(NULL, start_page_view);
497 Close();
500 void AppListViewTestContext::RunPageSwitchingAnimationTest() {
501 if (test_type_ == EXPERIMENTAL) {
502 Show();
504 AppListMainView* main_view = view_->app_list_main_view();
505 // Checks on the main view.
506 EXPECT_NO_FATAL_FAILURE(CheckView(main_view));
507 EXPECT_NO_FATAL_FAILURE(CheckView(main_view->contents_view()));
509 ContentsView* contents_view = main_view->contents_view();
511 contents_view->SetActiveState(AppListModel::STATE_START);
512 contents_view->Layout();
514 IsStateShown(AppListModel::STATE_START);
516 // Change pages. View should not have moved without Layout().
517 contents_view->SetActiveState(AppListModel::STATE_SEARCH_RESULTS);
518 IsStateShown(AppListModel::STATE_START);
520 // Change to a third page. This queues up the second animation behind the
521 // first.
522 contents_view->SetActiveState(AppListModel::STATE_APPS);
523 IsStateShown(AppListModel::STATE_START);
525 // Call Layout(). Should jump to the third page.
526 contents_view->Layout();
527 IsStateShown(AppListModel::STATE_APPS);
530 Close();
533 void AppListViewTestContext::RunProfileChangeTest() {
534 EXPECT_FALSE(view_->GetWidget()->IsVisible());
535 EXPECT_EQ(-1, GetPaginationModel()->total_pages());
536 delegate_->GetTestModel()->PopulateApps(kInitialItems);
538 Show();
540 if (is_landscape())
541 EXPECT_EQ(2, GetPaginationModel()->total_pages());
542 else
543 EXPECT_EQ(3, GetPaginationModel()->total_pages());
545 // Change the profile. The original model needs to be kept alive for
546 // observers to unregister themselves.
547 scoped_ptr<AppListTestModel> original_test_model(
548 delegate_->ReleaseTestModel());
549 delegate_->set_next_profile_app_count(1);
551 // The original ContentsView is destroyed here.
552 view_->SetProfileByPath(base::FilePath());
553 EXPECT_EQ(1, GetPaginationModel()->total_pages());
555 StartPageView* start_page_view =
556 view_->app_list_main_view()->contents_view()->start_page_view();
557 if (test_type_ == EXPERIMENTAL)
558 EXPECT_NO_FATAL_FAILURE(CheckView(start_page_view));
559 else
560 EXPECT_EQ(NULL, start_page_view);
562 // New model updates should be processed by the start page view.
563 delegate_->GetTestModel()->results()->Add(new TestStartPageSearchResult());
564 if (test_type_ == EXPERIMENTAL) {
565 start_page_view->UpdateForTesting();
566 EXPECT_EQ(1u, GetVisibleViews(start_page_view->tile_views()));
569 // Old model updates should be ignored.
570 original_test_model->results()->Add(new TestStartPageSearchResult());
571 original_test_model->results()->Add(new TestStartPageSearchResult());
572 if (test_type_ == EXPERIMENTAL) {
573 start_page_view->UpdateForTesting();
574 EXPECT_EQ(1u, GetVisibleViews(start_page_view->tile_views()));
577 Close();
580 void AppListViewTestContext::RunSearchResultsTest() {
581 EXPECT_FALSE(view_->GetWidget()->IsVisible());
582 EXPECT_EQ(-1, GetPaginationModel()->total_pages());
583 AppListTestModel* model = delegate_->GetTestModel();
584 model->PopulateApps(3);
586 Show();
588 AppListMainView* main_view = view_->app_list_main_view();
589 ContentsView* contents_view = main_view->contents_view();
590 EXPECT_TRUE(SetAppListState(AppListModel::STATE_APPS));
592 // Show the search results.
593 contents_view->ShowSearchResults(true);
594 contents_view->Layout();
595 EXPECT_TRUE(contents_view->IsStateActive(AppListModel::STATE_SEARCH_RESULTS));
597 EXPECT_TRUE(IsStateShown(AppListModel::STATE_SEARCH_RESULTS));
599 // Hide the search results.
600 contents_view->ShowSearchResults(false);
601 contents_view->Layout();
603 // Check that we return to the page that we were on before the search.
604 EXPECT_TRUE(IsStateShown(AppListModel::STATE_APPS));
606 if (test_type_ == EXPERIMENTAL) {
607 // Check that typing into the search box triggers the search page.
608 EXPECT_TRUE(SetAppListState(AppListModel::STATE_START));
609 view_->Layout();
610 EXPECT_TRUE(IsStateShown(AppListModel::STATE_START));
612 base::string16 search_text = base::UTF8ToUTF16("test");
613 main_view->search_box_view()->search_box()->SetText(base::string16());
614 main_view->search_box_view()->search_box()->InsertText(search_text);
615 // Check that the current search is using |search_text|.
616 EXPECT_EQ(search_text, delegate_->GetTestModel()->search_box()->text());
617 EXPECT_EQ(search_text, main_view->search_box_view()->search_box()->text());
618 contents_view->Layout();
619 EXPECT_TRUE(
620 contents_view->IsStateActive(AppListModel::STATE_SEARCH_RESULTS));
621 EXPECT_TRUE(
622 CheckSearchBoxWidget(contents_view->GetDefaultSearchBoxBounds()));
624 // Check that typing into the search box triggers the search page.
625 EXPECT_TRUE(SetAppListState(AppListModel::STATE_APPS));
626 contents_view->Layout();
627 EXPECT_TRUE(IsStateShown(AppListModel::STATE_APPS));
628 EXPECT_TRUE(
629 CheckSearchBoxWidget(contents_view->GetDefaultSearchBoxBounds()));
631 base::string16 new_search_text = base::UTF8ToUTF16("apple");
632 main_view->search_box_view()->search_box()->SetText(base::string16());
633 main_view->search_box_view()->search_box()->InsertText(new_search_text);
634 // Check that the current search is using |new_search_text|.
635 EXPECT_EQ(new_search_text, delegate_->GetTestModel()->search_box()->text());
636 EXPECT_EQ(new_search_text,
637 main_view->search_box_view()->search_box()->text());
638 contents_view->Layout();
639 EXPECT_TRUE(IsStateShown(AppListModel::STATE_SEARCH_RESULTS));
640 EXPECT_TRUE(
641 CheckSearchBoxWidget(contents_view->GetDefaultSearchBoxBounds()));
644 Close();
647 void AppListViewTestContext::RunAppListOverlayTest() {
648 Show();
650 AppListMainView* main_view = view_->app_list_main_view();
651 SearchBoxView* search_box_view = main_view->search_box_view();
653 // The search box should not be enabled when the app list overlay is shown.
654 view_->SetAppListOverlayVisible(true);
655 EXPECT_FALSE(search_box_view->enabled());
657 // The search box should be refocused when the app list overlay is hidden.
658 view_->SetAppListOverlayVisible(false);
659 EXPECT_TRUE(search_box_view->enabled());
660 EXPECT_EQ(search_box_view->search_box(),
661 view_->GetWidget()->GetFocusManager()->GetFocusedView());
663 Close();
666 class AppListViewTestAura : public views::ViewsTestBase,
667 public ::testing::WithParamInterface<int> {
668 public:
669 AppListViewTestAura() {}
670 virtual ~AppListViewTestAura() {}
672 // testing::Test overrides:
673 void SetUp() override {
674 views::ViewsTestBase::SetUp();
676 // On Ash (only) the app list is placed into an aura::Window "container",
677 // which is also used to determine the context. In tests, use the ash root
678 // window as the parent. This only works on aura where the root window is a
679 // NativeView as well as a NativeWindow.
680 gfx::NativeView container = NULL;
681 #if defined(USE_AURA)
682 container = GetContext();
683 #endif
685 test_context_.reset(new AppListViewTestContext(GetParam(), container));
688 void TearDown() override {
689 test_context_.reset();
690 views::ViewsTestBase::TearDown();
693 protected:
694 scoped_ptr<AppListViewTestContext> test_context_;
696 private:
697 DISALLOW_COPY_AND_ASSIGN(AppListViewTestAura);
700 class AppListViewTestDesktop : public views::ViewsTestBase,
701 public ::testing::WithParamInterface<int> {
702 public:
703 AppListViewTestDesktop() {}
704 virtual ~AppListViewTestDesktop() {}
706 // testing::Test overrides:
707 void SetUp() override {
708 set_views_delegate(new AppListViewTestViewsDelegate(this));
709 views::ViewsTestBase::SetUp();
710 test_context_.reset(new AppListViewTestContext(GetParam(), NULL));
713 void TearDown() override {
714 test_context_.reset();
715 views::ViewsTestBase::TearDown();
718 protected:
719 scoped_ptr<AppListViewTestContext> test_context_;
721 private:
722 class AppListViewTestViewsDelegate : public views::TestViewsDelegate {
723 public:
724 explicit AppListViewTestViewsDelegate(AppListViewTestDesktop* parent)
725 : parent_(parent) {}
727 // Overridden from views::ViewsDelegate:
728 void OnBeforeWidgetInit(
729 views::Widget::InitParams* params,
730 views::internal::NativeWidgetDelegate* delegate) override;
732 private:
733 AppListViewTestDesktop* parent_;
735 DISALLOW_COPY_AND_ASSIGN(AppListViewTestViewsDelegate);
738 DISALLOW_COPY_AND_ASSIGN(AppListViewTestDesktop);
741 void AppListViewTestDesktop::AppListViewTestViewsDelegate::OnBeforeWidgetInit(
742 views::Widget::InitParams* params,
743 views::internal::NativeWidgetDelegate* delegate) {
744 // Mimic the logic in ChromeViewsDelegate::OnBeforeWidgetInit(). Except, for
745 // ChromeOS, use the root window from the AuraTestHelper rather than depending
746 // on ash::Shell:GetPrimaryRootWindow(). Also assume non-ChromeOS is never the
747 // Ash desktop, as that is covered by AppListViewTestAura.
748 #if defined(OS_CHROMEOS)
749 if (!params->parent && !params->context)
750 params->context = parent_->GetContext();
751 #elif defined(USE_AURA)
752 if (params->parent == NULL && params->context == NULL && !params->child)
753 params->native_widget = new views::DesktopNativeWidgetAura(delegate);
754 #endif
757 } // namespace
759 // Tests showing the app list with basic test model in an ash-style root window.
760 TEST_P(AppListViewTestAura, Display) {
761 EXPECT_NO_FATAL_FAILURE(test_context_->RunDisplayTest());
764 // Tests showing the app list on the desktop. Note on ChromeOS, this will still
765 // use the regular root window.
766 TEST_P(AppListViewTestDesktop, Display) {
767 EXPECT_NO_FATAL_FAILURE(test_context_->RunDisplayTest());
770 // Tests that the main grid view is shown after hiding and reshowing the app
771 // list with a folder view open. This is a regression test for crbug.com/357058.
772 TEST_P(AppListViewTestAura, ReshowWithOpenFolder) {
773 EXPECT_NO_FATAL_FAILURE(test_context_->RunReshowWithOpenFolderTest());
776 TEST_P(AppListViewTestDesktop, ReshowWithOpenFolder) {
777 EXPECT_NO_FATAL_FAILURE(test_context_->RunReshowWithOpenFolderTest());
780 // Tests that the start page view operates correctly.
781 TEST_P(AppListViewTestAura, StartPageTest) {
782 EXPECT_NO_FATAL_FAILURE(test_context_->RunStartPageTest());
785 TEST_P(AppListViewTestDesktop, StartPageTest) {
786 EXPECT_NO_FATAL_FAILURE(test_context_->RunStartPageTest());
789 // Tests that the start page view operates correctly.
790 TEST_P(AppListViewTestAura, PageSwitchingAnimationTest) {
791 EXPECT_NO_FATAL_FAILURE(test_context_->RunPageSwitchingAnimationTest());
794 TEST_P(AppListViewTestDesktop, PageSwitchingAnimationTest) {
795 EXPECT_NO_FATAL_FAILURE(test_context_->RunPageSwitchingAnimationTest());
798 // Tests that the profile changes operate correctly.
799 TEST_P(AppListViewTestAura, ProfileChangeTest) {
800 EXPECT_NO_FATAL_FAILURE(test_context_->RunProfileChangeTest());
803 TEST_P(AppListViewTestDesktop, ProfileChangeTest) {
804 EXPECT_NO_FATAL_FAILURE(test_context_->RunProfileChangeTest());
807 // Tests that the correct views are displayed for showing search results.
808 TEST_P(AppListViewTestAura, SearchResultsTest) {
809 EXPECT_NO_FATAL_FAILURE(test_context_->RunSearchResultsTest());
812 TEST_P(AppListViewTestDesktop, SearchResultsTest) {
813 EXPECT_NO_FATAL_FAILURE(test_context_->RunSearchResultsTest());
816 // Tests that the back button navigates through the app list correctly.
817 TEST_P(AppListViewTestAura, BackTest) {
818 EXPECT_NO_FATAL_FAILURE(test_context_->RunBackTest());
821 TEST_P(AppListViewTestDesktop, BackTest) {
822 EXPECT_NO_FATAL_FAILURE(test_context_->RunBackTest());
825 // Tests that the correct views are displayed for showing search results.
826 TEST_P(AppListViewTestAura, AppListOverlayTest) {
827 EXPECT_NO_FATAL_FAILURE(test_context_->RunAppListOverlayTest());
830 TEST_P(AppListViewTestDesktop, AppListOverlayTest) {
831 EXPECT_NO_FATAL_FAILURE(test_context_->RunAppListOverlayTest());
834 #if defined(USE_AURA)
835 INSTANTIATE_TEST_CASE_P(AppListViewTestAuraInstance,
836 AppListViewTestAura,
837 ::testing::Range<int>(TEST_TYPE_START, TEST_TYPE_END));
838 #endif
840 INSTANTIATE_TEST_CASE_P(AppListViewTestDesktopInstance,
841 AppListViewTestDesktop,
842 ::testing::Range<int>(TEST_TYPE_START, TEST_TYPE_END));
844 } // namespace test
845 } // namespace app_list