autocomplete_browsertest.cc revision f2477e01787aa58f445919b809d89e252beef54f
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/command_line.h"
6#include "base/format_macros.h"
7#include "base/path_service.h"
8#include "base/strings/stringprintf.h"
9#include "base/strings/utf_string_conversions.h"
10#include "chrome/browser/autocomplete/autocomplete_input.h"
11#include "chrome/browser/autocomplete/autocomplete_match.h"
12#include "chrome/browser/autocomplete/autocomplete_provider.h"
13#include "chrome/browser/extensions/extension_browsertest.h"
14#include "chrome/browser/extensions/extension_service.h"
15#include "chrome/browser/extensions/unpacked_installer.h"
16#include "chrome/browser/history/history_service.h"
17#include "chrome/browser/history/history_service_factory.h"
18#include "chrome/browser/profiles/profile.h"
19#include "chrome/browser/search_engines/template_url_service_factory.h"
20#include "chrome/browser/ui/browser.h"
21#include "chrome/browser/ui/browser_commands.h"
22#include "chrome/browser/ui/browser_tabstrip.h"
23#include "chrome/browser/ui/browser_window.h"
24#include "chrome/browser/ui/omnibox/location_bar.h"
25#include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
26#include "chrome/browser/ui/omnibox/omnibox_view.h"
27#include "chrome/browser/ui/tabs/tab_strip_model.h"
28#include "chrome/common/chrome_paths.h"
29#include "chrome/common/url_constants.h"
30#include "chrome/test/base/in_process_browser_test.h"
31#include "chrome/test/base/test_switches.h"
32#include "chrome/test/base/ui_test_utils.h"
33#include "content/public/browser/notification_service.h"
34#include "content/public/browser/notification_types.h"
35#include "testing/gtest/include/gtest/gtest.h"
36
37namespace {
38
39string16 AutocompleteResultAsString(const AutocompleteResult& result) {
40  std::string output(base::StringPrintf("{%" PRIuS "} ", result.size()));
41  for (size_t i = 0; i < result.size(); ++i) {
42    AutocompleteMatch match = result.match_at(i);
43    output.append(base::StringPrintf("[\"%s\" by \"%s\"] ",
44                                     UTF16ToUTF8(match.contents).c_str(),
45                                     match.provider->GetName()));
46  }
47  return UTF8ToUTF16(output);
48}
49
50}  // namespace
51
52class AutocompleteBrowserTest : public ExtensionBrowserTest {
53 protected:
54  void WaitForTemplateURLServiceToLoad() {
55    ui_test_utils::WaitForTemplateURLServiceToLoad(
56      TemplateURLServiceFactory::GetForProfile(browser()->profile()));
57  }
58
59  LocationBar* GetLocationBar() const {
60    return browser()->window()->GetLocationBar();
61  }
62
63  AutocompleteController* GetAutocompleteController() const {
64    return GetLocationBar()->GetOmniboxView()->model()->popup_model()->
65        autocomplete_controller();
66  }
67};
68
69IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, Basic) {
70#if defined(OS_WIN) && defined(USE_ASH)
71  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
72  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
73    return;
74#endif
75
76  WaitForTemplateURLServiceToLoad();
77  LocationBar* location_bar = GetLocationBar();
78  OmniboxView* omnibox_view = location_bar->GetOmniboxView();
79
80  EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
81  EXPECT_EQ(UTF8ToUTF16(content::kAboutBlankURL), omnibox_view->GetText());
82  // TODO(phajdan.jr): check state of IsSelectAll when it's consistent across
83  // platforms.
84
85  location_bar->FocusLocation(true);
86
87  EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
88  EXPECT_EQ(UTF8ToUTF16(content::kAboutBlankURL), omnibox_view->GetText());
89  EXPECT_TRUE(omnibox_view->IsSelectAll());
90
91  omnibox_view->SetUserText(ASCIIToUTF16("chrome"));
92
93  EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
94  EXPECT_EQ(ASCIIToUTF16("chrome"), omnibox_view->GetText());
95  EXPECT_FALSE(omnibox_view->IsSelectAll());
96
97  omnibox_view->RevertAll();
98
99  EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
100  EXPECT_EQ(UTF8ToUTF16(content::kAboutBlankURL), omnibox_view->GetText());
101  EXPECT_FALSE(omnibox_view->IsSelectAll());
102
103  omnibox_view->SetUserText(ASCIIToUTF16("chrome"));
104  location_bar->Revert();
105
106  EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
107  EXPECT_EQ(UTF8ToUTF16(content::kAboutBlankURL), omnibox_view->GetText());
108  EXPECT_FALSE(omnibox_view->IsSelectAll());
109}
110
111// Autocomplete test is flaky on ChromeOS.
112// http://crbug.com/52928
113#if defined(OS_CHROMEOS)
114#define MAYBE_Autocomplete DISABLED_Autocomplete
115#else
116#define MAYBE_Autocomplete Autocomplete
117#endif
118
119IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, MAYBE_Autocomplete) {
120#if defined(OS_WIN) && defined(USE_ASH)
121  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
122  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
123    return;
124#endif
125
126  WaitForTemplateURLServiceToLoad();
127  // The results depend on the history backend being loaded. Make sure it is
128  // loaded so that the autocomplete results are consistent.
129  ui_test_utils::WaitForHistoryToLoad(
130      HistoryServiceFactory::GetForProfile(browser()->profile(),
131                                           Profile::EXPLICIT_ACCESS));
132
133  LocationBar* location_bar = GetLocationBar();
134  OmniboxView* omnibox_view = location_bar->GetOmniboxView();
135  AutocompleteController* autocomplete_controller = GetAutocompleteController();
136
137  {
138    omnibox_view->model()->SetInputInProgress(true);
139    autocomplete_controller->Start(AutocompleteInput(
140        ASCIIToUTF16("chrome"), string16::npos, string16(), GURL(),
141        AutocompleteInput::NTP, true, false, true,
142        AutocompleteInput::SYNCHRONOUS_MATCHES));
143
144    EXPECT_TRUE(autocomplete_controller->done());
145    EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
146    EXPECT_TRUE(omnibox_view->GetText().empty());
147    EXPECT_TRUE(omnibox_view->IsSelectAll());
148    const AutocompleteResult& result = autocomplete_controller->result();
149    // We get two matches because we have a provider for extension apps and the
150    // Chrome Web Store is a built-in Extension app. For this test, we only care
151    // about the other match existing.
152    ASSERT_GE(result.size(), 1U) << AutocompleteResultAsString(result);
153    AutocompleteMatch match = result.match_at(0);
154    EXPECT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, match.type);
155    EXPECT_FALSE(match.deletable);
156  }
157
158  {
159    location_bar->Revert();
160    EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
161    EXPECT_EQ(UTF8ToUTF16(content::kAboutBlankURL), omnibox_view->GetText());
162    EXPECT_FALSE(omnibox_view->IsSelectAll());
163    const AutocompleteResult& result = autocomplete_controller->result();
164    EXPECT_TRUE(result.empty()) << AutocompleteResultAsString(result);
165  }
166}
167
168IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, TabAwayRevertSelect) {
169#if defined(OS_WIN) && defined(USE_ASH)
170  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
171  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
172    return;
173#endif
174
175  WaitForTemplateURLServiceToLoad();
176  // http://code.google.com/p/chromium/issues/detail?id=38385
177  // Make sure that tabbing away from an empty omnibox causes a revert
178  // and select all.
179  LocationBar* location_bar = GetLocationBar();
180  OmniboxView* omnibox_view = location_bar->GetOmniboxView();
181  EXPECT_EQ(UTF8ToUTF16(content::kAboutBlankURL), omnibox_view->GetText());
182  omnibox_view->SetUserText(string16());
183  content::WindowedNotificationObserver observer(
184      content::NOTIFICATION_LOAD_STOP,
185      content::NotificationService::AllSources());
186  chrome::AddSelectedTabWithURL(browser(), GURL(content::kAboutBlankURL),
187                                content::PAGE_TRANSITION_AUTO_TOPLEVEL);
188  observer.Wait();
189  EXPECT_EQ(UTF8ToUTF16(content::kAboutBlankURL), omnibox_view->GetText());
190  chrome::CloseTab(browser());
191  EXPECT_EQ(UTF8ToUTF16(content::kAboutBlankURL), omnibox_view->GetText());
192  EXPECT_TRUE(omnibox_view->IsSelectAll());
193}
194
195IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, FocusSearch) {
196#if defined(OS_WIN) && defined(USE_ASH)
197  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
198  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
199    return;
200#endif
201
202  WaitForTemplateURLServiceToLoad();
203  LocationBar* location_bar = GetLocationBar();
204  OmniboxView* omnibox_view = location_bar->GetOmniboxView();
205
206  // Focus search when omnibox is blank
207  {
208    EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
209    EXPECT_EQ(UTF8ToUTF16(content::kAboutBlankURL), omnibox_view->GetText());
210
211    location_bar->FocusSearch();
212    EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
213    EXPECT_EQ(ASCIIToUTF16("?"), omnibox_view->GetText());
214
215    size_t selection_start, selection_end;
216    omnibox_view->GetSelectionBounds(&selection_start, &selection_end);
217    EXPECT_EQ(1U, selection_start);
218    EXPECT_EQ(1U, selection_end);
219  }
220
221  // Focus search when omnibox is _not_ alread in forced query mode.
222  {
223    omnibox_view->SetUserText(ASCIIToUTF16("foo"));
224    EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
225    EXPECT_EQ(ASCIIToUTF16("foo"), omnibox_view->GetText());
226
227    location_bar->FocusSearch();
228    EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
229    EXPECT_EQ(ASCIIToUTF16("?"), omnibox_view->GetText());
230
231    size_t selection_start, selection_end;
232    omnibox_view->GetSelectionBounds(&selection_start, &selection_end);
233    EXPECT_EQ(1U, selection_start);
234    EXPECT_EQ(1U, selection_end);
235  }
236
237  // Focus search when omnibox _is_ already in forced query mode, but no query
238  // has been typed.
239  {
240    omnibox_view->SetUserText(ASCIIToUTF16("?"));
241    EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
242    EXPECT_EQ(ASCIIToUTF16("?"), omnibox_view->GetText());
243
244    location_bar->FocusSearch();
245    EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
246    EXPECT_EQ(ASCIIToUTF16("?"), omnibox_view->GetText());
247
248    size_t selection_start, selection_end;
249    omnibox_view->GetSelectionBounds(&selection_start, &selection_end);
250    EXPECT_EQ(1U, selection_start);
251    EXPECT_EQ(1U, selection_end);
252  }
253
254  // Focus search when omnibox _is_ already in forced query mode, and some query
255  // has been typed.
256  {
257    omnibox_view->SetUserText(ASCIIToUTF16("?foo"));
258    EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
259    EXPECT_EQ(ASCIIToUTF16("?foo"), omnibox_view->GetText());
260
261    location_bar->FocusSearch();
262    EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
263    EXPECT_EQ(ASCIIToUTF16("?foo"), omnibox_view->GetText());
264
265    size_t selection_start, selection_end;
266    omnibox_view->GetSelectionBounds(&selection_start, &selection_end);
267    EXPECT_EQ(1U, std::min(selection_start, selection_end));
268    EXPECT_EQ(4U, std::max(selection_start, selection_end));
269  }
270
271  // Focus search when omnibox is in forced query mode with leading whitespace.
272  {
273    omnibox_view->SetUserText(ASCIIToUTF16("   ?foo"));
274    EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
275    EXPECT_EQ(ASCIIToUTF16("   ?foo"), omnibox_view->GetText());
276
277    location_bar->FocusSearch();
278    EXPECT_FALSE(location_bar->GetDestinationURL().is_valid());
279    EXPECT_EQ(ASCIIToUTF16("   ?foo"), omnibox_view->GetText());
280
281    size_t selection_start, selection_end;
282    omnibox_view->GetSelectionBounds(&selection_start, &selection_end);
283    EXPECT_EQ(4U, std::min(selection_start, selection_end));
284    EXPECT_EQ(7U, std::max(selection_start, selection_end));
285  }
286}
287