• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
IN_PROC_BROWSER_TEST_F(OmniboxApiTest,Basic)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 
IN_PROC_BROWSER_TEST_F(OmniboxApiTest,OnInputEntered)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
IN_PROC_BROWSER_TEST_F(OmniboxApiTest,DISABLED_IncognitoSplitMode)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