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"
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"
46 NORMAL
= TEST_TYPE_START
,
53 size_t GetVisibleViews(const std::vector
<T
*>& tiles
) {
55 for (const auto& tile
: tiles
) {
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
{
77 TestStartPageSearchResult() { set_display_type(DISPLAY_RECOMMENDATION
); }
78 ~TestStartPageSearchResult() override
{}
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
{
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
97 void RunReshowWithOpenFolderTest();
99 // Tests that pressing the search box's back button navigates correctly.
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
123 void NativeWidgetClosing() {
128 // Whether the experimental "landscape" app launcher UI is being tested.
129 bool is_landscape() const {
130 return test_type_
== LANDSCAPE
|| test_type_
== EXPERIMENTAL
;
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.
145 // Closes the app list. This sets |view_| to NULL.
148 // Checks the search box widget is at |expected| in the contents view's
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
{
168 explicit UnitTestViewDelegate(AppListViewTestContext
* 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(); }
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_
) {
190 base::CommandLine::ForCurrentProcess()->AppendSwitch(
191 switches::kDisableExperimentalAppList
);
194 base::CommandLine::ForCurrentProcess()->AppendSwitch(
195 switches::kDisableExperimentalAppList
);
196 base::CommandLine::ForCurrentProcess()->AppendSwitch(
197 switches::kEnableCenteredAppList
);
200 base::CommandLine::ForCurrentProcess()->AppendSwitch(
201 switches::kEnableExperimentalAppList
);
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.
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();
245 for (int i
= 0; i
< contents_view
->NumLauncherPages(); ++i
) {
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());
259 EXPECT_TRUE(view_
->GetWidget()->IsVisible());
262 void AppListViewTestContext::Close() {
263 view_
->GetWidget()->Close();
264 run_loop_
.reset(new base::RunLoop
);
267 // |view_| should have been deleted and set to NULL via ViewClosing().
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()
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
);
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_
) {
301 EXPECT_EQ("400x500", view_
->bounds().size().ToString());
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());
310 EXPECT_EQ("768x570", view_
->bounds().size().ToString());
318 EXPECT_EQ(2, GetPaginationModel()->total_pages());
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());
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
);
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());
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());
381 void AppListViewTestContext::RunBackTest() {
382 if (test_type_
!= EXPERIMENTAL
) {
387 EXPECT_FALSE(view_
->GetWidget()->IsVisible());
388 EXPECT_EQ(-1, GetPaginationModel()->total_pages());
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());
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);
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
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()));
494 EXPECT_EQ(NULL
, start_page_view
);
500 void AppListViewTestContext::RunPageSwitchingAnimationTest() {
501 if (test_type_
== EXPERIMENTAL
) {
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
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
);
533 void AppListViewTestContext::RunProfileChangeTest() {
534 EXPECT_FALSE(view_
->GetWidget()->IsVisible());
535 EXPECT_EQ(-1, GetPaginationModel()->total_pages());
536 delegate_
->GetTestModel()->PopulateApps(kInitialItems
);
541 EXPECT_EQ(2, GetPaginationModel()->total_pages());
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
));
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()));
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);
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
));
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();
620 contents_view
->IsStateActive(AppListModel::STATE_SEARCH_RESULTS
));
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
));
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
));
641 CheckSearchBoxWidget(contents_view
->GetDefaultSearchBoxBounds()));
647 void AppListViewTestContext::RunAppListOverlayTest() {
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());
666 class AppListViewTestAura
: public views::ViewsTestBase
,
667 public ::testing::WithParamInterface
<int> {
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();
685 test_context_
.reset(new AppListViewTestContext(GetParam(), container
));
688 void TearDown() override
{
689 test_context_
.reset();
690 views::ViewsTestBase::TearDown();
694 scoped_ptr
<AppListViewTestContext
> test_context_
;
697 DISALLOW_COPY_AND_ASSIGN(AppListViewTestAura
);
700 class AppListViewTestDesktop
: public views::ViewsTestBase
,
701 public ::testing::WithParamInterface
<int> {
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();
719 scoped_ptr
<AppListViewTestContext
> test_context_
;
722 class AppListViewTestViewsDelegate
: public views::TestViewsDelegate
{
724 explicit AppListViewTestViewsDelegate(AppListViewTestDesktop
* parent
)
727 // Overridden from views::ViewsDelegate:
728 void OnBeforeWidgetInit(
729 views::Widget::InitParams
* params
,
730 views::internal::NativeWidgetDelegate
* delegate
) override
;
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
);
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
,
837 ::testing::Range
<int>(TEST_TYPE_START
, TEST_TYPE_END
));
840 INSTANTIATE_TEST_CASE_P(AppListViewTestDesktopInstance
,
841 AppListViewTestDesktop
,
842 ::testing::Range
<int>(TEST_TYPE_START
, TEST_TYPE_END
));
845 } // namespace app_list