1// Copyright (c) 2012 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. 4 5#include "base/strings/string16.h" 6#include "base/strings/utf_string_conversions.h" 7#include "chrome/browser/autocomplete/autocomplete_controller.h" 8#include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" 9#include "chrome/browser/extensions/api/omnibox/omnibox_api_testbase.h" 10#include "chrome/browser/profiles/profile.h" 11#include "chrome/browser/search_engines/template_url_service_factory.h" 12#include "chrome/browser/ui/browser.h" 13#include "chrome/browser/ui/location_bar/location_bar.h" 14#include "chrome/browser/ui/omnibox/omnibox_view.h" 15#include "chrome/test/base/ui_test_utils.h" 16#include "components/metrics/proto/omnibox_event.pb.h" 17#include "components/omnibox/autocomplete_input.h" 18#include "components/omnibox/autocomplete_match.h" 19#include "components/omnibox/autocomplete_result.h" 20#include "extensions/test/result_catcher.h" 21#include "ui/base/window_open_disposition.h" 22 23using base::ASCIIToUTF16; 24using extensions::ResultCatcher; 25using metrics::OmniboxEventProto; 26 27// http://crbug.com/167158 28IN_PROC_BROWSER_TEST_F(OmniboxApiTest, DISABLED_Basic) { 29 ASSERT_TRUE(RunExtensionTest("omnibox")) << message_; 30 31 // The results depend on the TemplateURLService being loaded. Make sure it is 32 // loaded so that the autocomplete results are consistent. 33 Profile* profile = browser()->profile(); 34 ui_test_utils::WaitForTemplateURLServiceToLoad( 35 TemplateURLServiceFactory::GetForProfile(profile)); 36 37 AutocompleteController* autocomplete_controller = 38 GetAutocompleteController(browser()); 39 40 // Test that our extension's keyword is suggested to us when we partially type 41 // it. 42 { 43 autocomplete_controller->Start(AutocompleteInput( 44 ASCIIToUTF16("keywor"), base::string16::npos, base::string16(), GURL(), 45 OmniboxEventProto::NTP, true, false, true, true, 46 ChromeAutocompleteSchemeClassifier(profile))); 47 WaitForAutocompleteDone(autocomplete_controller); 48 EXPECT_TRUE(autocomplete_controller->done()); 49 50 // Now, peek into the controller to see if it has the results we expect. 51 // First result should be to search for what was typed, second should be to 52 // enter "extension keyword" mode. 53 const AutocompleteResult& result = autocomplete_controller->result(); 54 ASSERT_EQ(2U, result.size()) << AutocompleteResultAsString(result); 55 AutocompleteMatch match = result.match_at(0); 56 EXPECT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, match.type); 57 EXPECT_FALSE(match.deletable); 58 59 match = result.match_at(1); 60 EXPECT_EQ(ASCIIToUTF16("keyword"), match.keyword); 61 } 62 63 // Test that our extension can send suggestions back to us. 64 { 65 autocomplete_controller->Start(AutocompleteInput( 66 ASCIIToUTF16("keyword suggestio"), base::string16::npos, 67 base::string16(), GURL(), OmniboxEventProto::NTP, true, false, true, 68 true, ChromeAutocompleteSchemeClassifier(profile))); 69 WaitForAutocompleteDone(autocomplete_controller); 70 EXPECT_TRUE(autocomplete_controller->done()); 71 72 // Now, peek into the controller to see if it has the results we expect. 73 // First result should be to invoke the keyword with what we typed, 2-4 74 // should be to invoke with suggestions from the extension, and the last 75 // should be to search for what we typed. 76 const AutocompleteResult& result = autocomplete_controller->result(); 77 ASSERT_EQ(5U, result.size()) << AutocompleteResultAsString(result); 78 79 EXPECT_EQ(ASCIIToUTF16("keyword"), result.match_at(0).keyword); 80 EXPECT_EQ(ASCIIToUTF16("keyword suggestio"), 81 result.match_at(0).fill_into_edit); 82 EXPECT_EQ(AutocompleteMatchType::SEARCH_OTHER_ENGINE, 83 result.match_at(0).type); 84 EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD, 85 result.match_at(0).provider->type()); 86 EXPECT_EQ(ASCIIToUTF16("keyword"), result.match_at(1).keyword); 87 EXPECT_EQ(ASCIIToUTF16("keyword suggestion1"), 88 result.match_at(1).fill_into_edit); 89 EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD, 90 result.match_at(1).provider->type()); 91 EXPECT_EQ(ASCIIToUTF16("keyword"), result.match_at(2).keyword); 92 EXPECT_EQ(ASCIIToUTF16("keyword suggestion2"), 93 result.match_at(2).fill_into_edit); 94 EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD, 95 result.match_at(2).provider->type()); 96 EXPECT_EQ(ASCIIToUTF16("keyword"), result.match_at(3).keyword); 97 EXPECT_EQ(ASCIIToUTF16("keyword suggestion3"), 98 result.match_at(3).fill_into_edit); 99 EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD, 100 result.match_at(3).provider->type()); 101 102 base::string16 description = 103 ASCIIToUTF16("Description with style: <match>, [dim], (url till end)"); 104 EXPECT_EQ(description, result.match_at(1).contents); 105 ASSERT_EQ(6u, result.match_at(1).contents_class.size()); 106 107 EXPECT_EQ(0u, 108 result.match_at(1).contents_class[0].offset); 109 EXPECT_EQ(ACMatchClassification::NONE, 110 result.match_at(1).contents_class[0].style); 111 112 EXPECT_EQ(description.find('<'), 113 result.match_at(1).contents_class[1].offset); 114 EXPECT_EQ(ACMatchClassification::MATCH, 115 result.match_at(1).contents_class[1].style); 116 117 EXPECT_EQ(description.find('>') + 1u, 118 result.match_at(1).contents_class[2].offset); 119 EXPECT_EQ(ACMatchClassification::NONE, 120 result.match_at(1).contents_class[2].style); 121 122 EXPECT_EQ(description.find('['), 123 result.match_at(1).contents_class[3].offset); 124 EXPECT_EQ(ACMatchClassification::DIM, 125 result.match_at(1).contents_class[3].style); 126 127 EXPECT_EQ(description.find(']') + 1u, 128 result.match_at(1).contents_class[4].offset); 129 EXPECT_EQ(ACMatchClassification::NONE, 130 result.match_at(1).contents_class[4].style); 131 132 EXPECT_EQ(description.find('('), 133 result.match_at(1).contents_class[5].offset); 134 EXPECT_EQ(ACMatchClassification::URL, 135 result.match_at(1).contents_class[5].style); 136 137 AutocompleteMatch match = result.match_at(4); 138 EXPECT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, match.type); 139 EXPECT_EQ(AutocompleteProvider::TYPE_SEARCH, 140 result.match_at(4).provider->type()); 141 EXPECT_FALSE(match.deletable); 142 } 143 144 // Flaky, see http://crbug.com/167158 145 /* 146 { 147 LocationBar* location_bar = GetLocationBar(browser()); 148 ResultCatcher catcher; 149 OmniboxView* omnibox_view = location_bar->GetOmniboxView(); 150 omnibox_view->OnBeforePossibleChange(); 151 omnibox_view->SetUserText(ASCIIToUTF16("keyword command")); 152 omnibox_view->OnAfterPossibleChange(); 153 location_bar->AcceptInput(); 154 // This checks that the keyword provider (via javascript) 155 // gets told to navigate to the string "command". 156 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 157 } 158 */ 159} 160 161IN_PROC_BROWSER_TEST_F(OmniboxApiTest, OnInputEntered) { 162 ASSERT_TRUE(RunExtensionTest("omnibox")) << message_; 163 Profile* profile = browser()->profile(); 164 ui_test_utils::WaitForTemplateURLServiceToLoad( 165 TemplateURLServiceFactory::GetForProfile(profile)); 166 167 LocationBar* location_bar = GetLocationBar(browser()); 168 OmniboxView* omnibox_view = location_bar->GetOmniboxView(); 169 ResultCatcher catcher; 170 AutocompleteController* autocomplete_controller = 171 GetAutocompleteController(browser()); 172 omnibox_view->OnBeforePossibleChange(); 173 omnibox_view->SetUserText(ASCIIToUTF16("keyword command")); 174 omnibox_view->OnAfterPossibleChange(); 175 176 autocomplete_controller->Start(AutocompleteInput( 177 ASCIIToUTF16("keyword command"), base::string16::npos, base::string16(), 178 GURL(), OmniboxEventProto::NTP, true, false, true, true, 179 ChromeAutocompleteSchemeClassifier(profile))); 180 omnibox_view->model()->AcceptInput(CURRENT_TAB, false); 181 WaitForAutocompleteDone(autocomplete_controller); 182 EXPECT_TRUE(autocomplete_controller->done()); 183 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 184 185 omnibox_view->OnBeforePossibleChange(); 186 omnibox_view->SetUserText(ASCIIToUTF16("keyword newtab")); 187 omnibox_view->OnAfterPossibleChange(); 188 WaitForAutocompleteDone(autocomplete_controller); 189 EXPECT_TRUE(autocomplete_controller->done()); 190 191 autocomplete_controller->Start(AutocompleteInput( 192 ASCIIToUTF16("keyword newtab"), base::string16::npos, base::string16(), 193 GURL(), OmniboxEventProto::NTP, true, false, true, true, 194 ChromeAutocompleteSchemeClassifier(profile))); 195 omnibox_view->model()->AcceptInput(NEW_FOREGROUND_TAB, false); 196 WaitForAutocompleteDone(autocomplete_controller); 197 EXPECT_TRUE(autocomplete_controller->done()); 198 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 199} 200 201// Tests that we get suggestions from and send input to the incognito context 202// of an incognito split mode extension. 203// http://crbug.com/100927 204// Test is flaky: http://crbug.com/101219 205IN_PROC_BROWSER_TEST_F(OmniboxApiTest, DISABLED_IncognitoSplitMode) { 206 Profile* profile = browser()->profile(); 207 ResultCatcher catcher_incognito; 208 catcher_incognito.RestrictToBrowserContext(profile->GetOffTheRecordProfile()); 209 210 ASSERT_TRUE(RunExtensionTestIncognito("omnibox")) << message_; 211 212 // Open an incognito window and wait for the incognito extension process to 213 // respond. 214 Browser* incognito_browser = CreateIncognitoBrowser(); 215 ASSERT_TRUE(catcher_incognito.GetNextResult()) << catcher_incognito.message(); 216 217 // The results depend on the TemplateURLService being loaded. Make sure it is 218 // loaded so that the autocomplete results are consistent. 219 ui_test_utils::WaitForTemplateURLServiceToLoad( 220 TemplateURLServiceFactory::GetForProfile(browser()->profile())); 221 222 LocationBar* location_bar = GetLocationBar(incognito_browser); 223 AutocompleteController* autocomplete_controller = 224 GetAutocompleteController(incognito_browser); 225 226 // Test that we get the incognito-specific suggestions. 227 { 228 autocomplete_controller->Start(AutocompleteInput( 229 ASCIIToUTF16("keyword suggestio"), base::string16::npos, 230 base::string16(), GURL(), OmniboxEventProto::NTP, true, false, true, 231 true, ChromeAutocompleteSchemeClassifier(profile))); 232 WaitForAutocompleteDone(autocomplete_controller); 233 EXPECT_TRUE(autocomplete_controller->done()); 234 235 // First result should be to invoke the keyword with what we typed, 2-4 236 // should be to invoke with suggestions from the extension, and the last 237 // should be to search for what we typed. 238 const AutocompleteResult& result = autocomplete_controller->result(); 239 ASSERT_EQ(5U, result.size()) << AutocompleteResultAsString(result); 240 ASSERT_FALSE(result.match_at(0).keyword.empty()); 241 EXPECT_EQ(ASCIIToUTF16("keyword suggestion3 incognito"), 242 result.match_at(3).fill_into_edit); 243 } 244 245 // Test that our input is sent to the incognito context. The test will do a 246 // text comparison and succeed only if "command incognito" is sent to the 247 // incognito context. 248 { 249 ResultCatcher catcher; 250 autocomplete_controller->Start(AutocompleteInput( 251 ASCIIToUTF16("keyword command incognito"), base::string16::npos, 252 base::string16(), GURL(), OmniboxEventProto::NTP, true, false, true, 253 true, ChromeAutocompleteSchemeClassifier(profile))); 254 location_bar->AcceptInput(); 255 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 256 } 257} 258