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