Commit 2c9819fd authored by wutao's avatar wutao Committed by Commit Bot

app_list: Add unit tests for embedded Assistant UI

This patch adds unit tests for emebedded Assistant UI to test the basic
UI visibility and app list states.

Bug: 924624
Test: AppListView*Test:*EmbeddedAssistantUI*
Change-Id: I588ffb174d5f4e6ec2a1e0c80d139648740a01fb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1501514
Commit-Queue: Tao Wu <wutao@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#638422}
parent 63e07e35
...@@ -229,6 +229,7 @@ test("app_list_unittests") { ...@@ -229,6 +229,7 @@ test("app_list_unittests") {
"//ash/public/cpp/app_list/vector_icons", "//ash/public/cpp/app_list/vector_icons",
"//base", "//base",
"//base/test:test_support", "//base/test:test_support",
"//chromeos/constants",
"//mojo/core/embedder", "//mojo/core/embedder",
"//mojo/public/cpp/bindings", "//mojo/public/cpp/bindings",
"//services/content/public/cpp", "//services/content/public/cpp",
......
...@@ -4,6 +4,7 @@ include_rules = [ ...@@ -4,6 +4,7 @@ include_rules = [
"+ash/assistant/util", "+ash/assistant/util",
"+ash/resources/vector_icons", "+ash/resources/vector_icons",
"+ash/strings", "+ash/strings",
"+chromeos/constants",
"+components/keyed_service/core", "+components/keyed_service/core",
"+components/sync", "+components/sync",
"+mojo/public/cpp", "+mojo/public/cpp",
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <vector> #include <vector>
#include "ash/app_list/model/app_list_model.h" #include "ash/app_list/model/app_list_model.h"
#include "ash/public/cpp/app_list/app_list_features.h"
#include "ash/public/cpp/app_list/app_list_switches.h" #include "ash/public/cpp/app_list/app_list_switches.h"
#include "ash/public/cpp/menu_utils.h" #include "ash/public/cpp/menu_utils.h"
#include "base/callback.h" #include "base/callback.h"
...@@ -40,6 +41,10 @@ void AppListTestViewDelegate::OpenSearchResult(const std::string& result_id, ...@@ -40,6 +41,10 @@ void AppListTestViewDelegate::OpenSearchResult(const std::string& result_id,
for (size_t i = 0; i < results->item_count(); ++i) { for (size_t i = 0; i < results->item_count(); ++i) {
if (results->GetItemAt(i)->id() == result_id) { if (results->GetItemAt(i)->id() == result_id) {
open_search_result_counts_[i]++; open_search_result_counts_[i]++;
if (app_list_features::IsEmbeddedAssistantUIEnabled() &&
results->GetItemAt(i)->is_omnibox_search()) {
++open_assistant_ui_count_;
}
break; break;
} }
} }
......
...@@ -35,6 +35,7 @@ class AppListTestViewDelegate : public AppListViewDelegate, ...@@ -35,6 +35,7 @@ class AppListTestViewDelegate : public AppListViewDelegate,
int dismiss_count() const { return dismiss_count_; } int dismiss_count() const { return dismiss_count_; }
int open_search_result_count() const { return open_search_result_count_; } int open_search_result_count() const { return open_search_result_count_; }
int open_assistant_ui_count() const { return open_assistant_ui_count_; }
std::map<size_t, int>& open_search_result_counts() { std::map<size_t, int>& open_search_result_counts() {
return open_search_result_counts_; return open_search_result_counts_;
} }
...@@ -108,6 +109,7 @@ class AppListTestViewDelegate : public AppListViewDelegate, ...@@ -108,6 +109,7 @@ class AppListTestViewDelegate : public AppListViewDelegate,
int dismiss_count_ = 0; int dismiss_count_ = 0;
int open_search_result_count_ = 0; int open_search_result_count_ = 0;
int open_assistant_ui_count_ = 0;
int next_profile_app_count_ = 0; int next_profile_app_count_ = 0;
int show_wallpaper_context_menu_count_ = 0; int show_wallpaper_context_menu_count_ = 0;
std::map<size_t, int> open_search_result_counts_; std::map<size_t, int> open_search_result_counts_;
......
...@@ -40,10 +40,12 @@ ...@@ -40,10 +40,12 @@
#include "ash/public/cpp/app_list/app_list_features.h" #include "ash/public/cpp/app_list/app_list_features.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/test/icu_test_util.h" #include "base/test/icu_test_util.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "chromeos/constants/chromeos_switches.h"
#include "services/content/public/cpp/test/fake_navigable_contents.h" #include "services/content/public/cpp/test/fake_navigable_contents.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/models/simple_menu_model.h" #include "ui/base/models/simple_menu_model.h"
...@@ -346,6 +348,34 @@ class AppListViewFocusTest : public views::ViewsTestBase, ...@@ -346,6 +348,34 @@ class AppListViewFocusTest : public views::ViewsTestBase,
RunPendingMessages(); RunPendingMessages();
} }
// Add search results for test on embedded Assistant UI.
void SetUpSearchResultsForAssistantUI(int list_results_num,
int index_open_assistant_ui) {
SearchModel::SearchResults* results =
delegate_->GetSearchModel()->results();
results->DeleteAll();
double display_score = list_results_num;
for (int i = 0; i < list_results_num; ++i) {
// Set the display score of the results in decreasing order
// (so the earlier groups have higher display score, and therefore appear
// first).
display_score -= 1;
std::unique_ptr<TestSearchResult> result =
std::make_unique<TestSearchResult>();
result->set_display_type(ash::SearchResultDisplayType::kList);
result->set_display_score(display_score);
result->set_title(base::ASCIIToUTF16("Test" + base::NumberToString(i)));
result->set_result_id("Test" + base::NumberToString(i));
if (i == index_open_assistant_ui)
result->set_is_omnibox_search(true);
results->Add(std::move(result));
}
// Adding results will schedule Update().
RunPendingMessages();
}
void ClearSearchResults() { void ClearSearchResults() {
delegate_->GetSearchModel()->results()->DeleteAll(); delegate_->GetSearchModel()->results()->DeleteAll();
} }
...@@ -372,6 +402,10 @@ class AppListViewFocusTest : public views::ViewsTestBase, ...@@ -372,6 +402,10 @@ class AppListViewFocusTest : public views::ViewsTestBase,
return delegate_->open_search_result_count(); return delegate_->open_search_result_count();
} }
int GetTotalOpenAssistantUICount() {
return delegate_->open_assistant_ui_count();
}
// Test focus traversal across all the views in |view_list|. The initial focus // Test focus traversal across all the views in |view_list|. The initial focus
// is expected to be on the first view in |view_list|. The final focus is // is expected to be on the first view in |view_list|. The final focus is
// expected to be on the last view in |view_list| after |view_list.size()-1| // expected to be on the last view in |view_list| after |view_list.size()-1|
...@@ -2099,5 +2133,128 @@ TEST_F(AppListViewTest, BackAction) { ...@@ -2099,5 +2133,128 @@ TEST_F(AppListViewTest, BackAction) {
EXPECT_EQ(0, apps_grid_view()->pagination_model()->selected_page()); EXPECT_EQ(0, apps_grid_view()->pagination_model()->selected_page());
} }
// Tests selecting search result to show embedded Assistant UI.
TEST_F(AppListViewFocusTest, ShowEmbeddedAssistantUI) {
scoped_feature_list_.InitWithFeatures(
{chromeos::switches::kAssistantFeature,
app_list_features::kEnableEmbeddedAssistantUI},
{});
Show();
// Initially the search box is inactive, hitting Enter to activate it.
EXPECT_FALSE(search_box_view()->is_search_box_active());
SimulateKeyPress(ui::VKEY_RETURN, false);
EXPECT_TRUE(search_box_view()->is_search_box_active());
// Type something in search box to transition to HALF state and populate
// fake list results. Then hit Enter key.
search_box_view()->search_box()->InsertText(base::UTF8ToUTF16("test"));
const int kListResults = 2;
const int kIndexOpenAssistantUi = 1;
SetUpSearchResultsForAssistantUI(kListResults, kIndexOpenAssistantUi);
SimulateKeyPress(ui::VKEY_RETURN, false);
EXPECT_EQ(1, GetOpenFirstSearchResultCount());
EXPECT_EQ(1, GetTotalOpenSearchResultCount());
EXPECT_EQ(0, GetTotalOpenAssistantUICount());
SearchResultListView* list_view =
contents_view()->search_result_list_view_for_test();
ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE);
list_view->GetResultViewAt(kIndexOpenAssistantUi)->OnKeyEvent(&key_event);
EXPECT_EQ(1, GetOpenFirstSearchResultCount());
EXPECT_EQ(2, GetTotalOpenSearchResultCount());
EXPECT_EQ(1, GetTotalOpenAssistantUICount());
}
// Tests that no answer card view when kEnableEmbeddedAssistantUI is enabled.
TEST_F(AppListViewTest, NoAnswerCardWhenEmbeddedAssistantUIEnabled) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{chromeos::switches::kAssistantFeature,
app_list_features::kEnableEmbeddedAssistantUI},
{});
ASSERT_TRUE(app_list_features::IsEmbeddedAssistantUIEnabled());
Initialize(0, false, false);
Show();
EXPECT_FALSE(contents_view()->search_result_answer_card_view_for_test());
}
// Tests that pressing escape when in embedded Assistant UI to search page view.
TEST_F(AppListViewTest, EscapeKeyEmbeddedAssistantUIToSearch) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{chromeos::switches::kAssistantFeature,
app_list_features::kEnableEmbeddedAssistantUI},
{});
ASSERT_TRUE(app_list_features::IsEmbeddedAssistantUIEnabled());
Initialize(0, false, false);
Show();
// Set search_box_view active.
ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE);
view_->GetWidget()->OnKeyEvent(&key_event);
contents_view()->ShowEmbeddedAssistantUI(true);
EXPECT_TRUE(contents_view()->IsShowingEmbeddedAssistantUI());
view_->AcceleratorPressed(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
EXPECT_TRUE(contents_view()->IsShowingSearchResults());
}
// Tests that clicking empty region in AppListview when showing Assistant UI
// should go back to peeking state.
TEST_F(AppListViewTest, ClickOutsideEmbeddedAssistantUIToPeeking) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{chromeos::switches::kAssistantFeature,
app_list_features::kEnableEmbeddedAssistantUI},
{});
ASSERT_TRUE(app_list_features::IsEmbeddedAssistantUIEnabled());
Initialize(0, false, false);
Show();
// Set search_box_view active.
ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE);
view_->GetWidget()->OnKeyEvent(&key_event);
contents_view()->ShowEmbeddedAssistantUI(true);
EXPECT_TRUE(contents_view()->IsShowingEmbeddedAssistantUI());
// Click on the same empty region, the AppList should be peeking state.
const gfx::Point empty_region = view_->GetBoundsInScreen().origin();
ui::MouseEvent mouse_click(ui::ET_MOUSE_PRESSED, empty_region, empty_region,
base::TimeTicks(), 0, 0);
ui::Event::DispatcherApi mouse_click_dispatcher_api(
static_cast<ui::Event*>(&mouse_click));
mouse_click_dispatcher_api.set_target(view_);
view_->OnMouseEvent(&mouse_click);
EXPECT_EQ(AppListViewState::PEEKING, view_->app_list_state());
}
// Tests that expand arrow is not visible when showing embedded Assistant UI.
TEST_F(AppListViewTest, ExpandArrowNotVisibleInEmbeddedAssistantUI) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{chromeos::switches::kAssistantFeature,
app_list_features::kEnableEmbeddedAssistantUI},
{});
ASSERT_TRUE(app_list_features::IsEmbeddedAssistantUIEnabled());
Initialize(0, false, false);
Show();
// Set search_box_view active.
ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE);
view_->GetWidget()->OnKeyEvent(&key_event);
contents_view()->ShowEmbeddedAssistantUI(true);
EXPECT_TRUE(contents_view()->IsShowingEmbeddedAssistantUI());
EXPECT_TRUE(contents_view()->expand_arrow_view()->layer()->opacity() == 0.0f);
}
} // namespace test } // namespace test
} // namespace app_list } // namespace app_list
...@@ -50,8 +50,11 @@ void AssistantPageView::InitLayout() { ...@@ -50,8 +50,11 @@ void AssistantPageView::InitLayout() {
SetLayoutManager(std::make_unique<views::FillLayout>()); SetLayoutManager(std::make_unique<views::FillLayout>());
assistant_main_view_ = new AssistantMainView(assistant_view_delegate_); // |assistant_view_delegate_| could be nullptr in test.
AddChildView(assistant_main_view_); if (assistant_view_delegate_) {
assistant_main_view_ = new AssistantMainView(assistant_view_delegate_);
AddChildView(assistant_main_view_);
}
} }
const char* AssistantPageView::GetClassName() const { const char* AssistantPageView::GetClassName() const {
...@@ -63,7 +66,9 @@ gfx::Size AssistantPageView::CalculatePreferredSize() const { ...@@ -63,7 +66,9 @@ gfx::Size AssistantPageView::CalculatePreferredSize() const {
} }
void AssistantPageView::RequestFocus() { void AssistantPageView::RequestFocus() {
assistant_main_view_->RequestFocus(); // |assistant_main_view_| could be nullptr in test.
if (assistant_main_view_)
assistant_main_view_->RequestFocus();
} }
void AssistantPageView::OnBoundsChanged(const gfx::Rect& previous_bounds) { void AssistantPageView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment