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