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