Workaround for xkbcommon dead keys.
[chromium-blink-merge.git] / ui / app_list / views / app_list_view_unittest.cc
blob4fc6595db3f0e9529d8969af66d4f2ffc3a75207
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_switches.h"
16 #include "ui/app_list/pagination_model.h"
17 #include "ui/app_list/search_box_model.h"
18 #include "ui/app_list/test/app_list_test_model.h"
19 #include "ui/app_list/test/app_list_test_view_delegate.h"
20 #include "ui/app_list/test/test_search_result.h"
21 #include "ui/app_list/views/app_list_folder_view.h"
22 #include "ui/app_list/views/app_list_main_view.h"
23 #include "ui/app_list/views/apps_container_view.h"
24 #include "ui/app_list/views/apps_grid_view.h"
25 #include "ui/app_list/views/contents_view.h"
26 #include "ui/app_list/views/search_box_view.h"
27 #include "ui/app_list/views/search_result_list_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/views/controls/textfield/textfield.h"
34 #include "ui/views/test/views_test_base.h"
35 #include "ui/views/views_delegate.h"
36 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
38 namespace app_list {
39 namespace test {
41 namespace {
43 enum TestType {
44 TEST_TYPE_START = 0,
45 NORMAL = TEST_TYPE_START,
46 LANDSCAPE,
47 EXPERIMENTAL,
48 TEST_TYPE_END,
51 template <class T>
52 size_t GetVisibleViews(const std::vector<T*>& tiles) {
53 size_t count = 0;
54 for (const auto& tile : tiles) {
55 if (tile->visible())
56 count++;
58 return count;
61 void SimulateClick(views::View* view) {
62 gfx::Point center = view->GetLocalBounds().CenterPoint();
63 view->OnMousePressed(ui::MouseEvent(ui::ET_MOUSE_PRESSED,
64 center,
65 center,
66 ui::EF_LEFT_MOUSE_BUTTON,
67 ui::EF_LEFT_MOUSE_BUTTON));
68 view->OnMouseReleased(ui::MouseEvent(ui::ET_MOUSE_RELEASED,
69 center,
70 center,
71 ui::EF_LEFT_MOUSE_BUTTON,
72 ui::EF_LEFT_MOUSE_BUTTON));
75 // Choose a set that is 3 regular app list pages and 2 landscape app list pages.
76 const int kInitialItems = 34;
78 class TestStartPageSearchResult : public TestSearchResult {
79 public:
80 TestStartPageSearchResult() { set_display_type(DISPLAY_RECOMMENDATION); }
81 ~TestStartPageSearchResult() override {}
83 private:
84 DISALLOW_COPY_AND_ASSIGN(TestStartPageSearchResult);
87 // Allows the same tests to run with different contexts: either an Ash-style
88 // root window or a desktop window tree host.
89 class AppListViewTestContext {
90 public:
91 AppListViewTestContext(int test_type, gfx::NativeView parent);
92 ~AppListViewTestContext();
94 // Test displaying the app list and performs a standard set of checks on its
95 // top level views. Then closes the window.
96 void RunDisplayTest();
98 // Hides and reshows the app list with a folder open, expecting the main grid
99 // view to be shown.
100 void RunReshowWithOpenFolderTest();
102 // Tests that pressing the search box's back button navigates correctly.
103 void RunBackTest();
105 // Tests displaying of the experimental app list and shows the start page.
106 void RunStartPageTest();
108 // Tests switching rapidly between multiple pages of the launcher.
109 void RunPageSwitchingAnimationTest();
111 // Tests changing the App List profile.
112 void RunProfileChangeTest();
114 // Tests displaying of the search results.
115 void RunSearchResultsTest();
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 whether the app list showing |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 int index = contents_view->GetPageIndexForState(state);
238 contents_view->SetActivePage(index);
239 contents_view->Layout();
240 return IsStateShown(state);
243 bool AppListViewTestContext::IsStateShown(AppListModel::State state) {
244 ContentsView* contents_view = view_->app_list_main_view()->contents_view();
245 int index = contents_view->GetPageIndexForState(state);
246 bool success = true;
247 for (int i = 0; i < contents_view->NumLauncherPages(); ++i) {
248 success = success &&
249 (i == index) == (contents_view->GetDefaultContentsBounds() ==
250 contents_view->GetPageView(i)->bounds());
252 return success && state == delegate_->GetTestModel()->state();
255 void AppListViewTestContext::Show() {
256 view_->GetWidget()->Show();
257 run_loop_.reset(new base::RunLoop);
258 view_->SetNextPaintCallback(run_loop_->QuitClosure());
259 run_loop_->Run();
261 EXPECT_TRUE(view_->GetWidget()->IsVisible());
264 void AppListViewTestContext::Close() {
265 view_->GetWidget()->Close();
266 run_loop_.reset(new base::RunLoop);
267 run_loop_->Run();
269 // |view_| should have been deleted and set to NULL via ViewClosing().
270 EXPECT_FALSE(view_);
273 bool AppListViewTestContext::CheckSearchBoxWidget(const gfx::Rect& expected) {
274 ContentsView* contents_view = view_->app_list_main_view()->contents_view();
275 gfx::Point point = expected.origin();
276 views::View::ConvertPointToScreen(contents_view, &point);
278 return gfx::Rect(point, expected.size()) ==
279 view_->search_box_widget()->GetWindowBoundsInScreen();
282 PaginationModel* AppListViewTestContext::GetPaginationModel() {
283 return view_->GetAppsPaginationModel();
286 void AppListViewTestContext::RunDisplayTest() {
287 EXPECT_FALSE(view_->GetWidget()->IsVisible());
288 EXPECT_EQ(-1, GetPaginationModel()->total_pages());
289 delegate_->GetTestModel()->PopulateApps(kInitialItems);
291 Show();
293 // Explicitly enforce the exact dimensions of the app list. Feel free to
294 // change these if you need to (they are just here to prevent against
295 // accidental changes to the window size).
296 switch (test_type_) {
297 case NORMAL:
298 EXPECT_EQ("400x500", view_->bounds().size().ToString());
299 break;
300 case LANDSCAPE:
301 // NOTE: Height should not exceed 402, because otherwise there might not
302 // be enough space to accomodate the virtual keyboard. (LANDSCAPE mode is
303 // enabled by default when the virtual keyboard is enabled.)
304 EXPECT_EQ("576x402", view_->bounds().size().ToString());
305 break;
306 case EXPERIMENTAL:
307 // TODO(calamity): This should be 768x560, to match the most recent mocks.
308 EXPECT_EQ("768x577", view_->bounds().size().ToString());
309 break;
310 default:
311 NOTREACHED();
312 break;
315 if (is_landscape())
316 EXPECT_EQ(2, GetPaginationModel()->total_pages());
317 else
318 EXPECT_EQ(3, GetPaginationModel()->total_pages());
319 EXPECT_EQ(0, GetPaginationModel()->selected_page());
321 // Checks on the main view.
322 AppListMainView* main_view = view_->app_list_main_view();
323 EXPECT_NO_FATAL_FAILURE(CheckView(main_view));
324 EXPECT_NO_FATAL_FAILURE(CheckView(main_view->contents_view()));
326 AppListModel::State expected = test_type_ == EXPERIMENTAL
327 ? AppListModel::STATE_START
328 : AppListModel::STATE_APPS;
329 EXPECT_TRUE(main_view->contents_view()->IsStateActive(expected));
330 EXPECT_EQ(expected, delegate_->GetTestModel()->state());
332 Close();
335 void AppListViewTestContext::RunReshowWithOpenFolderTest() {
336 EXPECT_FALSE(view_->GetWidget()->IsVisible());
337 EXPECT_EQ(-1, GetPaginationModel()->total_pages());
339 AppListTestModel* model = delegate_->GetTestModel();
340 model->PopulateApps(kInitialItems);
341 const std::string folder_id =
342 model->MergeItems(model->top_level_item_list()->item_at(0)->id(),
343 model->top_level_item_list()->item_at(1)->id());
345 AppListFolderItem* folder_item = model->FindFolderItem(folder_id);
346 EXPECT_TRUE(folder_item);
348 Show();
350 // The main grid view should be showing initially.
351 AppListMainView* main_view = view_->app_list_main_view();
352 AppsContainerView* container_view =
353 main_view->contents_view()->apps_container_view();
354 EXPECT_NO_FATAL_FAILURE(CheckView(main_view));
355 EXPECT_NO_FATAL_FAILURE(CheckView(container_view->apps_grid_view()));
356 EXPECT_FALSE(container_view->app_list_folder_view()->visible());
358 AppsGridViewTestApi test_api(container_view->apps_grid_view());
359 test_api.PressItemAt(0);
361 // After pressing the folder item, the folder view should be showing.
362 EXPECT_NO_FATAL_FAILURE(CheckView(main_view));
363 EXPECT_NO_FATAL_FAILURE(CheckView(container_view->app_list_folder_view()));
364 EXPECT_FALSE(container_view->apps_grid_view()->visible());
366 view_->GetWidget()->Hide();
367 EXPECT_FALSE(view_->GetWidget()->IsVisible());
369 Show();
371 // The main grid view should be showing after a reshow.
372 EXPECT_NO_FATAL_FAILURE(CheckView(main_view));
373 EXPECT_NO_FATAL_FAILURE(CheckView(container_view->apps_grid_view()));
374 EXPECT_FALSE(container_view->app_list_folder_view()->visible());
376 Close();
379 void AppListViewTestContext::RunBackTest() {
380 if (test_type_ != EXPERIMENTAL) {
381 Close();
382 return;
385 EXPECT_FALSE(view_->GetWidget()->IsVisible());
386 EXPECT_EQ(-1, GetPaginationModel()->total_pages());
388 Show();
390 AppListMainView* main_view = view_->app_list_main_view();
391 ContentsView* contents_view = main_view->contents_view();
392 SearchBoxView* search_box_view = main_view->search_box_view();
394 // Show the apps grid.
395 SetAppListState(AppListModel::STATE_APPS);
396 EXPECT_NO_FATAL_FAILURE(CheckView(search_box_view->back_button()));
398 // The back button should return to the start page.
399 EXPECT_TRUE(contents_view->Back());
400 contents_view->Layout();
401 EXPECT_TRUE(IsStateShown(AppListModel::STATE_START));
402 EXPECT_FALSE(search_box_view->back_button()->visible());
404 // Show the apps grid again.
405 SetAppListState(AppListModel::STATE_APPS);
406 EXPECT_NO_FATAL_FAILURE(CheckView(search_box_view->back_button()));
408 // Pressing ESC should return to the start page.
409 view_->AcceleratorPressed(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
410 contents_view->Layout();
411 EXPECT_TRUE(IsStateShown(AppListModel::STATE_START));
412 EXPECT_FALSE(search_box_view->back_button()->visible());
414 // Pressing ESC from the start page should close the app list.
415 EXPECT_EQ(0, delegate_->dismiss_count());
416 view_->AcceleratorPressed(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
417 EXPECT_EQ(1, delegate_->dismiss_count());
419 // Show the search results.
420 base::string16 new_search_text = base::UTF8ToUTF16("apple");
421 search_box_view->search_box()->SetText(base::string16());
422 search_box_view->search_box()->InsertText(new_search_text);
423 contents_view->Layout();
424 EXPECT_TRUE(IsStateShown(AppListModel::STATE_SEARCH_RESULTS));
425 EXPECT_NO_FATAL_FAILURE(CheckView(search_box_view->back_button()));
427 // The back button should return to the start page.
428 EXPECT_TRUE(contents_view->Back());
429 contents_view->Layout();
430 EXPECT_TRUE(IsStateShown(AppListModel::STATE_START));
431 EXPECT_FALSE(search_box_view->back_button()->visible());
433 Close();
436 void AppListViewTestContext::RunStartPageTest() {
437 EXPECT_FALSE(view_->GetWidget()->IsVisible());
438 EXPECT_EQ(-1, GetPaginationModel()->total_pages());
439 AppListTestModel* model = delegate_->GetTestModel();
440 model->PopulateApps(3);
442 Show();
444 AppListMainView* main_view = view_->app_list_main_view();
445 StartPageView* start_page_view =
446 main_view->contents_view()->start_page_view();
447 // Checks on the main view.
448 EXPECT_NO_FATAL_FAILURE(CheckView(main_view));
449 EXPECT_NO_FATAL_FAILURE(CheckView(main_view->contents_view()));
450 if (test_type_ == EXPERIMENTAL) {
451 EXPECT_NO_FATAL_FAILURE(CheckView(start_page_view));
453 // Show the start page view.
454 EXPECT_TRUE(SetAppListState(AppListModel::STATE_START));
455 gfx::Size view_size(view_->GetPreferredSize());
457 // Simulate clicking the "All apps" button. Check that we navigate to the
458 // apps grid view.
459 EXPECT_TRUE(start_page_view->all_apps_button()->visible());
460 SimulateClick(start_page_view->all_apps_button());
461 main_view->contents_view()->Layout();
462 EXPECT_TRUE(IsStateShown(AppListModel::STATE_APPS));
464 // Hiding and showing the search box should not affect the app list's
465 // preferred size. This is a regression test for http://crbug.com/386912.
466 EXPECT_EQ(view_size.ToString(), view_->GetPreferredSize().ToString());
468 // Check tiles hide and show on deletion and addition.
469 model->results()->Add(new TestStartPageSearchResult());
470 start_page_view->UpdateForTesting();
471 EXPECT_EQ(1u, GetVisibleViews(start_page_view->tile_views()));
472 model->results()->DeleteAll();
473 start_page_view->UpdateForTesting();
474 EXPECT_EQ(0u, GetVisibleViews(start_page_view->tile_views()));
475 } else {
476 EXPECT_EQ(NULL, start_page_view);
479 Close();
482 void AppListViewTestContext::RunPageSwitchingAnimationTest() {
483 if (test_type_ == EXPERIMENTAL) {
484 Show();
486 AppListMainView* main_view = view_->app_list_main_view();
487 // Checks on the main view.
488 EXPECT_NO_FATAL_FAILURE(CheckView(main_view));
489 EXPECT_NO_FATAL_FAILURE(CheckView(main_view->contents_view()));
491 ContentsView* contents_view = main_view->contents_view();
492 // Pad the ContentsView with blank pages so we have at least 3 views.
493 while (contents_view->NumLauncherPages() < 3)
494 contents_view->AddBlankPageForTesting();
496 contents_view->SetActivePage(0);
497 contents_view->Layout();
499 const gfx::Rect expected_bounds = contents_view->GetDefaultContentsBounds();
501 EXPECT_EQ(expected_bounds, contents_view->GetPageView(0)->bounds());
502 EXPECT_NE(expected_bounds, contents_view->GetPageView(1)->bounds());
503 EXPECT_NE(expected_bounds, contents_view->GetPageView(2)->bounds());
505 // Change pages. View should not have moved without Layout().
506 contents_view->SetActivePage(1);
507 EXPECT_EQ(expected_bounds, contents_view->GetPageView(0)->bounds());
508 EXPECT_NE(expected_bounds, contents_view->GetPageView(1)->bounds());
509 EXPECT_NE(expected_bounds, contents_view->GetPageView(2)->bounds());
511 // Change to a third page. This queues up the second animation behind the
512 // first.
513 contents_view->SetActivePage(2);
514 EXPECT_EQ(expected_bounds, contents_view->GetPageView(0)->bounds());
515 EXPECT_NE(expected_bounds, contents_view->GetPageView(1)->bounds());
516 EXPECT_NE(expected_bounds, contents_view->GetPageView(2)->bounds());
518 // Call Layout(). Should jump to the third page.
519 contents_view->Layout();
520 EXPECT_NE(expected_bounds, contents_view->GetPageView(0)->bounds());
521 EXPECT_NE(expected_bounds, contents_view->GetPageView(1)->bounds());
522 EXPECT_EQ(expected_bounds, contents_view->GetPageView(2)->bounds());
525 Close();
528 void AppListViewTestContext::RunProfileChangeTest() {
529 EXPECT_FALSE(view_->GetWidget()->IsVisible());
530 EXPECT_EQ(-1, GetPaginationModel()->total_pages());
531 delegate_->GetTestModel()->PopulateApps(kInitialItems);
533 Show();
535 if (is_landscape())
536 EXPECT_EQ(2, GetPaginationModel()->total_pages());
537 else
538 EXPECT_EQ(3, GetPaginationModel()->total_pages());
540 // Change the profile. The original model needs to be kept alive for
541 // observers to unregister themselves.
542 scoped_ptr<AppListTestModel> original_test_model(
543 delegate_->ReleaseTestModel());
544 delegate_->set_next_profile_app_count(1);
546 // The original ContentsView is destroyed here.
547 view_->SetProfileByPath(base::FilePath());
548 EXPECT_EQ(1, GetPaginationModel()->total_pages());
550 StartPageView* start_page_view =
551 view_->app_list_main_view()->contents_view()->start_page_view();
552 if (test_type_ == EXPERIMENTAL)
553 EXPECT_NO_FATAL_FAILURE(CheckView(start_page_view));
554 else
555 EXPECT_EQ(NULL, start_page_view);
557 // New model updates should be processed by the start page view.
558 delegate_->GetTestModel()->results()->Add(new TestStartPageSearchResult());
559 if (test_type_ == EXPERIMENTAL) {
560 start_page_view->UpdateForTesting();
561 EXPECT_EQ(1u, GetVisibleViews(start_page_view->tile_views()));
564 // Old model updates should be ignored.
565 original_test_model->results()->Add(new TestStartPageSearchResult());
566 original_test_model->results()->Add(new TestStartPageSearchResult());
567 if (test_type_ == EXPERIMENTAL) {
568 start_page_view->UpdateForTesting();
569 EXPECT_EQ(1u, GetVisibleViews(start_page_view->tile_views()));
572 Close();
575 void AppListViewTestContext::RunSearchResultsTest() {
576 EXPECT_FALSE(view_->GetWidget()->IsVisible());
577 EXPECT_EQ(-1, GetPaginationModel()->total_pages());
578 AppListTestModel* model = delegate_->GetTestModel();
579 model->PopulateApps(3);
581 Show();
583 AppListMainView* main_view = view_->app_list_main_view();
584 ContentsView* contents_view = main_view->contents_view();
585 EXPECT_TRUE(SetAppListState(AppListModel::STATE_APPS));
587 // Show the search results.
588 contents_view->ShowSearchResults(true);
589 contents_view->Layout();
590 EXPECT_TRUE(contents_view->IsStateActive(AppListModel::STATE_SEARCH_RESULTS));
592 const gfx::Rect default_contents_bounds =
593 contents_view->GetDefaultContentsBounds();
594 EXPECT_EQ(AppListModel::STATE_SEARCH_RESULTS,
595 delegate_->GetTestModel()->state());
596 if (test_type_ == EXPERIMENTAL) {
597 EXPECT_EQ(default_contents_bounds,
598 contents_view->search_results_page_view()->bounds());
599 } else {
600 EXPECT_EQ(default_contents_bounds,
601 contents_view->search_results_list_view()->bounds());
604 // Hide the search results.
605 contents_view->ShowSearchResults(false);
606 contents_view->Layout();
608 // Check that we return to the page that we were on before the search.
609 EXPECT_TRUE(contents_view->IsStateActive(AppListModel::STATE_APPS));
610 EXPECT_EQ(AppListModel::STATE_APPS, delegate_->GetTestModel()->state());
611 EXPECT_EQ(default_contents_bounds,
612 contents_view->apps_container_view()->bounds());
614 if (test_type_ == EXPERIMENTAL) {
615 // Check that typing into the search box triggers the search page.
616 EXPECT_TRUE(SetAppListState(AppListModel::STATE_START));
617 view_->Layout();
618 EXPECT_EQ(default_contents_bounds,
619 contents_view->start_page_view()->bounds());
620 EXPECT_TRUE(CheckSearchBoxWidget(
621 contents_view->GetSearchBoxBoundsForState(AppListModel::STATE_START)));
623 base::string16 search_text = base::UTF8ToUTF16("test");
624 main_view->search_box_view()->search_box()->SetText(base::string16());
625 main_view->search_box_view()->search_box()->InsertText(search_text);
626 // Check that the current search is using |search_text|.
627 EXPECT_EQ(search_text, delegate_->GetTestModel()->search_box()->text());
628 EXPECT_EQ(search_text, main_view->search_box_view()->search_box()->text());
629 contents_view->Layout();
630 EXPECT_TRUE(
631 contents_view->IsStateActive(AppListModel::STATE_SEARCH_RESULTS));
632 EXPECT_TRUE(
633 CheckSearchBoxWidget(contents_view->GetDefaultSearchBoxBounds()));
635 // Check that typing into the search box triggers the search page.
636 EXPECT_TRUE(SetAppListState(AppListModel::STATE_APPS));
637 contents_view->Layout();
638 EXPECT_EQ(default_contents_bounds,
639 contents_view->apps_container_view()->bounds());
640 EXPECT_TRUE(
641 CheckSearchBoxWidget(contents_view->GetDefaultSearchBoxBounds()));
643 base::string16 new_search_text = base::UTF8ToUTF16("apple");
644 main_view->search_box_view()->search_box()->SetText(base::string16());
645 main_view->search_box_view()->search_box()->InsertText(new_search_text);
646 // Check that the current search is using |new_search_text|.
647 EXPECT_EQ(new_search_text, delegate_->GetTestModel()->search_box()->text());
648 EXPECT_EQ(new_search_text,
649 main_view->search_box_view()->search_box()->text());
650 contents_view->Layout();
651 EXPECT_TRUE(
652 contents_view->IsStateActive(AppListModel::STATE_SEARCH_RESULTS));
653 EXPECT_TRUE(
654 CheckSearchBoxWidget(contents_view->GetDefaultSearchBoxBounds()));
657 Close();
660 class AppListViewTestAura : public views::ViewsTestBase,
661 public ::testing::WithParamInterface<int> {
662 public:
663 AppListViewTestAura() {}
664 virtual ~AppListViewTestAura() {}
666 // testing::Test overrides:
667 void SetUp() override {
668 views::ViewsTestBase::SetUp();
670 // On Ash (only) the app list is placed into an aura::Window "container",
671 // which is also used to determine the context. In tests, use the ash root
672 // window as the parent. This only works on aura where the root window is a
673 // NativeView as well as a NativeWindow.
674 gfx::NativeView container = NULL;
675 #if defined(USE_AURA)
676 container = GetContext();
677 #endif
679 test_context_.reset(new AppListViewTestContext(GetParam(), container));
682 void TearDown() override {
683 test_context_.reset();
684 views::ViewsTestBase::TearDown();
687 protected:
688 scoped_ptr<AppListViewTestContext> test_context_;
690 private:
691 DISALLOW_COPY_AND_ASSIGN(AppListViewTestAura);
694 class AppListViewTestDesktop : public views::ViewsTestBase,
695 public ::testing::WithParamInterface<int> {
696 public:
697 AppListViewTestDesktop() {}
698 virtual ~AppListViewTestDesktop() {}
700 // testing::Test overrides:
701 void SetUp() override {
702 set_views_delegate(new AppListViewTestViewsDelegate(this));
703 views::ViewsTestBase::SetUp();
704 test_context_.reset(new AppListViewTestContext(GetParam(), NULL));
707 void TearDown() override {
708 test_context_.reset();
709 views::ViewsTestBase::TearDown();
712 protected:
713 scoped_ptr<AppListViewTestContext> test_context_;
715 private:
716 class AppListViewTestViewsDelegate : public views::TestViewsDelegate {
717 public:
718 explicit AppListViewTestViewsDelegate(AppListViewTestDesktop* parent)
719 : parent_(parent) {}
721 // Overridden from views::ViewsDelegate:
722 void OnBeforeWidgetInit(
723 views::Widget::InitParams* params,
724 views::internal::NativeWidgetDelegate* delegate) override;
726 private:
727 AppListViewTestDesktop* parent_;
729 DISALLOW_COPY_AND_ASSIGN(AppListViewTestViewsDelegate);
732 DISALLOW_COPY_AND_ASSIGN(AppListViewTestDesktop);
735 void AppListViewTestDesktop::AppListViewTestViewsDelegate::OnBeforeWidgetInit(
736 views::Widget::InitParams* params,
737 views::internal::NativeWidgetDelegate* delegate) {
738 // Mimic the logic in ChromeViewsDelegate::OnBeforeWidgetInit(). Except, for
739 // ChromeOS, use the root window from the AuraTestHelper rather than depending
740 // on ash::Shell:GetPrimaryRootWindow(). Also assume non-ChromeOS is never the
741 // Ash desktop, as that is covered by AppListViewTestAura.
742 #if defined(OS_CHROMEOS)
743 if (!params->parent && !params->context)
744 params->context = parent_->GetContext();
745 #elif defined(USE_AURA)
746 if (params->parent == NULL && params->context == NULL && !params->child)
747 params->native_widget = new views::DesktopNativeWidgetAura(delegate);
748 #endif
751 } // namespace
753 // Tests showing the app list with basic test model in an ash-style root window.
754 TEST_P(AppListViewTestAura, Display) {
755 EXPECT_NO_FATAL_FAILURE(test_context_->RunDisplayTest());
758 // Tests showing the app list on the desktop. Note on ChromeOS, this will still
759 // use the regular root window.
760 TEST_P(AppListViewTestDesktop, Display) {
761 EXPECT_NO_FATAL_FAILURE(test_context_->RunDisplayTest());
764 // Tests that the main grid view is shown after hiding and reshowing the app
765 // list with a folder view open. This is a regression test for crbug.com/357058.
766 TEST_P(AppListViewTestAura, ReshowWithOpenFolder) {
767 EXPECT_NO_FATAL_FAILURE(test_context_->RunReshowWithOpenFolderTest());
770 TEST_P(AppListViewTestDesktop, ReshowWithOpenFolder) {
771 EXPECT_NO_FATAL_FAILURE(test_context_->RunReshowWithOpenFolderTest());
774 // Tests that the start page view operates correctly.
775 TEST_P(AppListViewTestAura, StartPageTest) {
776 EXPECT_NO_FATAL_FAILURE(test_context_->RunStartPageTest());
779 TEST_P(AppListViewTestDesktop, StartPageTest) {
780 EXPECT_NO_FATAL_FAILURE(test_context_->RunStartPageTest());
783 // Tests that the start page view operates correctly.
784 TEST_P(AppListViewTestAura, PageSwitchingAnimationTest) {
785 EXPECT_NO_FATAL_FAILURE(test_context_->RunPageSwitchingAnimationTest());
788 TEST_P(AppListViewTestDesktop, PageSwitchingAnimationTest) {
789 EXPECT_NO_FATAL_FAILURE(test_context_->RunPageSwitchingAnimationTest());
792 // Tests that the profile changes operate correctly.
793 TEST_P(AppListViewTestAura, ProfileChangeTest) {
794 EXPECT_NO_FATAL_FAILURE(test_context_->RunProfileChangeTest());
797 TEST_P(AppListViewTestDesktop, ProfileChangeTest) {
798 EXPECT_NO_FATAL_FAILURE(test_context_->RunProfileChangeTest());
801 // Tests that the correct views are displayed for showing search results.
802 TEST_P(AppListViewTestAura, SearchResultsTest) {
803 EXPECT_NO_FATAL_FAILURE(test_context_->RunSearchResultsTest());
806 TEST_P(AppListViewTestDesktop, SearchResultsTest) {
807 EXPECT_NO_FATAL_FAILURE(test_context_->RunSearchResultsTest());
810 // Tests that the back button navigates through the app list correctly.
811 TEST_P(AppListViewTestAura, BackTest) {
812 EXPECT_NO_FATAL_FAILURE(test_context_->RunBackTest());
815 TEST_P(AppListViewTestDesktop, BackTest) {
816 EXPECT_NO_FATAL_FAILURE(test_context_->RunBackTest());
819 INSTANTIATE_TEST_CASE_P(AppListViewTestAuraInstance,
820 AppListViewTestAura,
821 ::testing::Range<int>(TEST_TYPE_START, TEST_TYPE_END));
823 INSTANTIATE_TEST_CASE_P(AppListViewTestDesktopInstance,
824 AppListViewTestDesktop,
825 ::testing::Range<int>(TEST_TYPE_START, TEST_TYPE_END));
827 } // namespace test
828 } // namespace app_list