extension_omnibox_apitest.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 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/string_util.h"
6#include "base/stringprintf.h"
7#include "base/utf_string_conversions.h"
8#include "chrome/browser/autocomplete/autocomplete.h"
9#include "chrome/browser/autocomplete/autocomplete_edit.h"
10#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
11#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
12#include "chrome/browser/browser.h"
13#include "chrome/browser/browser_window.h"
14#include "chrome/browser/extensions/extension_apitest.h"
15#include "chrome/browser/location_bar.h"
16#include "chrome/browser/profile.h"
17#include "chrome/browser/search_engines/template_url.h"
18#include "chrome/browser/search_engines/template_url_model.h"
19#include "chrome/common/chrome_switches.h"
20#include "chrome/common/notification_type.h"
21#include "chrome/common/url_constants.h"
22#include "chrome/test/ui_test_utils.h"
23
24// Basic test is flaky on ChromeOS.
25// http://crbug.com/52929
26#if defined(OS_CHROMEOS)
27#define MAYBE_Basic FLAKY_Basic
28#else
29#define MAYBE_Basic Basic
30#endif
31
32namespace {
33
34std::wstring AutocompleteResultAsString(const AutocompleteResult& result) {
35  std::wstring output(base::StringPrintf(L"{%d} ", result.size()));
36  for (size_t i = 0; i < result.size(); ++i) {
37    AutocompleteMatch match = result.match_at(i);
38    std::wstring provider_name(ASCIIToWide(match.provider->name()));
39    output.append(base::StringPrintf(L"[\"%ls\" by \"%ls\"] ",
40                                     match.contents.c_str(),
41                                     provider_name.c_str()));
42  }
43  return output;
44}
45
46}  // namespace
47
48class OmniboxApiTest : public ExtensionApiTest {
49 protected:
50  LocationBar* GetLocationBar() const {
51    return browser()->window()->GetLocationBar();
52  }
53
54  AutocompleteController* GetAutocompleteController() const {
55    return GetLocationBar()->location_entry()->model()->popup_model()->
56        autocomplete_controller();
57  }
58
59  void WaitForTemplateURLModelToLoad() {
60    TemplateURLModel* model =
61        browser()->profile()->GetTemplateURLModel();
62    model->Load();
63    if (!model->loaded()) {
64      ui_test_utils::WaitForNotification(
65          NotificationType::TEMPLATE_URL_MODEL_LOADED);
66    }
67  }
68
69  void WaitForAutocompleteDone(AutocompleteController* controller) {
70    while (!controller->done()) {
71      ui_test_utils::WaitForNotification(
72          NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_UPDATED);
73    }
74  }
75};
76
77IN_PROC_BROWSER_TEST_F(OmniboxApiTest, MAYBE_Basic) {
78  CommandLine::ForCurrentProcess()->AppendSwitch(
79      switches::kEnableExperimentalExtensionApis);
80
81  ASSERT_TRUE(test_server()->Start());
82  ASSERT_TRUE(RunExtensionTest("omnibox")) << message_;
83
84  // The results depend on the TemplateURLModel being loaded. Make sure it is
85  // loaded so that the autocomplete results are consistent.
86  WaitForTemplateURLModelToLoad();
87
88  LocationBar* location_bar = GetLocationBar();
89  AutocompleteController* autocomplete_controller = GetAutocompleteController();
90
91  // Test that our extension's keyword is suggested to us when we partially type
92  // it.
93  {
94    autocomplete_controller->Start(L"keywor", std::wstring(),
95                                   true, false, false);
96
97    WaitForAutocompleteDone(autocomplete_controller);
98    EXPECT_TRUE(autocomplete_controller->done());
99    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
100    EXPECT_EQ(std::wstring(), location_bar->location_entry()->GetText());
101    EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
102
103    // First result should be to search for what was typed, second should be to
104    // enter "extension keyword" mode.
105    const AutocompleteResult& result = autocomplete_controller->result();
106    ASSERT_EQ(2U, result.size()) << AutocompleteResultAsString(result);
107    AutocompleteMatch match = result.match_at(0);
108    EXPECT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, match.type);
109    EXPECT_FALSE(match.deletable);
110
111    match = result.match_at(1);
112    ASSERT_TRUE(match.template_url);
113    EXPECT_TRUE(match.template_url->IsExtensionKeyword());
114    EXPECT_EQ(L"keyword", match.template_url->keyword());
115  }
116
117  // Test that our extension can send suggestions back to us.
118  {
119    autocomplete_controller->Start(L"keyword suggestio", std::wstring(),
120                                   true, false, false);
121
122    WaitForAutocompleteDone(autocomplete_controller);
123    EXPECT_TRUE(autocomplete_controller->done());
124
125    // First result should be to invoke the keyword with what we typed, 2-4
126    // should be to invoke with suggestions from the extension, and the last
127    // should be to search for what we typed.
128    const AutocompleteResult& result = autocomplete_controller->result();
129    ASSERT_EQ(5U, result.size()) << AutocompleteResultAsString(result);
130
131    ASSERT_TRUE(result.match_at(0).template_url);
132    EXPECT_EQ(L"keyword suggestio", result.match_at(0).fill_into_edit);
133    EXPECT_EQ(L"keyword suggestion1", result.match_at(1).fill_into_edit);
134    EXPECT_EQ(L"keyword suggestion2", result.match_at(2).fill_into_edit);
135    EXPECT_EQ(L"keyword suggestion3", result.match_at(3).fill_into_edit);
136
137    std::wstring description = L"Description with style: <match> [dim], none";
138    EXPECT_EQ(description, result.match_at(1).contents);
139    ASSERT_EQ(5u, result.match_at(1).contents_class.size());
140    EXPECT_EQ(0u,
141              result.match_at(1).contents_class[0].offset);
142    EXPECT_EQ(ACMatchClassification::NONE,
143              result.match_at(1).contents_class[0].style);
144    EXPECT_EQ(description.find('<'),
145              result.match_at(1).contents_class[1].offset);
146    EXPECT_EQ(ACMatchClassification::MATCH,
147              result.match_at(1).contents_class[1].style);
148    EXPECT_EQ(description.find('>'),
149              result.match_at(1).contents_class[2].offset);
150    EXPECT_EQ(ACMatchClassification::NONE,
151              result.match_at(1).contents_class[2].style);
152    EXPECT_EQ(description.find('['),
153              result.match_at(1).contents_class[3].offset);
154    EXPECT_EQ(ACMatchClassification::DIM,
155              result.match_at(1).contents_class[3].style);
156    EXPECT_EQ(description.find(']'),
157              result.match_at(1).contents_class[4].offset);
158    EXPECT_EQ(ACMatchClassification::NONE,
159              result.match_at(1).contents_class[4].style);
160
161    AutocompleteMatch match = result.match_at(4);
162    EXPECT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, match.type);
163    EXPECT_FALSE(match.deletable);
164  }
165
166  {
167    ResultCatcher catcher;
168    autocomplete_controller->Start(L"keyword command", std::wstring(),
169                                   true, false, false);
170    location_bar->AcceptInput();
171    EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
172  }
173}
174