| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/omnibox/browser/omnibox_view.h" |
| |
| #include <stddef.h> |
| #include <stdio.h> |
| |
| #include <array> |
| #include <memory> |
| #include <optional> |
| #include <string> |
| |
| #include "base/compiler_specific.h" |
| #include "base/functional/bind.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/run_loop.h" |
| #include "base/strings/strcat.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/task/single_thread_task_runner.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "base/time/time.h" |
| #include "build/build_config.h" |
| #include "chrome/app/chrome_command_ids.h" |
| #include "chrome/browser/bookmarks/bookmark_model_factory.h" |
| #include "chrome/browser/history/history_service_factory.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/search_engines/template_url_service_factory.h" |
| #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_commands.h" |
| #include "chrome/browser/ui/browser_navigator_params.h" |
| #include "chrome/browser/ui/browser_window.h" |
| #include "chrome/browser/ui/browser_window/public/browser_window_features.h" |
| #include "chrome/browser/ui/location_bar/location_bar.h" |
| #include "chrome/browser/ui/omnibox/omnibox_tab_helper.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/browser/web_applications/web_app_provider.h" |
| #include "chrome/common/chrome_paths.h" |
| #include "chrome/common/url_constants.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "chrome/test/base/interactive_test_utils.h" |
| #include "chrome/test/base/search_test_utils.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "components/bookmarks/browser/bookmark_model.h" |
| #include "components/bookmarks/browser/bookmark_utils.h" |
| #include "components/bookmarks/test/bookmark_test_helpers.h" |
| #include "components/history/core/browser/history_service.h" |
| #include "components/omnibox/browser/autocomplete_input.h" |
| #include "components/omnibox/browser/autocomplete_match.h" |
| #include "components/omnibox/browser/history_quick_provider.h" |
| #include "components/omnibox/browser/omnibox_controller.h" |
| #include "components/omnibox/browser/omnibox_edit_model.h" |
| #include "components/omnibox/browser/omnibox_popup_selection.h" |
| #include "components/omnibox/browser/test_location_bar_model.h" |
| #include "components/omnibox/common/omnibox_features.h" |
| #include "components/policy/core/browser/browser_policy_connector.h" |
| #include "components/policy/core/common/mock_configuration_policy_provider.h" |
| #include "components/policy/policy_constants.h" |
| #include "components/search_engines/enterprise/search_aggregator_policy_handler.h" |
| #include "components/search_engines/enterprise/site_search_policy_handler.h" |
| #include "components/search_engines/template_url.h" |
| #include "components/search_engines/template_url_data.h" |
| #include "components/search_engines/template_url_service.h" |
| #include "components/signin/public/identity_manager/identity_test_environment.h" |
| #include "components/signin/public/identity_manager/identity_test_utils.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/test/browser_test.h" |
| #include "content/public/test/browser_test_utils.h" |
| #include "content/public/test/test_navigation_observer.h" |
| #include "content/public/test/url_loader_interceptor.h" |
| #include "net/dns/mock_host_resolver.h" |
| #include "ui/base/clipboard/clipboard.h" |
| #include "ui/base/clipboard/scoped_clipboard_writer.h" |
| #include "ui/events/event_constants.h" |
| #include "ui/events/keycodes/keyboard_codes.h" |
| #include "ui/gfx/geometry/point.h" |
| #include "url/url_features.h" |
| |
| using base::ASCIIToUTF16; |
| using base::UTF16ToUTF8; |
| using bookmarks::BookmarkModel; |
| |
| namespace { |
| |
| const char16_t kSearchKeyword[] = u"foo"; |
| const char16_t kSearchKeyword2[] = u"footest.com"; |
| const char16_t kSiteSearchPolicyKeyword[] = u"work"; |
| const char16_t kSiteSearchPolicyKeywordWithAtPrefix[] = u"@work"; |
| const ui::KeyboardCode kSearchKeywordKeys[] = {ui::VKEY_F, ui::VKEY_O, |
| ui::VKEY_O, ui::VKEY_UNKNOWN}; |
| const ui::KeyboardCode kSiteSearchPolicyKeywordKeys[] = { |
| ui::VKEY_W, ui::VKEY_O, ui::VKEY_R, ui::VKEY_K, ui::VKEY_UNKNOWN}; |
| const char kSearchURL[] = "http://www.foo.com/search?q={searchTerms}"; |
| const char kSiteSearchPolicyURL[] = |
| "http://www.work.com/search?q={searchTerms}"; |
| const char16_t kSearchShortName[] = u"foo"; |
| const char16_t kSiteSearchPolicyName[] = u"Work"; |
| const char16_t kSearchText[] = u"abc"; |
| const ui::KeyboardCode kSearchTextKeys[] = {ui::VKEY_A, ui::VKEY_B, ui::VKEY_C, |
| ui::VKEY_UNKNOWN}; |
| const char kSearchTextURL[] = "http://www.foo.com/search?q=abc"; |
| const char kSiteSearchPolicyTextURL[] = "http://www.work.com/search?q=abc"; |
| const char kSearchAggregatorPolicyIconUrl[] = |
| "https://www.aggregator.com/icon.png"; |
| const char16_t kSearchAggregatorPolicyKeyword[] = u"aggregator"; |
| const char16_t kSearchAggregatorPolicyKeywordWithAtPrefix[] = u"@aggregator"; |
| const ui::KeyboardCode kSearchAggregatorPolicyKeywordKeys[] = { |
| ui::VKEY_A, ui::VKEY_G, ui::VKEY_G, ui::VKEY_R, ui::VKEY_E, ui::VKEY_G, |
| ui::VKEY_A, ui::VKEY_T, ui::VKEY_O, ui::VKEY_R, ui::VKEY_UNKNOWN}; |
| const char kSearchAggregatorPolicySearchUrl[] = |
| "https://www.aggregator.com/search?q={searchTerms}"; |
| const char kSearchAggregatorPolicySuggestUrl[] = |
| "https://www.aggregator.com/suggest?q={searchTerms}"; |
| const char16_t kSearchAggregatorPolicyName[] = u"Aggregator"; |
| const char kSearchAggregatorPolicyTextURL[] = |
| "https://www.aggregator.com/search?q=abc"; |
| |
| const char kInlineAutocompleteText[] = "def"; |
| const ui::KeyboardCode kInlineAutocompleteTextKeys[] = { |
| ui::VKEY_D, ui::VKEY_E, ui::VKEY_F, ui::VKEY_UNKNOWN}; |
| |
| // Hostnames that shall be blocked by host resolver. |
| const char* kBlockedHostnames[] = { |
| "foo", "*.foo.com", "bar", "*.bar.com", "abc", "*.abc.com", |
| "def", "*.def.com", "*.site.com", "history", "z"}; |
| |
| struct TestHistoryEntry { |
| const char* url; |
| const char* title; |
| int visit_count; |
| int typed_count; |
| bool starred; |
| }; |
| const auto kHistoryEntries = std::to_array<TestHistoryEntry>({ |
| {"http://www.bar.com/1", "Page 1", 10, 10, false}, |
| {"http://www.bar.com/2", "Page 2", 9, 9, false}, |
| {"http://www.bar.com/3", "Page 3", 8, 8, false}, |
| {"http://www.bar.com/4", "Page 4", 7, 7, false}, |
| {"http://www.bar.com/5", "Page 5", 6, 6, false}, |
| {"http://www.bar.com/6", "Page 6", 5, 5, false}, |
| {"http://www.bar.com/7", "Page 7", 4, 4, false}, |
| {"http://www.bar.com/8", "Page 8", 3, 3, false}, |
| {"http://www.bar.com/9", "Page 9", 2, 2, false}, |
| {"http://www.site.com/path/1", "Site 1", 4, 4, false}, |
| {"http://www.site.com/path/2", "Site 2", 3, 3, false}, |
| {"http://www.site.com/path/3", "Site 3", 2, 2, false}, |
| |
| // To trigger inline autocomplete. |
| {"http://www.def.com", "Page def", 10000, 10000, true}, |
| |
| // Used in particular for the desired TLD test. This makes it test |
| // the interesting case when there's an intranet host with the same |
| // name as the .com. |
| {"http://bar/", "Bar", 1, 0, false}, |
| }); |
| |
| // Stores the given text to clipboard. |
| void SetClipboardText(const std::u16string& text) { |
| ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste); |
| writer.WriteText(text); |
| } |
| |
| #if BUILDFLAG(IS_MAC) |
| const int kCtrlOrCmdMask = ui::EF_COMMAND_DOWN; |
| #else |
| const int kCtrlOrCmdMask = ui::EF_CONTROL_DOWN; |
| #endif |
| |
| } // namespace |
| |
| class OmniboxViewTest : public InProcessBrowserTest { |
| public: |
| OmniboxViewTest() { |
| scoped_feature_list_.InitAndDisableFeature( |
| omnibox::kAiModeOmniboxEntryPoint); |
| } |
| |
| OmniboxViewTest(const OmniboxViewTest&) = delete; |
| OmniboxViewTest& operator=(const OmniboxViewTest&) = delete; |
| |
| protected: |
| void SetUpOnMainThread() override { |
| ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); |
| ASSERT_NO_FATAL_FAILURE(SetupComponents()); |
| chrome::FocusLocationBar(browser()); |
| ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); |
| |
| identity_test_env_adaptor_ = |
| std::make_unique<IdentityTestEnvironmentProfileAdaptor>( |
| browser()->profile()); |
| identity_test_env()->SetPrimaryAccount("test@mail.com", |
| signin::ConsentLevel::kSignin); |
| identity_test_env()->SetRefreshTokenForPrimaryAccount(); |
| identity_test_env()->SetAutomaticIssueOfAccessTokens(true); |
| } |
| |
| void SetUp() override { |
| policy_provider_.SetDefaultReturns( |
| /*is_initialization_complete_return=*/true, |
| /*is_first_policy_load_complete_return=*/true); |
| policy::BrowserPolicyConnector::SetPolicyProviderForTesting( |
| &policy_provider_); |
| InProcessBrowserTest::SetUp(); |
| } |
| |
| void SetUpInProcessBrowserTestFixture() override { |
| create_services_subscription_ = |
| BrowserContextDependencyManager::GetInstance() |
| ->RegisterCreateServicesCallbackForTesting(base::BindRepeating( |
| &OmniboxViewTest::OnWillCreateBrowserContextServices, |
| base::Unretained(this))); |
| } |
| |
| static void GetOmniboxViewForBrowser(const Browser* browser, |
| OmniboxView** omnibox_view) { |
| BrowserWindow* window = browser->window(); |
| ASSERT_TRUE(window); |
| LocationBar* location_bar = window->GetLocationBar(); |
| ASSERT_TRUE(location_bar); |
| *omnibox_view = location_bar->GetOmniboxView(); |
| ASSERT_TRUE(*omnibox_view); |
| } |
| |
| void GetOmniboxView(OmniboxView** omnibox_view) { |
| GetOmniboxViewForBrowser(browser(), omnibox_view); |
| } |
| |
| static void SendKeyForBrowser(const Browser* browser, |
| ui::KeyboardCode key, |
| int modifiers) { |
| ASSERT_TRUE(ui_test_utils::SendKeyPressSync( |
| browser, key, (modifiers & ui::EF_CONTROL_DOWN) != 0, |
| (modifiers & ui::EF_SHIFT_DOWN) != 0, |
| (modifiers & ui::EF_ALT_DOWN) != 0, |
| (modifiers & ui::EF_COMMAND_DOWN) != 0)); |
| } |
| |
| void SendKey(ui::KeyboardCode key, int modifiers) { |
| SendKeyForBrowser(browser(), key, modifiers); |
| } |
| |
| void SendKeySequence(const ui::KeyboardCode* keys) { |
| for (; *keys != ui::VKEY_UNKNOWN; UNSAFE_TODO(++keys)) { |
| ASSERT_NO_FATAL_FAILURE(SendKey(*keys, 0)); |
| } |
| } |
| |
| void ExpectBrowserClosed(Browser* browser, |
| ui::KeyboardCode key, |
| int modifiers) { |
| // Press the accelerator after starting to wait for a browser to close as |
| // the close may be synchronous. |
| base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( |
| FROM_HERE, |
| base::BindOnce( |
| [](const Browser* browser, ui::KeyboardCode key, int modifiers) { |
| EXPECT_TRUE(ui_test_utils::SendKeyPressSync( |
| browser, key, (modifiers & ui::EF_CONTROL_DOWN) != 0, |
| (modifiers & ui::EF_SHIFT_DOWN) != 0, |
| (modifiers & ui::EF_ALT_DOWN) != 0, |
| (modifiers & ui::EF_COMMAND_DOWN) != 0)); |
| }, |
| browser, key, modifiers)); |
| ui_test_utils::WaitForBrowserToClose(browser); |
| } |
| |
| void NavigateExpectUrl(const GURL& url, int modifiers = 0) { |
| content::TestNavigationObserver observer(url); |
| observer.WatchExistingWebContents(); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, modifiers)); |
| observer.WaitForNavigationFinished(); |
| } |
| |
| void WaitForTabOpenOrClose(int expected_tab_count) { |
| int tab_count = browser()->tab_strip_model()->count(); |
| if (tab_count == expected_tab_count) { |
| return; |
| } |
| |
| while (!HasFailure() && |
| browser()->tab_strip_model()->count() != expected_tab_count) { |
| content::RunMessageLoop(); |
| } |
| |
| ASSERT_EQ(expected_tab_count, browser()->tab_strip_model()->count()); |
| } |
| |
| void WaitForAutocompleteControllerDone() { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| AutocompleteController* controller = |
| omnibox_view->controller()->autocomplete_controller(); |
| ASSERT_TRUE(controller); |
| |
| if (controller->done()) { |
| return; |
| } |
| |
| ui_test_utils::WaitForAutocompleteDone(browser()); |
| ASSERT_TRUE(controller->done()); |
| } |
| |
| void SetupSearchEngine() { |
| Profile* profile = browser()->profile(); |
| TemplateURLService* model = |
| TemplateURLServiceFactory::GetForProfile(profile); |
| ASSERT_TRUE(model); |
| |
| search_test_utils::WaitForTemplateURLServiceToLoad(model); |
| |
| ASSERT_TRUE(model->loaded()); |
| |
| TemplateURLData data; |
| data.SetShortName(kSearchShortName); |
| data.SetKeyword(kSearchKeyword); |
| data.SetURL(kSearchURL); |
| TemplateURL* template_url = model->Add(std::make_unique<TemplateURL>(data)); |
| model->SetUserSelectedDefaultSearchProvider(template_url); |
| |
| data.SetKeyword(kSearchKeyword2); |
| model->Add(std::make_unique<TemplateURL>(data)); |
| |
| // Remove built-in template urls, like google.com, bing.com etc., as they |
| // may appear as autocomplete suggests and interfere with our tests. |
| TemplateURLService::TemplateURLVector urls = model->GetTemplateURLs(); |
| for (const auto& url : urls) { |
| if (url->prepopulate_id() != 0) { |
| model->Remove(url); |
| } |
| } |
| } |
| |
| void AddHistoryEntry(const TestHistoryEntry& entry, const base::Time& time) { |
| Profile* profile = browser()->profile(); |
| history::HistoryService* history_service = |
| HistoryServiceFactory::GetForProfile( |
| profile, ServiceAccessType::EXPLICIT_ACCESS); |
| ASSERT_TRUE(history_service); |
| |
| if (!history_service->BackendLoaded()) { |
| // Running the task scheduler until idle loads the history backend. |
| content::RunAllTasksUntilIdle(); |
| ASSERT_TRUE(history_service->BackendLoaded()); |
| } |
| |
| BookmarkModel* bookmark_model = |
| BookmarkModelFactory::GetForBrowserContext(profile); |
| ASSERT_TRUE(bookmark_model); |
| bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model); |
| |
| GURL url(entry.url); |
| // Add everything in order of time. We don't want to have a time that |
| // is "right now" or it will nondeterministically appear in the results. |
| history_service->AddPageWithDetails(url, base::UTF8ToUTF16(entry.title), |
| entry.visit_count, entry.typed_count, |
| time, false, history::SOURCE_BROWSED); |
| if (entry.starred) { |
| bookmarks::AddIfNotBookmarked(bookmark_model, url, std::u16string()); |
| } |
| |
| // Running the task scheduler until idle finishes AddPageWithDetails. |
| content::RunAllTasksUntilIdle(); |
| } |
| |
| void SetupHistory() { |
| // Add enough history pages containing |kSearchText| to trigger |
| // open history page url in autocomplete result. |
| for (size_t i = 0; i < std::size(kHistoryEntries); i++) { |
| // Add everything in order of time. We don't want to have a time that |
| // is "right now" or it will nondeterministically appear in the results. |
| base::Time t = base::Time::Now() - base::Hours(i + 1); |
| ASSERT_NO_FATAL_FAILURE(AddHistoryEntry(kHistoryEntries[i], t)); |
| } |
| } |
| |
| void SetupHostResolver() { |
| for (auto* kBlockedHostname : kBlockedHostnames) { |
| host_resolver()->AddSimulatedFailure(kBlockedHostname); |
| } |
| } |
| |
| void SetupComponents() { |
| ASSERT_NO_FATAL_FAILURE(SetupHostResolver()); |
| ASSERT_NO_FATAL_FAILURE(SetupSearchEngine()); |
| ASSERT_NO_FATAL_FAILURE(SetupHistory()); |
| } |
| |
| void SetTestToolbarPermanentText(const std::u16string& text) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| OmniboxEditModel* edit_model = omnibox_view->model(); |
| ASSERT_NE(nullptr, edit_model); |
| |
| if (!test_location_bar_model_) { |
| test_location_bar_model_ = new TestLocationBarModel; |
| std::unique_ptr<LocationBarModel> location_bar_model( |
| test_location_bar_model_); |
| browser()->GetFeatures().swap_location_bar_models(&location_bar_model); |
| } |
| |
| test_location_bar_model_->set_formatted_full_url(text); |
| |
| // Normally the URL for display has portions elided. We aren't doing that in |
| // this case, because that is irrevelant for these tests. |
| test_location_bar_model_->set_url_for_display(text); |
| |
| omnibox_view->Update(); |
| } |
| |
| void OnWillCreateBrowserContextServices(content::BrowserContext* context) { |
| IdentityTestEnvironmentProfileAdaptor:: |
| SetIdentityTestEnvironmentFactoriesOnBrowserContext(context); |
| } |
| |
| policy::MockConfigurationPolicyProvider* policy_provider() { |
| return &policy_provider_; |
| } |
| |
| signin::IdentityTestEnvironment* identity_test_env() { |
| return identity_test_env_adaptor_->identity_test_env(); |
| } |
| |
| private: |
| base::test::ScopedFeatureList scoped_feature_list_; |
| testing::NiceMock<policy::MockConfigurationPolicyProvider> policy_provider_; |
| base::CallbackListSubscription create_services_subscription_; |
| std::unique_ptr<IdentityTestEnvironmentProfileAdaptor> |
| identity_test_env_adaptor_; |
| |
| // Non-owning pointer. |
| raw_ptr<TestLocationBarModel> test_location_bar_model_ = nullptr; |
| }; |
| |
| // Test if ctrl-* accelerators are workable in omnibox. |
| // Flaky. See https://crbug.com/751031. |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, DISABLED_BrowserAccelerators) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| int tab_count = browser()->tab_strip_model()->count(); |
| |
| // Create a new Tab. |
| chrome::NewTab(browser()); |
| ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count + 1)); |
| |
| // Select the first Tab. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_1, kCtrlOrCmdMask)); |
| ASSERT_EQ(0, browser()->tab_strip_model()->active_index()); |
| |
| chrome::FocusLocationBar(browser()); |
| |
| // Select the second Tab. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_2, kCtrlOrCmdMask)); |
| ASSERT_EQ(1, browser()->tab_strip_model()->active_index()); |
| |
| chrome::FocusLocationBar(browser()); |
| |
| // Try ctrl-w to close a Tab. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_W, kCtrlOrCmdMask)); |
| ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count)); |
| |
| // Try ctrl-l to focus location bar. |
| omnibox_view->SetUserText(u"Hello world"); |
| EXPECT_FALSE(omnibox_view->IsSelectAll()); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_L, kCtrlOrCmdMask)); |
| EXPECT_TRUE(omnibox_view->IsSelectAll()); |
| |
| // Try editing the location bar text. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RIGHT, 0)); |
| EXPECT_FALSE(omnibox_view->IsSelectAll()); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_S, 0)); |
| EXPECT_EQ(u"Hello worlds", omnibox_view->GetText()); |
| |
| // Try ctrl-x to cut text. |
| #if BUILDFLAG(IS_MAC) |
| // Mac uses alt-left/right to select a word. |
| ASSERT_NO_FATAL_FAILURE( |
| SendKey(ui::VKEY_LEFT, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)); |
| #else |
| ASSERT_NO_FATAL_FAILURE( |
| SendKey(ui::VKEY_LEFT, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)); |
| #endif |
| EXPECT_FALSE(omnibox_view->IsSelectAll()); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_X, kCtrlOrCmdMask)); |
| EXPECT_EQ(u"Hello ", omnibox_view->GetText()); |
| |
| #if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_MAC) |
| // Try alt-f4 to close the browser. |
| ExpectBrowserClosed(browser(), ui::VKEY_F4, ui::EF_ALT_DOWN); |
| #endif |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, PopupAccelerators) { |
| // Create a popup. |
| Browser* popup = CreateBrowserForPopup(browser()->profile()); |
| ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(popup)); |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(popup, &omnibox_view)); |
| chrome::FocusLocationBar(popup); |
| EXPECT_TRUE(omnibox_view->IsSelectAll()); |
| |
| // Try ctrl/cmd-w to close the popup. |
| ExpectBrowserClosed(popup, ui::VKEY_W, kCtrlOrCmdMask); |
| |
| // Create another popup. |
| popup = CreateBrowserForPopup(browser()->profile()); |
| ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(popup)); |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(popup, &omnibox_view)); |
| |
| // Set the edit text to "Hello world". |
| omnibox_view->SetUserText(u"Hello world"); |
| chrome::FocusLocationBar(popup); |
| EXPECT_TRUE(omnibox_view->IsSelectAll()); |
| |
| // Try editing the location bar text -- should be disallowed. |
| ASSERT_NO_FATAL_FAILURE(SendKeyForBrowser(popup, ui::VKEY_S, 0)); |
| EXPECT_EQ(u"Hello world", omnibox_view->GetText()); |
| EXPECT_TRUE(omnibox_view->IsSelectAll()); |
| |
| ASSERT_NO_FATAL_FAILURE(SendKeyForBrowser(popup, ui::VKEY_X, kCtrlOrCmdMask)); |
| EXPECT_EQ(u"Hello world", omnibox_view->GetText()); |
| EXPECT_TRUE(omnibox_view->IsSelectAll()); |
| |
| #if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_MAC) |
| // Try alt-f4 to close the popup. |
| ExpectBrowserClosed(popup, ui::VKEY_F4, ui::EF_ALT_DOWN); |
| #endif |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, BackspaceInKeywordMode) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| // Trigger keyword hint mode. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys)); |
| ASSERT_TRUE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_EQ(kSearchKeyword, omnibox_view->model()->keyword()); |
| |
| // Trigger keyword mode. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); |
| ASSERT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_EQ(kSearchKeyword, omnibox_view->model()->keyword()); |
| |
| // Backspace without search text should bring back keyword hint mode. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); |
| ASSERT_TRUE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_EQ(kSearchKeyword, omnibox_view->model()->keyword()); |
| |
| // Trigger keyword mode again. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); |
| ASSERT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_EQ(kSearchKeyword, omnibox_view->model()->keyword()); |
| |
| // Input something as search text. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); |
| |
| // Should stay in keyword mode while deleting search text by pressing |
| // backspace. |
| for (size_t i = 0; i < std::size(kSearchText) - 1; ++i) { |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); |
| ASSERT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_EQ(kSearchKeyword, omnibox_view->model()->keyword()); |
| } |
| |
| // Input something as search text. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); |
| |
| // Move cursor to the beginning of the search text. |
| #if BUILDFLAG(IS_MAC) |
| // Home doesn't work on Mac trybot. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, ui::EF_CONTROL_DOWN)); |
| #else |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_HOME, 0)); |
| #endif |
| // Backspace at the beginning of the search text shall turn off |
| // the keyword mode. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); |
| // A keyword 'hint'/button will persist as long as the entry begins with a |
| // keyword. |
| ASSERT_TRUE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_EQ(kSearchKeyword, omnibox_view->model()->keyword()); |
| } |
| |
| // TODO(crbug.com/40661918): This test flakily times out. |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, DISABLED_DesiredTLD) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| // Test ctrl-Enter. |
| const ui::KeyboardCode kKeys[] = {ui::VKEY_B, ui::VKEY_A, ui::VKEY_R, |
| ui::VKEY_UNKNOWN}; |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| // ctrl-Enter triggers desired_tld feature, thus www.bar.com shall be |
| // opened. |
| ASSERT_NO_FATAL_FAILURE( |
| NavigateExpectUrl(GURL("http://www.bar.com/"), ui::EF_CONTROL_DOWN)); |
| } |
| |
| // TODO(crbug.com/40661918): Test times out on Win and Linux. |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, DISABLED_DesiredTLDWithTemporaryText) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| Profile* profile = browser()->profile(); |
| TemplateURLService* template_url_service = |
| TemplateURLServiceFactory::GetForProfile(profile); |
| |
| // Add a non-substituting keyword. This ensures the popup will have a |
| // non-verbatim entry with "ab" as a prefix. This way, by arrowing down, we |
| // can set "abc" as temporary text in the omnibox. |
| TemplateURLData data; |
| data.SetShortName(u"abc"); |
| data.SetKeyword(kSearchText); |
| data.SetURL("http://abc.com/"); |
| template_url_service->Add(std::make_unique<TemplateURL>(data)); |
| |
| // Send "ab", so that an "abc" entry appears in the popup. |
| const ui::KeyboardCode kSearchTextPrefixKeys[] = {ui::VKEY_A, ui::VKEY_B, |
| ui::VKEY_UNKNOWN}; |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextPrefixKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| // Arrow down to the "abc" entry in the popup. |
| size_t size = |
| omnibox_view->controller()->autocomplete_controller()->result().size(); |
| while (omnibox_view->model()->GetPopupSelection().line < size - 1) { |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DOWN, 0)); |
| if (omnibox_view->GetText() == u"abc") { |
| break; |
| } |
| } |
| ASSERT_EQ(u"abc", omnibox_view->GetText()); |
| |
| // Hitting ctrl-enter should navigate based on the current text rather than |
| // the original input, i.e. to www.abc.com instead of www.ab.com. |
| ASSERT_NO_FATAL_FAILURE( |
| NavigateExpectUrl(GURL("http://www.abc.com/"), ui::EF_CONTROL_DOWN)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, ClearUserTextAfterBackgroundCommit) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| // Navigate in first tab and enter text into the omnibox. |
| GURL url1("data:text/html,page1"); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url1)); |
| omnibox_view->SetUserText(u"foo"); |
| content::WebContents* contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| |
| // Create another tab in the foreground. |
| ASSERT_TRUE(AddTabAtIndex(1, url1, ui::PAGE_TRANSITION_TYPED)); |
| EXPECT_EQ(2, browser()->tab_strip_model()->count()); |
| EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); |
| |
| // Navigate in the first tab, currently in the background. |
| GURL url2("data:text/html,page2"); |
| NavigateParams params(browser(), url2, ui::PAGE_TRANSITION_LINK); |
| params.source_contents = contents; |
| params.disposition = WindowOpenDisposition::CURRENT_TAB; |
| ui_test_utils::NavigateToURL(¶ms); |
| |
| // Switch back to the first tab. The user text should be cleared, and the |
| // omnibox should have the new URL. |
| browser()->tab_strip_model()->ActivateTabAt( |
| 0, TabStripUserGestureDetails( |
| TabStripUserGestureDetails::GestureType::kOther)); |
| EXPECT_EQ(ASCIIToUTF16(url2.spec()), omnibox_view->GetText()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, AltEnter) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| omnibox_view->SetUserText(chrome::kChromeUIHistoryURL16); |
| int tab_count = browser()->tab_strip_model()->count(); |
| // alt-Enter opens a new tab. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, ui::EF_ALT_DOWN)); |
| ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count + 1)); |
| } |
| |
| // TODO(crbug.com/40661918): This test flakily times out. |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, DISABLED_EnterToSearch) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| // Test Enter to search. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| ASSERT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, |
| omnibox_view->controller() |
| ->autocomplete_controller() |
| ->result() |
| .default_match() |
| ->type); |
| ASSERT_NO_FATAL_FAILURE(NavigateExpectUrl(GURL(kSearchTextURL))); |
| |
| // Test that entering a single character then Enter performs a search. |
| chrome::FocusLocationBar(browser()); |
| EXPECT_TRUE(omnibox_view->IsSelectAll()); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, 0)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| ASSERT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, |
| omnibox_view->controller() |
| ->autocomplete_controller() |
| ->result() |
| .default_match() |
| ->type); |
| ASSERT_NO_FATAL_FAILURE( |
| NavigateExpectUrl(GURL("http://www.foo.com/search?q=z"))); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, EscapeToDefaultMatch) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| // Input something to trigger inline autocomplete. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| std::u16string old_text = omnibox_view->GetText(); |
| |
| // Make sure inline autocomplete is triggered. |
| EXPECT_GT(old_text.length(), std::size(kInlineAutocompleteText) - 1); |
| |
| size_t old_selected_line = omnibox_view->model()->GetPopupSelection().line; |
| EXPECT_EQ(0U, old_selected_line); |
| |
| // Move to another line with different text. |
| size_t size = |
| omnibox_view->controller()->autocomplete_controller()->result().size(); |
| while (omnibox_view->model()->GetPopupSelection().line < size - 1) { |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DOWN, 0)); |
| ASSERT_NE(old_selected_line, |
| omnibox_view->model()->GetPopupSelection().line); |
| if (old_text != omnibox_view->GetText()) { |
| break; |
| } |
| } |
| |
| EXPECT_NE(old_text, omnibox_view->GetText()); |
| |
| // Escape shall revert back to the default match item. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_ESCAPE, 0)); |
| EXPECT_EQ(old_text, omnibox_view->GetText()); |
| EXPECT_EQ(old_selected_line, omnibox_view->model()->GetPopupSelection().line); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, |
| RevertDefaultRevertInlineTextWhenSelectingDefaultMatch) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| // Input something to trigger inline autocomplete. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| std::u16string old_text = omnibox_view->GetText(); |
| |
| // Make sure inline autocomplete is triggered. |
| EXPECT_GT(old_text.length(), std::size(kInlineAutocompleteText) - 1); |
| |
| size_t old_selected_line = omnibox_view->model()->GetPopupSelection().line; |
| EXPECT_EQ(0U, old_selected_line); |
| |
| // Move to another line with different text. |
| size_t size = |
| omnibox_view->controller()->autocomplete_controller()->result().size(); |
| while (omnibox_view->model()->GetPopupSelection().line < size - 1) { |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DOWN, 0)); |
| ASSERT_NE(old_selected_line, |
| omnibox_view->model()->GetPopupSelection().line); |
| if (old_text != omnibox_view->GetText()) { |
| break; |
| } |
| } |
| |
| EXPECT_NE(old_text, omnibox_view->GetText()); |
| |
| // Move back to the first line |
| while (omnibox_view->model()->GetPopupSelection().line > 0) { |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_UP, 0)); |
| } |
| |
| EXPECT_EQ(old_text, omnibox_view->GetText()); |
| EXPECT_EQ(old_selected_line, omnibox_view->model()->GetPopupSelection().line); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, BasicTextOperations) { |
| ASSERT_TRUE( |
| ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL))); |
| chrome::FocusLocationBar(browser()); |
| |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| std::u16string old_text = omnibox_view->GetText(); |
| EXPECT_EQ(url::kAboutBlankURL16, old_text); |
| EXPECT_TRUE(omnibox_view->IsSelectAll()); |
| |
| size_t start, end; |
| omnibox_view->GetSelectionBounds(&start, &end); |
| #if defined(TOOLKIT_VIEWS) |
| // Views textfields select-all in reverse to show the leading text. |
| std::swap(start, end); |
| #endif |
| EXPECT_EQ(0U, start); |
| EXPECT_EQ(old_text.size(), end); |
| |
| // Move the cursor to the end. |
| #if BUILDFLAG(IS_MAC) |
| // End doesn't work on Mac trybot. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_E, ui::EF_CONTROL_DOWN)); |
| #else |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_END, 0)); |
| #endif |
| EXPECT_FALSE(omnibox_view->IsSelectAll()); |
| |
| // Make sure the cursor is placed correctly. |
| omnibox_view->GetSelectionBounds(&start, &end); |
| EXPECT_EQ(old_text.size(), start); |
| EXPECT_EQ(old_text.size(), end); |
| |
| // Insert one character at the end. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, 0)); |
| EXPECT_EQ(old_text + u'a', omnibox_view->GetText()); |
| |
| // Delete one character from the end. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); |
| EXPECT_EQ(old_text, omnibox_view->GetText()); |
| |
| omnibox_view->SelectAll(true); |
| EXPECT_TRUE(omnibox_view->IsSelectAll()); |
| omnibox_view->GetSelectionBounds(&start, &end); |
| #if defined(TOOLKIT_VIEWS) |
| // Views textfields select-all in reverse to show the leading text. |
| std::swap(start, end); |
| #endif |
| EXPECT_EQ(0U, start); |
| EXPECT_EQ(old_text.size(), end); |
| |
| // Delete the content |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DELETE, 0)); |
| EXPECT_FALSE(omnibox_view->IsSelectAll()); |
| omnibox_view->GetSelectionBounds(&start, &end); |
| EXPECT_EQ(0U, start); |
| EXPECT_EQ(0U, end); |
| EXPECT_TRUE(omnibox_view->GetText().empty()); |
| |
| // Add a small amount of text to move the cursor past offset 0. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, 0)); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_B, 0)); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_C, 0)); |
| |
| // Check if RevertAll() resets the text and preserves the cursor position. |
| omnibox_view->RevertAll(); |
| EXPECT_FALSE(omnibox_view->IsSelectAll()); |
| EXPECT_EQ(old_text, omnibox_view->GetText()); |
| omnibox_view->GetSelectionBounds(&start, &end); |
| EXPECT_EQ(3U, start); |
| EXPECT_EQ(3U, end); |
| |
| // Check that reverting clamps the cursor to the bounds of the new text. |
| // Move the cursor to the end. |
| #if BUILDFLAG(IS_MAC) |
| // End doesn't work on Mac trybot. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_E, ui::EF_CONTROL_DOWN)); |
| #else |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_END, 0)); |
| #endif |
| // Add a small amount of text to push the cursor past where the text end |
| // will be once we revert. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, 0)); |
| omnibox_view->RevertAll(); |
| // Cursor should be no further than original text. |
| omnibox_view->GetSelectionBounds(&start, &end); |
| EXPECT_EQ(11U, start); |
| EXPECT_EQ(11U, end); |
| } |
| |
| // Make sure the cursor position doesn't get set past the last character of |
| // user input text when the URL is longer than the keyword. |
| // (http://crbug.com/656209) |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, FocusSearchLongUrl) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| ASSERT_GT(strlen(url::kAboutBlankURL), |
| std::char_traits<char16_t>::length(kSearchKeyword)); |
| ASSERT_TRUE( |
| ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL))); |
| |
| // Make sure nothing DCHECKs. |
| chrome::FocusSearch(browser()); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, AcceptKeywordByTypingQuestionMark) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| std::u16string search_keyword(kSearchKeyword); |
| |
| // If the user gets into keyword mode by typing '?', they should be put into |
| // keyword mode for their default search provider. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_OEM_2, ui::EF_SHIFT_DOWN)); |
| ASSERT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_TRUE(omnibox_view->model()->is_keyword_selected()); |
| ASSERT_EQ(search_keyword, omnibox_view->model()->keyword()); |
| ASSERT_EQ(std::u16string(), omnibox_view->GetText()); |
| |
| // If the user press backspace, they should be left with '?' in the omnibox. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); |
| EXPECT_EQ(u"?", omnibox_view->GetText()); |
| EXPECT_EQ(std::u16string(), omnibox_view->model()->keyword()); |
| EXPECT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| EXPECT_FALSE(omnibox_view->model()->is_keyword_selected()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, SearchDisabledDontCrashOnQuestionMark) { |
| policy::PolicyMap policies; |
| policies.Set("DefaultSearchProviderEnabled", policy::POLICY_LEVEL_MANDATORY, |
| policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_PLATFORM, |
| base::Value(false), nullptr); |
| policy_provider()->UpdateChromePolicy(policies); |
| |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| // '?' isn't in the same place on all keyboard layouts, so send the character |
| // instead of keystrokes. |
| ASSERT_NO_FATAL_FAILURE({ |
| omnibox_view->OnBeforePossibleChange(); |
| omnibox_view->SetUserText(u"?"); |
| omnibox_view->OnAfterPossibleChange(true); |
| }); |
| ASSERT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_FALSE(omnibox_view->model()->is_keyword_selected()); |
| ASSERT_EQ(u"?", omnibox_view->GetText()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, NonDefaultSubstitutingKeywordTest) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| Profile* profile = browser()->profile(); |
| TemplateURLService* template_url_service = |
| TemplateURLServiceFactory::GetForProfile(profile); |
| |
| // Add a non-default substituting keyword. |
| TemplateURLData data; |
| data.SetShortName(u"Search abc"); |
| data.SetKeyword(kSearchText); |
| data.SetURL("http://abc.com/{searchTerms}"); |
| data.is_active = TemplateURLData::ActiveStatus::kTrue; |
| template_url_service->Add(std::make_unique<TemplateURL>(data)); |
| |
| omnibox_view->SetUserText(std::u16string()); |
| |
| // Non-default substituting keyword shouldn't be matched by default. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| // Check if the default match result is Search Primary Provider. |
| auto* default_match = omnibox_view->controller() |
| ->autocomplete_controller() |
| ->result() |
| .default_match(); |
| EXPECT_EQ(default_match->type, AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED); |
| EXPECT_EQ(default_match->destination_url.spec(), kSearchTextURL); |
| |
| omnibox_view->SetUserText(std::u16string()); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_FALSE(omnibox_view->model()->PopupIsOpen()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, NonSubstitutingKeywordTest) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| Profile* profile = browser()->profile(); |
| TemplateURLService* template_url_service = |
| TemplateURLServiceFactory::GetForProfile(profile); |
| |
| // Add a non-substituting keyword. |
| TemplateURLData data; |
| data.SetShortName(u"abc"); |
| data.SetKeyword(kSearchText); |
| data.SetURL("http://abc.com/"); |
| data.is_active = TemplateURLData::ActiveStatus::kTrue; |
| template_url_service->Add(std::make_unique<TemplateURL>(data)); |
| |
| omnibox_view->SetUserText(std::u16string()); |
| |
| // We always allow exact matches for non-substituting keywords. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| auto* default_match = omnibox_view->controller() |
| ->autocomplete_controller() |
| ->result() |
| .default_match(); |
| EXPECT_EQ(default_match->type, AutocompleteMatchType::HISTORY_KEYWORD); |
| EXPECT_EQ(default_match->destination_url.spec(), "http://abc.com/"); |
| |
| omnibox_view->SetUserText(std::u16string()); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_FALSE(omnibox_view->model()->PopupIsOpen()); |
| } |
| |
| // Flaky. See https://crbug.com/751031. |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, DISABLED_DeleteItem) { |
| // Disable the search provider, to make sure the popup contains only history |
| // items. |
| TemplateURLService* model = |
| TemplateURLServiceFactory::GetForProfile(browser()->profile()); |
| model->SetUserSelectedDefaultSearchProvider(nullptr); |
| |
| ASSERT_TRUE( |
| ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL))); |
| chrome::FocusLocationBar(browser()); |
| |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| std::u16string old_text = omnibox_view->GetText(); |
| |
| // Input something that can match history items. |
| omnibox_view->SetUserText(u"site.com/p"); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| // Delete the inline autocomplete part. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DELETE, 0)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| ASSERT_GE( |
| omnibox_view->controller()->autocomplete_controller()->result().size(), |
| 3U); |
| |
| std::u16string user_text = omnibox_view->GetText(); |
| ASSERT_EQ(u"site.com/p", user_text); |
| omnibox_view->SelectAll(true); |
| ASSERT_TRUE(omnibox_view->IsSelectAll()); |
| |
| // Move down. |
| size_t default_line = omnibox_view->model()->GetPopupSelection().line; |
| omnibox_view->model()->OnUpOrDownPressed(true, false); |
| ASSERT_EQ(default_line + 1, omnibox_view->model()->GetPopupSelection().line); |
| std::u16string selected_text = omnibox_view->controller() |
| ->autocomplete_controller() |
| ->result() |
| .match_at(default_line + 1) |
| .fill_into_edit; |
| // Temporary text is shown. |
| ASSERT_EQ(selected_text, omnibox_view->GetText()); |
| ASSERT_FALSE(omnibox_view->IsSelectAll()); |
| |
| // Delete the item. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DELETE, ui::EF_SHIFT_DOWN)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| // The selected line shouldn't be changed, because we have more than two |
| // items. |
| ASSERT_EQ(default_line + 1, omnibox_view->model()->GetPopupSelection().line); |
| // Make sure the item is really deleted. |
| ASSERT_NE(selected_text, omnibox_view->controller() |
| ->autocomplete_controller() |
| ->result() |
| .match_at(default_line + 1) |
| .fill_into_edit); |
| selected_text = omnibox_view->controller() |
| ->autocomplete_controller() |
| ->result() |
| .match_at(default_line + 1) |
| .fill_into_edit; |
| // New temporary text is shown. |
| ASSERT_EQ(selected_text, omnibox_view->GetText()); |
| |
| // Revert to the default match. |
| ASSERT_TRUE(omnibox_view->model()->OnEscapeKeyPressed()); |
| ASSERT_EQ(default_line, omnibox_view->model()->GetPopupSelection().line); |
| ASSERT_EQ(user_text, omnibox_view->GetText()); |
| ASSERT_TRUE(omnibox_view->IsSelectAll()); |
| |
| // Move down and up to select the default match as temporary text. |
| omnibox_view->model()->OnUpOrDownPressed(true, false); |
| ASSERT_EQ(default_line + 1, omnibox_view->model()->GetPopupSelection().line); |
| omnibox_view->model()->OnUpOrDownPressed(false, false); |
| ASSERT_EQ(default_line, omnibox_view->model()->GetPopupSelection().line); |
| |
| selected_text = omnibox_view->controller() |
| ->autocomplete_controller() |
| ->result() |
| .match_at(default_line) |
| .fill_into_edit; |
| // New temporary text is shown. |
| ASSERT_EQ(selected_text, omnibox_view->GetText()); |
| ASSERT_FALSE(omnibox_view->IsSelectAll()); |
| |
| // As the current selected item is the new default item, pressing Escape key |
| // should revert all directly. |
| ASSERT_TRUE(omnibox_view->model()->OnEscapeKeyPressed()); |
| ASSERT_EQ(old_text, omnibox_view->GetText()); |
| ASSERT_TRUE(omnibox_view->IsSelectAll()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, TabAcceptKeyword) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| std::u16string text = kSearchKeyword; |
| |
| // Trigger keyword hint mode. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys)); |
| ASSERT_TRUE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_EQ(text, omnibox_view->model()->keyword()); |
| ASSERT_EQ(text, omnibox_view->GetText()); |
| |
| // Trigger keyword mode by tab. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); |
| ASSERT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_EQ(text, omnibox_view->model()->keyword()); |
| ASSERT_TRUE(omnibox_view->GetText().empty()); |
| |
| // Revert to keyword hint mode. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); |
| ASSERT_TRUE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_EQ(text, omnibox_view->model()->keyword()); |
| ASSERT_EQ(text, omnibox_view->GetText()); |
| |
| // The location bar should still have focus. |
| ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); |
| |
| // Trigger keyword mode by tab. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); |
| ASSERT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_EQ(text, omnibox_view->model()->keyword()); |
| ASSERT_TRUE(omnibox_view->GetText().empty()); |
| |
| // Revert to keyword hint mode with SHIFT+TAB. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN)); |
| ASSERT_TRUE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_EQ(text, omnibox_view->model()->keyword()); |
| ASSERT_EQ(text, omnibox_view->GetText()); |
| ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, PersistKeywordModeOnTabSwitch) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| // Trigger keyword hint mode. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys)); |
| ASSERT_TRUE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_EQ(kSearchKeyword, omnibox_view->model()->keyword()); |
| |
| // Trigger keyword mode. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); |
| ASSERT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| ASSERT_EQ(kSearchKeyword, omnibox_view->model()->keyword()); |
| |
| // Create a new tab. |
| chrome::NewTab(browser()); |
| |
| // Switch back to the first tab. |
| browser()->tab_strip_model()->ActivateTabAt( |
| 0, TabStripUserGestureDetails( |
| TabStripUserGestureDetails::GestureType::kOther)); |
| |
| // Make sure we're still in keyword mode. |
| ASSERT_TRUE(omnibox_view->model()->is_keyword_selected()); |
| ASSERT_EQ(kSearchKeyword, omnibox_view->model()->keyword()); |
| ASSERT_EQ(omnibox_view->GetText(), std::u16string()); |
| |
| // Input something as search text. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); |
| |
| // Switch to the second tab and back to the first. |
| browser()->tab_strip_model()->ActivateTabAt( |
| 1, TabStripUserGestureDetails( |
| TabStripUserGestureDetails::GestureType::kOther)); |
| browser()->tab_strip_model()->ActivateTabAt( |
| 0, TabStripUserGestureDetails( |
| TabStripUserGestureDetails::GestureType::kOther)); |
| |
| // Make sure we're still in keyword mode. |
| ASSERT_TRUE(omnibox_view->model()->is_keyword_selected()); |
| ASSERT_EQ(kSearchKeyword, omnibox_view->model()->keyword()); |
| ASSERT_EQ(omnibox_view->GetText(), kSearchText); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, |
| CtrlKeyPressedWithInlineAutocompleteTest) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| // Input something to trigger inline autocomplete. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| std::u16string old_text = omnibox_view->GetText(); |
| |
| // Make sure inline autocomplete is triggered. |
| EXPECT_GT(old_text.length(), std::size(kInlineAutocompleteText) - 1); |
| |
| // Press ctrl key. |
| omnibox_view->model()->OnControlKeyChanged(true); |
| |
| // Inline autocomplete should still be there. |
| EXPECT_EQ(old_text, omnibox_view->GetText()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, UndoRedo) { |
| ASSERT_TRUE( |
| ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL))); |
| chrome::FocusLocationBar(browser()); |
| |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| std::u16string old_text = omnibox_view->GetText(); |
| EXPECT_EQ(url::kAboutBlankURL16, old_text); |
| EXPECT_TRUE(omnibox_view->IsSelectAll()); |
| |
| // Delete the text, then undo. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); |
| EXPECT_TRUE(omnibox_view->GetText().empty()); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, kCtrlOrCmdMask)); |
| EXPECT_EQ(old_text, omnibox_view->GetText()); |
| |
| // Redo should delete the text again. |
| ASSERT_NO_FATAL_FAILURE( |
| SendKey(ui::VKEY_Z, kCtrlOrCmdMask | ui::EF_SHIFT_DOWN)); |
| EXPECT_TRUE(omnibox_view->GetText().empty()); |
| |
| // Perform an undo. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, kCtrlOrCmdMask)); |
| EXPECT_TRUE(omnibox_view->IsSelectAll()); |
| |
| // The text should be selected. |
| size_t start, end; |
| omnibox_view->GetSelectionBounds(&start, &end); |
| EXPECT_EQ(old_text.size(), start); |
| EXPECT_EQ(0U, end); |
| |
| // Delete three characters; "about:bl" should not trigger inline autocomplete. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_END, 0)); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); |
| EXPECT_EQ(old_text.substr(0, old_text.size() - 3), omnibox_view->GetText()); |
| |
| // Undo delete. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, kCtrlOrCmdMask)); |
| EXPECT_EQ(old_text, omnibox_view->GetText()); |
| |
| // Redo delete. |
| ASSERT_NO_FATAL_FAILURE( |
| SendKey(ui::VKEY_Z, kCtrlOrCmdMask | ui::EF_SHIFT_DOWN)); |
| EXPECT_EQ(old_text.substr(0, old_text.size() - 3), omnibox_view->GetText()); |
| |
| // Delete everything. |
| omnibox_view->SelectAll(true); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); |
| EXPECT_TRUE(omnibox_view->GetText().empty()); |
| |
| // Undo delete everything. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, kCtrlOrCmdMask)); |
| EXPECT_EQ(old_text.substr(0, old_text.size() - 3), omnibox_view->GetText()); |
| |
| // Undo delete two characters. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, kCtrlOrCmdMask)); |
| EXPECT_EQ(old_text, omnibox_view->GetText()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, BackspaceDeleteHalfWidthKatakana) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| // Insert text: ダ. This is two, 3-byte UTF-8 characters: |
| // U+FF80 "HALFWIDTH KATAKANA LETTER TA" and |
| // U+FF9E "HALFWIDTH KATAKANA VOICED SOUND MARK". |
| omnibox_view->SetUserText(u"\uFF80\uFF9E"); |
| EXPECT_FALSE(omnibox_view->GetText().empty()); |
| |
| // Move the cursor to the end. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_END, 0)); |
| |
| // Backspace should delete the character. In http://crbug.com/192743, the bug |
| // was that nothing was deleted. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); |
| #if BUILDFLAG(IS_MAC) |
| // Cocoa text fields attach the sound mark and delete the whole thing. This |
| // behavior should remain on Mac even when using a toolkit-views browser |
| // window. |
| EXPECT_TRUE(omnibox_view->GetText().empty()); |
| #else |
| // Toolkit-views text fields delete just the sound mark. |
| EXPECT_EQ(u"\uFF80", omnibox_view->GetText()); |
| #endif |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, DoesNotUpdateAutocompleteOnBlur) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| // Input something to trigger inline autocomplete. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| size_t start, end; |
| omnibox_view->GetSelectionBounds(&start, &end); |
| EXPECT_TRUE(start != end); |
| std::u16string old_autocomplete_text = |
| omnibox_view->controller()->autocomplete_controller()->input_.text(); |
| |
| // Unfocus the omnibox. This should close the popup but should not run |
| // autocomplete. |
| ui_test_utils::ClickOnView(browser(), VIEW_ID_TAB_CONTAINER); |
| ASSERT_FALSE(omnibox_view->model()->PopupIsOpen()); |
| EXPECT_EQ( |
| old_autocomplete_text, |
| omnibox_view->controller()->autocomplete_controller()->input_.text()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, Paste) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| EXPECT_FALSE(omnibox_view->model()->PopupIsOpen()); |
| |
| // Paste should yield the expected text and open the popup. |
| SetClipboardText(kSearchText); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_V, kCtrlOrCmdMask)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| EXPECT_EQ(kSearchText, omnibox_view->GetText()); |
| EXPECT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| // Close the popup and select all. |
| omnibox_view->CloseOmniboxPopup(); |
| omnibox_view->SelectAll(false); |
| EXPECT_FALSE(omnibox_view->model()->PopupIsOpen()); |
| |
| // Pasting the same text again over itself should re-open the popup. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_V, kCtrlOrCmdMask)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| EXPECT_EQ(kSearchText, omnibox_view->GetText()); |
| EXPECT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| omnibox_view->CloseOmniboxPopup(); |
| EXPECT_FALSE(omnibox_view->model()->PopupIsOpen()); |
| |
| // Pasting amid text should yield the expected text and re-open the popup. |
| omnibox_view->SetWindowTextAndCaretPos(u"abcd", 2, false, false); |
| SetClipboardText(u"123"); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_V, kCtrlOrCmdMask)); |
| EXPECT_EQ(u"ab123cd", omnibox_view->GetText()); |
| EXPECT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| // Ctrl/Cmd+Alt+V should not paste. |
| ASSERT_NO_FATAL_FAILURE( |
| SendKey(ui::VKEY_V, kCtrlOrCmdMask | ui::EF_ALT_DOWN)); |
| EXPECT_EQ(u"ab123cd", omnibox_view->GetText()); |
| // TODO(msw): Test that AltGr+V does not paste. |
| } |
| |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, EditSearchEngines) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_EDIT_SEARCH_ENGINES)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| const std::string target_url = |
| std::string(chrome::kChromeUISettingsURL) + chrome::kSearchEnginesSubPage; |
| EXPECT_EQ(ASCIIToUTF16(target_url), omnibox_view->GetText()); |
| EXPECT_FALSE(omnibox_view->model()->PopupIsOpen()); |
| } |
| |
| // Flaky test. The below suggestions are in a random order, and the injected |
| // keys may or may not have registered. Probably https://crbug.com/751031, |
| // but I believe the whole input mechanism needs to be re-architected. |
| // What I'd like to see is, after a sequence of keys is injected, we inject |
| // an artificial input, and, *only* after that input has been registered, |
| // do we continue. |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, |
| DISABLED_CtrlArrowAfterArrowSuggestions) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| // Input something to trigger results. |
| const ui::KeyboardCode kKeys[] = {ui::VKEY_B, ui::VKEY_A, ui::VKEY_R, |
| ui::VKEY_UNKNOWN}; |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| ASSERT_EQ(u"bar.com/1", omnibox_view->GetText()); |
| |
| // Arrow down on a suggestion, and omnibox text should be the suggestion. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DOWN, 0)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| ASSERT_EQ(u"www.bar.com/2", omnibox_view->GetText()); |
| |
| // Highlight the last 2 words and the omnibox text should not change. |
| // Simulating Ctrl-shift-left only once does not seem to highlight anything |
| // on Linux. |
| #if BUILDFLAG(IS_MAC) |
| // Mac uses alt-left/right to select a word. |
| const int modifiers = ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN; |
| #else |
| const int modifiers = ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN; |
| #endif |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, modifiers)); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, modifiers)); |
| ASSERT_EQ(u"www.bar.com/2", omnibox_view->GetText()); |
| } |
| |
| namespace { |
| |
| // Returns the number of characters currently selected in |omnibox_view|. |
| size_t GetSelectionSize(OmniboxView* omnibox_view) { |
| size_t start, end; |
| omnibox_view->GetSelectionBounds(&start, &end); |
| if (end >= start) { |
| return end - start; |
| } |
| return start - end; |
| } |
| |
| } // namespace |
| |
| // Test that if the Omnibox has focus, and had everything selected before a |
| // non-user-initiated update, then it retains the selection after the update. |
| // Flaky. See https://crbug.com/751031. |
| IN_PROC_BROWSER_TEST_F(OmniboxViewTest, DISABLED_SelectAllStaysAfterUpdate) { |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| std::u16string url_a(u"http://www.a.com/"); |
| std::u16string url_b(u"http://www.b.com/"); |
| chrome::FocusLocationBar(browser()); |
| |
| SetTestToolbarPermanentText(url_a); |
| EXPECT_EQ(url_a, omnibox_view->GetText()); |
| EXPECT_TRUE(omnibox_view->IsSelectAll()); |
| |
| // Updating while selected should retain SelectAll(). |
| SetTestToolbarPermanentText(url_b); |
| EXPECT_EQ(url_b, omnibox_view->GetText()); |
| EXPECT_TRUE(omnibox_view->IsSelectAll()); |
| |
| // Select nothing, then update. Should gain SelectAll(). |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RIGHT, 0)); |
| SetTestToolbarPermanentText(url_a); |
| EXPECT_EQ(url_a, omnibox_view->GetText()); |
| EXPECT_TRUE(omnibox_view->IsSelectAll()); |
| |
| // Test behavior of the "reversed" attribute of OmniboxView::SelectAll(). |
| SetTestToolbarPermanentText(u"AB"); |
| // Should be at beginning. Shift+left should do nothing. |
| EXPECT_EQ(2u, GetSelectionSize(omnibox_view)); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, ui::EF_SHIFT_DOWN)); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, ui::EF_SHIFT_DOWN)); |
| EXPECT_EQ(2u, GetSelectionSize(omnibox_view)); |
| EXPECT_TRUE(omnibox_view->IsSelectAll()); |
| |
| SetTestToolbarPermanentText(u"CD"); |
| EXPECT_EQ(2u, GetSelectionSize(omnibox_view)); |
| |
| // At the start, so Shift+Left should do nothing. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, ui::EF_SHIFT_DOWN)); |
| EXPECT_EQ(2u, GetSelectionSize(omnibox_view)); |
| |
| // And Shift+Right should reduce by one character. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RIGHT, ui::EF_SHIFT_DOWN)); |
| EXPECT_EQ(1u, GetSelectionSize(omnibox_view)); |
| |
| // No go to start and select all to the right (not reversed). |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0)); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0)); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RIGHT, ui::EF_SHIFT_DOWN)); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RIGHT, ui::EF_SHIFT_DOWN)); |
| SetTestToolbarPermanentText(u"AB"); |
| EXPECT_EQ(2u, GetSelectionSize(omnibox_view)); |
| |
| // We reverse select all on Update() so shift-left won't do anything. |
| // On Cocoa, shift-left will just anchor it on the left. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, ui::EF_SHIFT_DOWN)); |
| EXPECT_EQ(2u, GetSelectionSize(omnibox_view)); |
| |
| // And shift-right should reduce by one character. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RIGHT, ui::EF_SHIFT_DOWN)); |
| EXPECT_EQ(1u, GetSelectionSize(omnibox_view)); |
| } |
| |
| class SiteSearchPolicyOmniboxViewTest |
| : public OmniboxViewTest, |
| public ::testing::WithParamInterface<std::optional<bool>> { |
| public: |
| SiteSearchPolicyOmniboxViewTest() { |
| scoped_feature_list_.InitAndEnableFeature( |
| omnibox::kEnableSiteSearchAllowUserOverridePolicy); |
| } |
| ~SiteSearchPolicyOmniboxViewTest() override = default; |
| |
| base::Value CreateSiteSearchPolicyValue(bool featured) { |
| base::Value::Dict policy_dict = |
| base::Value::Dict() |
| .Set(policy::SiteSearchPolicyHandler::kShortcut, |
| kSiteSearchPolicyKeyword) |
| .Set(policy::SiteSearchPolicyHandler::kName, kSiteSearchPolicyName) |
| .Set(policy::SiteSearchPolicyHandler::kUrl, kSiteSearchPolicyURL) |
| .Set(policy::SiteSearchPolicyHandler::kFeatured, featured); |
| if (is_allow_user_override().has_value()) { |
| policy_dict.Set(policy::SiteSearchPolicyHandler::kAllowUserOverride, |
| is_allow_user_override().value()); |
| } |
| base::Value::List policy_value; |
| policy_value.Append(std::move(policy_dict)); |
| return base::Value(std::move(policy_value)); |
| } |
| |
| std::optional<bool> is_allow_user_override() const { return GetParam(); } |
| |
| private: |
| base::test::ScopedFeatureList scoped_feature_list_; |
| }; |
| |
| // Verifies that keyword search works when `SiteSearchSettings` policy is set. |
| IN_PROC_BROWSER_TEST_P(SiteSearchPolicyOmniboxViewTest, |
| NonFeaturedPolicyKeyword) { |
| policy::PolicyMap policies; |
| policies.Set(policy::key::kSiteSearchSettings, policy::POLICY_LEVEL_MANDATORY, |
| policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, |
| CreateSiteSearchPolicyValue(/*featured=*/false), nullptr); |
| policy_provider()->UpdateChromePolicy(policies); |
| |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| // Check that new entries have been added to TemplateURLService. |
| const TemplateURL* turl = |
| TemplateURLServiceFactory::GetForProfile(browser()->profile()) |
| ->GetTemplateURLForKeyword(kSiteSearchPolicyKeyword); |
| ASSERT_TRUE(turl); |
| EXPECT_EQ(turl->policy_origin(), TemplateURLData::PolicyOrigin::kSiteSearch); |
| EXPECT_EQ(turl->short_name(), kSiteSearchPolicyName); |
| EXPECT_EQ(turl->url(), kSiteSearchPolicyURL); |
| EXPECT_FALSE(turl->featured_by_policy()); |
| EXPECT_EQ(turl->enforced_by_policy(), |
| !is_allow_user_override().value_or(false)); |
| |
| // Trigger keyword hint mode. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSiteSearchPolicyKeywordKeys)); |
| EXPECT_TRUE(omnibox_view->model()->is_keyword_hint()); |
| EXPECT_EQ(omnibox_view->model()->keyword(), kSiteSearchPolicyKeyword); |
| |
| // Trigger keyword mode. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); |
| EXPECT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| EXPECT_EQ(omnibox_view->model()->keyword(), kSiteSearchPolicyKeyword); |
| |
| // Input something as search text and perform a search. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| EXPECT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| EXPECT_EQ(omnibox_view->controller() |
| ->autocomplete_controller() |
| ->result() |
| .default_match() |
| ->destination_url.spec(), |
| kSiteSearchPolicyTextURL); |
| } |
| |
| // Verifies that keyword search works when `SiteSearchSettings` policy defines |
| // a featured search engine. |
| IN_PROC_BROWSER_TEST_P(SiteSearchPolicyOmniboxViewTest, FeaturedPolicyKeyword) { |
| policy::PolicyMap policies; |
| policies.Set(policy::key::kSiteSearchSettings, policy::POLICY_LEVEL_MANDATORY, |
| policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, |
| CreateSiteSearchPolicyValue(/*featured=*/true), nullptr); |
| policy_provider()->UpdateChromePolicy(policies); |
| |
| OmniboxView* omnibox_view; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| // Check that new entries have been added to TemplateURLService. |
| const TemplateURL* turl = |
| TemplateURLServiceFactory::GetForProfile(browser()->profile()) |
| ->GetTemplateURLForKeyword(kSiteSearchPolicyKeywordWithAtPrefix); |
| ASSERT_TRUE(turl); |
| EXPECT_EQ(turl->policy_origin(), TemplateURLData::PolicyOrigin::kSiteSearch); |
| EXPECT_EQ(turl->short_name(), kSiteSearchPolicyName); |
| EXPECT_EQ(turl->url(), kSiteSearchPolicyURL); |
| EXPECT_TRUE(turl->featured_by_policy()); |
| EXPECT_EQ(turl->enforced_by_policy(), |
| !is_allow_user_override().value_or(false)); |
| |
| // Type the keyword. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_2, ui::EF_SHIFT_DOWN)); |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSiteSearchPolicyKeywordKeys)); |
| EXPECT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| EXPECT_EQ(omnibox_view->model()->keyword(), u""); |
| |
| // Trigger keyword mode. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); |
| EXPECT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| EXPECT_EQ(omnibox_view->model()->keyword(), |
| kSiteSearchPolicyKeywordWithAtPrefix); |
| |
| // Input something as search text and perform a search. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); // ABC |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| EXPECT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| EXPECT_EQ(omnibox_view->controller() |
| ->autocomplete_controller() |
| ->result() |
| .default_match() |
| ->destination_url.spec(), |
| kSiteSearchPolicyTextURL); // ...?q=ABC |
| } |
| |
| // Verifies that featured search engine is shown with starter pack on "@" state |
| // and that the underlying search works. |
| IN_PROC_BROWSER_TEST_P(SiteSearchPolicyOmniboxViewTest, |
| FeaturedPolicyKeywordArrowDown) { |
| policy::PolicyMap policies; |
| policies.Set(policy::key::kSiteSearchSettings, policy::POLICY_LEVEL_MANDATORY, |
| policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, |
| CreateSiteSearchPolicyValue(/*featured=*/true), nullptr); |
| policy_provider()->UpdateChromePolicy(policies); |
| |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| // Check that new entries have been added to TemplateURLService. |
| const TemplateURL* turl = |
| TemplateURLServiceFactory::GetForProfile(browser()->profile()) |
| ->GetTemplateURLForKeyword(kSiteSearchPolicyKeywordWithAtPrefix); |
| ASSERT_TRUE(turl); |
| EXPECT_EQ(turl->policy_origin(), TemplateURLData::PolicyOrigin::kSiteSearch); |
| EXPECT_EQ(turl->short_name(), kSiteSearchPolicyName); |
| EXPECT_EQ(turl->url(), kSiteSearchPolicyURL); |
| EXPECT_TRUE(turl->featured_by_policy()); |
| EXPECT_EQ(turl->enforced_by_policy(), |
| !is_allow_user_override().value_or(false)); |
| |
| // Trigger keyword mode. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_2, ui::EF_SHIFT_DOWN)); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DOWN, /*modifiers=*/0)); |
| EXPECT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| EXPECT_EQ(omnibox_view->model()->keyword(), |
| kSiteSearchPolicyKeywordWithAtPrefix); |
| |
| // Input something as search text and perform a search. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| EXPECT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| EXPECT_EQ(omnibox_view->controller() |
| ->autocomplete_controller() |
| ->result() |
| .default_match() |
| ->destination_url.spec(), |
| kSiteSearchPolicyTextURL); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(All, |
| SiteSearchPolicyOmniboxViewTest, |
| ::testing::Values(std::nullopt, true, false)); |
| |
| class SearchAggregatorPolicyOmniboxViewTest : public OmniboxViewTest { |
| public: |
| SearchAggregatorPolicyOmniboxViewTest() { |
| scoped_feature_list_.InitAndEnableFeature( |
| omnibox::kEnableSearchAggregatorPolicy); |
| } |
| ~SearchAggregatorPolicyOmniboxViewTest() override = default; |
| |
| base::Value CreateEnterpriseSearchAggregatorPolicyValue() { |
| base::Value::Dict policy_value; |
| policy_value = base::Value::Dict() |
| .Set(policy::SearchAggregatorPolicyHandler::kIconUrl, |
| kSearchAggregatorPolicyIconUrl) |
| .Set(policy::SearchAggregatorPolicyHandler::kShortcut, |
| kSearchAggregatorPolicyKeyword) |
| .Set(policy::SearchAggregatorPolicyHandler::kName, |
| kSearchAggregatorPolicyName) |
| .Set(policy::SearchAggregatorPolicyHandler::kSearchUrl, |
| kSearchAggregatorPolicySearchUrl) |
| .Set(policy::SearchAggregatorPolicyHandler::kSuggestUrl, |
| kSearchAggregatorPolicySuggestUrl); |
| return base::Value(std::move(policy_value)); |
| } |
| |
| private: |
| base::test::ScopedFeatureList scoped_feature_list_; |
| }; |
| |
| // Verifies that keyword search works when |
| // `EnterpriseSearchAggregatorSettings` policy is set. |
| IN_PROC_BROWSER_TEST_F(SearchAggregatorPolicyOmniboxViewTest, NonFeatured) { |
| policy::PolicyMap policies; |
| policies.Set(policy::key::kEnterpriseSearchAggregatorSettings, |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, |
| policy::POLICY_SOURCE_CLOUD, |
| CreateEnterpriseSearchAggregatorPolicyValue(), nullptr); |
| policy_provider()->UpdateChromePolicy(policies); |
| |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| // Check that new entries have been added to TemplateURLService. |
| const TemplateURL* turl = |
| TemplateURLServiceFactory::GetForProfile(browser()->profile()) |
| ->GetTemplateURLForKeyword(kSearchAggregatorPolicyKeyword); |
| ASSERT_TRUE(turl); |
| EXPECT_EQ(turl->policy_origin(), |
| TemplateURLData::PolicyOrigin::kSearchAggregator); |
| EXPECT_EQ(turl->short_name(), kSearchAggregatorPolicyName); |
| EXPECT_EQ(turl->url(), kSearchAggregatorPolicySearchUrl); |
| EXPECT_EQ(turl->suggestions_url(), kSearchAggregatorPolicySuggestUrl); |
| EXPECT_EQ(turl->favicon_url(), kSearchAggregatorPolicyIconUrl); |
| EXPECT_TRUE(turl->enforced_by_policy()); |
| EXPECT_FALSE(turl->safe_for_autoreplace()); |
| EXPECT_FALSE(turl->featured_by_policy()); |
| |
| // Trigger keyword hint mode. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchAggregatorPolicyKeywordKeys)); |
| EXPECT_TRUE(omnibox_view->model()->is_keyword_hint()); |
| EXPECT_EQ(omnibox_view->model()->keyword(), kSearchAggregatorPolicyKeyword); |
| |
| // Trigger keyword mode. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); |
| EXPECT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| EXPECT_EQ(omnibox_view->model()->keyword(), kSearchAggregatorPolicyKeyword); |
| |
| // Input something as search text and perform a search. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| EXPECT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| EXPECT_EQ(omnibox_view->controller() |
| ->autocomplete_controller() |
| ->result() |
| .default_match() |
| ->destination_url.spec(), |
| kSearchAggregatorPolicyTextURL); |
| } |
| |
| // Verifies that featured search engine is shown when |
| // `EnterpriseSearchAggregatorSettings` policy is set. |
| IN_PROC_BROWSER_TEST_F(SearchAggregatorPolicyOmniboxViewTest, Featured) { |
| policy::PolicyMap policies; |
| policies.Set(policy::key::kEnterpriseSearchAggregatorSettings, |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, |
| policy::POLICY_SOURCE_CLOUD, |
| CreateEnterpriseSearchAggregatorPolicyValue(), nullptr); |
| policy_provider()->UpdateChromePolicy(policies); |
| |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| // Check that new entries have been added to TemplateURLService with at |
| // prefix. |
| const TemplateURL* turl = |
| TemplateURLServiceFactory::GetForProfile(browser()->profile()) |
| ->GetTemplateURLForKeyword( |
| kSearchAggregatorPolicyKeywordWithAtPrefix); |
| ASSERT_TRUE(turl); |
| EXPECT_EQ(turl->policy_origin(), |
| TemplateURLData::PolicyOrigin::kSearchAggregator); |
| EXPECT_EQ(turl->short_name(), kSearchAggregatorPolicyName); |
| EXPECT_EQ(turl->url(), kSearchAggregatorPolicySearchUrl); |
| EXPECT_EQ(turl->suggestions_url(), kSearchAggregatorPolicySuggestUrl); |
| EXPECT_EQ(turl->favicon_url(), kSearchAggregatorPolicyIconUrl); |
| EXPECT_TRUE(turl->enforced_by_policy()); |
| EXPECT_FALSE(turl->safe_for_autoreplace()); |
| EXPECT_TRUE(turl->featured_by_policy()); |
| |
| // Type the keyword. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_2, ui::EF_SHIFT_DOWN)); |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchAggregatorPolicyKeywordKeys)); |
| EXPECT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| EXPECT_EQ(omnibox_view->model()->keyword(), u""); |
| |
| // Trigger keyword mode. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); |
| EXPECT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| EXPECT_EQ(omnibox_view->model()->keyword(), |
| kSearchAggregatorPolicyKeywordWithAtPrefix); |
| |
| // Input something as search text and perform a search. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| EXPECT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| EXPECT_EQ(omnibox_view->controller() |
| ->autocomplete_controller() |
| ->result() |
| .default_match() |
| ->destination_url.spec(), |
| kSearchAggregatorPolicyTextURL); |
| } |
| |
| // Verifies that featured search engine is shown with starter pack on "@" |
| // state and that the underlying search works when |
| // `EnterpriseSearchAggregatorSettings` policy is set. |
| IN_PROC_BROWSER_TEST_F(SearchAggregatorPolicyOmniboxViewTest, |
| FeaturedOnArrowDown) { |
| policy::PolicyMap policies; |
| policies.Set(policy::key::kEnterpriseSearchAggregatorSettings, |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, |
| policy::POLICY_SOURCE_CLOUD, |
| CreateEnterpriseSearchAggregatorPolicyValue(), nullptr); |
| policy_provider()->UpdateChromePolicy(policies); |
| |
| OmniboxView* omnibox_view = nullptr; |
| ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); |
| |
| // Check that new entries have been added to TemplateURLService with at |
| // prefix. |
| const TemplateURL* turl = |
| TemplateURLServiceFactory::GetForProfile(browser()->profile()) |
| ->GetTemplateURLForKeyword( |
| kSearchAggregatorPolicyKeywordWithAtPrefix); |
| ASSERT_TRUE(turl); |
| EXPECT_EQ(turl->policy_origin(), |
| TemplateURLData::PolicyOrigin::kSearchAggregator); |
| EXPECT_EQ(turl->short_name(), kSearchAggregatorPolicyName); |
| EXPECT_EQ(turl->url(), kSearchAggregatorPolicySearchUrl); |
| EXPECT_EQ(turl->suggestions_url(), kSearchAggregatorPolicySuggestUrl); |
| EXPECT_EQ(turl->favicon_url(), kSearchAggregatorPolicyIconUrl); |
| EXPECT_TRUE(turl->enforced_by_policy()); |
| EXPECT_FALSE(turl->safe_for_autoreplace()); |
| EXPECT_TRUE(turl->featured_by_policy()); |
| |
| // Trigger keyword mode. |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_2, ui::EF_SHIFT_DOWN)); |
| ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); |
| EXPECT_FALSE(omnibox_view->model()->is_keyword_hint()); |
| EXPECT_EQ(omnibox_view->model()->keyword(), |
| kSearchAggregatorPolicyKeywordWithAtPrefix); |
| |
| // Input something as search text and perform a search. |
| ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); |
| ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); |
| EXPECT_TRUE(omnibox_view->model()->PopupIsOpen()); |
| |
| EXPECT_EQ(omnibox_view->controller() |
| ->autocomplete_controller() |
| ->result() |
| .default_match() |
| ->destination_url.spec(), |
| kSearchAggregatorPolicyTextURL); |
| } |