Home | History | Annotate | Download | only in autocomplete
      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 
     37 namespace {
     38 
     39 base::string16 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 
     52 class 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 
     69 IN_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 
    119 IN_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"), base::string16::npos, base::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 
    168 IN_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(base::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 
    195 IN_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