Home | History | Annotate | Download | only in omnibox
      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 
     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 
    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
    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