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/chrome_autocomplete_scheme_classifier.h"
      9 #include "chrome/browser/extensions/api/omnibox/omnibox_api_testbase.h"
     10 #include "chrome/browser/profiles/profile.h"
     11 #include "chrome/browser/search_engines/template_url_service_factory.h"
     12 #include "chrome/browser/ui/browser.h"
     13 #include "chrome/browser/ui/location_bar/location_bar.h"
     14 #include "chrome/browser/ui/omnibox/omnibox_view.h"
     15 #include "chrome/test/base/ui_test_utils.h"
     16 #include "components/metrics/proto/omnibox_event.pb.h"
     17 #include "components/omnibox/autocomplete_input.h"
     18 #include "components/omnibox/autocomplete_match.h"
     19 #include "components/omnibox/autocomplete_result.h"
     20 #include "extensions/test/result_catcher.h"
     21 #include "ui/base/window_open_disposition.h"
     22 
     23 using base::ASCIIToUTF16;
     24 using extensions::ResultCatcher;
     25 using metrics::OmniboxEventProto;
     26 
     27 // http://crbug.com/167158
     28 IN_PROC_BROWSER_TEST_F(OmniboxApiTest, DISABLED_Basic) {
     29   ASSERT_TRUE(RunExtensionTest("omnibox")) << message_;
     30 
     31   // The results depend on the TemplateURLService being loaded. Make sure it is
     32   // loaded so that the autocomplete results are consistent.
     33   Profile* profile = browser()->profile();
     34   ui_test_utils::WaitForTemplateURLServiceToLoad(
     35       TemplateURLServiceFactory::GetForProfile(profile));
     36 
     37   AutocompleteController* autocomplete_controller =
     38       GetAutocompleteController(browser());
     39 
     40   // Test that our extension's keyword is suggested to us when we partially type
     41   // it.
     42   {
     43     autocomplete_controller->Start(AutocompleteInput(
     44         ASCIIToUTF16("keywor"), base::string16::npos, base::string16(), GURL(),
     45         OmniboxEventProto::NTP, true, false, true, true,
     46         ChromeAutocompleteSchemeClassifier(profile)));
     47     WaitForAutocompleteDone(autocomplete_controller);
     48     EXPECT_TRUE(autocomplete_controller->done());
     49 
     50     // Now, peek into the controller to see if it has the results we expect.
     51     // First result should be to search for what was typed, second should be to
     52     // enter "extension keyword" mode.
     53     const AutocompleteResult& result = autocomplete_controller->result();
     54     ASSERT_EQ(2U, result.size()) << AutocompleteResultAsString(result);
     55     AutocompleteMatch match = result.match_at(0);
     56     EXPECT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, match.type);
     57     EXPECT_FALSE(match.deletable);
     58 
     59     match = result.match_at(1);
     60     EXPECT_EQ(ASCIIToUTF16("keyword"), match.keyword);
     61   }
     62 
     63   // Test that our extension can send suggestions back to us.
     64   {
     65     autocomplete_controller->Start(AutocompleteInput(
     66         ASCIIToUTF16("keyword suggestio"), base::string16::npos,
     67         base::string16(), GURL(), OmniboxEventProto::NTP, true, false, true,
     68         true, ChromeAutocompleteSchemeClassifier(profile)));
     69     WaitForAutocompleteDone(autocomplete_controller);
     70     EXPECT_TRUE(autocomplete_controller->done());
     71 
     72     // Now, peek into the controller to see if it has the results we expect.
     73     // First result should be to invoke the keyword with what we typed, 2-4
     74     // should be to invoke with suggestions from the extension, and the last
     75     // should be to search for what we typed.
     76     const AutocompleteResult& result = autocomplete_controller->result();
     77     ASSERT_EQ(5U, result.size()) << AutocompleteResultAsString(result);
     78 
     79     EXPECT_EQ(ASCIIToUTF16("keyword"), result.match_at(0).keyword);
     80     EXPECT_EQ(ASCIIToUTF16("keyword suggestio"),
     81               result.match_at(0).fill_into_edit);
     82     EXPECT_EQ(AutocompleteMatchType::SEARCH_OTHER_ENGINE,
     83               result.match_at(0).type);
     84     EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD,
     85               result.match_at(0).provider->type());
     86     EXPECT_EQ(ASCIIToUTF16("keyword"), result.match_at(1).keyword);
     87     EXPECT_EQ(ASCIIToUTF16("keyword suggestion1"),
     88               result.match_at(1).fill_into_edit);
     89     EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD,
     90               result.match_at(1).provider->type());
     91     EXPECT_EQ(ASCIIToUTF16("keyword"), result.match_at(2).keyword);
     92     EXPECT_EQ(ASCIIToUTF16("keyword suggestion2"),
     93               result.match_at(2).fill_into_edit);
     94     EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD,
     95               result.match_at(2).provider->type());
     96     EXPECT_EQ(ASCIIToUTF16("keyword"), result.match_at(3).keyword);
     97     EXPECT_EQ(ASCIIToUTF16("keyword suggestion3"),
     98               result.match_at(3).fill_into_edit);
     99     EXPECT_EQ(AutocompleteProvider::TYPE_KEYWORD,
    100               result.match_at(3).provider->type());
    101 
    102     base::string16 description =
    103         ASCIIToUTF16("Description with style: <match>, [dim], (url till end)");
    104     EXPECT_EQ(description, result.match_at(1).contents);
    105     ASSERT_EQ(6u, result.match_at(1).contents_class.size());
    106 
    107     EXPECT_EQ(0u,
    108               result.match_at(1).contents_class[0].offset);
    109     EXPECT_EQ(ACMatchClassification::NONE,
    110               result.match_at(1).contents_class[0].style);
    111 
    112     EXPECT_EQ(description.find('<'),
    113               result.match_at(1).contents_class[1].offset);
    114     EXPECT_EQ(ACMatchClassification::MATCH,
    115               result.match_at(1).contents_class[1].style);
    116 
    117     EXPECT_EQ(description.find('>') + 1u,
    118               result.match_at(1).contents_class[2].offset);
    119     EXPECT_EQ(ACMatchClassification::NONE,
    120               result.match_at(1).contents_class[2].style);
    121 
    122     EXPECT_EQ(description.find('['),
    123               result.match_at(1).contents_class[3].offset);
    124     EXPECT_EQ(ACMatchClassification::DIM,
    125               result.match_at(1).contents_class[3].style);
    126 
    127     EXPECT_EQ(description.find(']') + 1u,
    128               result.match_at(1).contents_class[4].offset);
    129     EXPECT_EQ(ACMatchClassification::NONE,
    130               result.match_at(1).contents_class[4].style);
    131 
    132     EXPECT_EQ(description.find('('),
    133               result.match_at(1).contents_class[5].offset);
    134     EXPECT_EQ(ACMatchClassification::URL,
    135               result.match_at(1).contents_class[5].style);
    136 
    137     AutocompleteMatch match = result.match_at(4);
    138     EXPECT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, match.type);
    139     EXPECT_EQ(AutocompleteProvider::TYPE_SEARCH,
    140               result.match_at(4).provider->type());
    141     EXPECT_FALSE(match.deletable);
    142   }
    143 
    144   // Flaky, see http://crbug.com/167158
    145   /*
    146   {
    147     LocationBar* location_bar = GetLocationBar(browser());
    148     ResultCatcher catcher;
    149     OmniboxView* omnibox_view = location_bar->GetOmniboxView();
    150     omnibox_view->OnBeforePossibleChange();
    151     omnibox_view->SetUserText(ASCIIToUTF16("keyword command"));
    152     omnibox_view->OnAfterPossibleChange();
    153     location_bar->AcceptInput();
    154     // This checks that the keyword provider (via javascript)
    155     // gets told to navigate to the string "command".
    156     EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    157   }
    158   */
    159 }
    160 
    161 IN_PROC_BROWSER_TEST_F(OmniboxApiTest, OnInputEntered) {
    162   ASSERT_TRUE(RunExtensionTest("omnibox")) << message_;
    163   Profile* profile = browser()->profile();
    164   ui_test_utils::WaitForTemplateURLServiceToLoad(
    165       TemplateURLServiceFactory::GetForProfile(profile));
    166 
    167   LocationBar* location_bar = GetLocationBar(browser());
    168   OmniboxView* omnibox_view = location_bar->GetOmniboxView();
    169   ResultCatcher catcher;
    170   AutocompleteController* autocomplete_controller =
    171       GetAutocompleteController(browser());
    172   omnibox_view->OnBeforePossibleChange();
    173   omnibox_view->SetUserText(ASCIIToUTF16("keyword command"));
    174   omnibox_view->OnAfterPossibleChange();
    175 
    176   autocomplete_controller->Start(AutocompleteInput(
    177       ASCIIToUTF16("keyword command"), base::string16::npos, base::string16(),
    178       GURL(), OmniboxEventProto::NTP, true, false, true, true,
    179       ChromeAutocompleteSchemeClassifier(profile)));
    180   omnibox_view->model()->AcceptInput(CURRENT_TAB, false);
    181   WaitForAutocompleteDone(autocomplete_controller);
    182   EXPECT_TRUE(autocomplete_controller->done());
    183   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    184 
    185   omnibox_view->OnBeforePossibleChange();
    186   omnibox_view->SetUserText(ASCIIToUTF16("keyword newtab"));
    187   omnibox_view->OnAfterPossibleChange();
    188   WaitForAutocompleteDone(autocomplete_controller);
    189   EXPECT_TRUE(autocomplete_controller->done());
    190 
    191   autocomplete_controller->Start(AutocompleteInput(
    192       ASCIIToUTF16("keyword newtab"), base::string16::npos, base::string16(),
    193       GURL(), OmniboxEventProto::NTP, true, false, true, true,
    194       ChromeAutocompleteSchemeClassifier(profile)));
    195   omnibox_view->model()->AcceptInput(NEW_FOREGROUND_TAB, false);
    196   WaitForAutocompleteDone(autocomplete_controller);
    197   EXPECT_TRUE(autocomplete_controller->done());
    198   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    199 }
    200 
    201 // Tests that we get suggestions from and send input to the incognito context
    202 // of an incognito split mode extension.
    203 // http://crbug.com/100927
    204 // Test is flaky: http://crbug.com/101219
    205 IN_PROC_BROWSER_TEST_F(OmniboxApiTest, DISABLED_IncognitoSplitMode) {
    206   Profile* profile = browser()->profile();
    207   ResultCatcher catcher_incognito;
    208   catcher_incognito.RestrictToBrowserContext(profile->GetOffTheRecordProfile());
    209 
    210   ASSERT_TRUE(RunExtensionTestIncognito("omnibox")) << message_;
    211 
    212   // Open an incognito window and wait for the incognito extension process to
    213   // respond.
    214   Browser* incognito_browser = CreateIncognitoBrowser();
    215   ASSERT_TRUE(catcher_incognito.GetNextResult()) << catcher_incognito.message();
    216 
    217   // The results depend on the TemplateURLService being loaded. Make sure it is
    218   // loaded so that the autocomplete results are consistent.
    219   ui_test_utils::WaitForTemplateURLServiceToLoad(
    220       TemplateURLServiceFactory::GetForProfile(browser()->profile()));
    221 
    222   LocationBar* location_bar = GetLocationBar(incognito_browser);
    223   AutocompleteController* autocomplete_controller =
    224       GetAutocompleteController(incognito_browser);
    225 
    226   // Test that we get the incognito-specific suggestions.
    227   {
    228     autocomplete_controller->Start(AutocompleteInput(
    229         ASCIIToUTF16("keyword suggestio"), base::string16::npos,
    230         base::string16(), GURL(), OmniboxEventProto::NTP, true, false, true,
    231         true, ChromeAutocompleteSchemeClassifier(profile)));
    232     WaitForAutocompleteDone(autocomplete_controller);
    233     EXPECT_TRUE(autocomplete_controller->done());
    234 
    235     // First result should be to invoke the keyword with what we typed, 2-4
    236     // should be to invoke with suggestions from the extension, and the last
    237     // should be to search for what we typed.
    238     const AutocompleteResult& result = autocomplete_controller->result();
    239     ASSERT_EQ(5U, result.size()) << AutocompleteResultAsString(result);
    240     ASSERT_FALSE(result.match_at(0).keyword.empty());
    241     EXPECT_EQ(ASCIIToUTF16("keyword suggestion3 incognito"),
    242               result.match_at(3).fill_into_edit);
    243   }
    244 
    245   // Test that our input is sent to the incognito context. The test will do a
    246   // text comparison and succeed only if "command incognito" is sent to the
    247   // incognito context.
    248   {
    249     ResultCatcher catcher;
    250     autocomplete_controller->Start(AutocompleteInput(
    251         ASCIIToUTF16("keyword command incognito"), base::string16::npos,
    252         base::string16(), GURL(), OmniboxEventProto::NTP, true, false, true,
    253         true, ChromeAutocompleteSchemeClassifier(profile)));
    254     location_bar->AcceptInput();
    255     EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    256   }
    257 }
    258