1// Copyright (c) 2011 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 <stdio.h>
6
7#include "base/message_loop.h"
8#include "base/string16.h"
9#include "base/string_util.h"
10#include "base/time.h"
11#include "base/utf_string_conversions.h"
12#include "chrome/app/chrome_command_ids.h"
13#include "chrome/browser/autocomplete/autocomplete.h"
14#include "chrome/browser/autocomplete/autocomplete_edit.h"
15#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
16#include "chrome/browser/autocomplete/autocomplete_match.h"
17#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
18#include "chrome/browser/bookmarks/bookmark_model.h"
19#include "chrome/browser/history/history.h"
20#include "chrome/browser/profiles/profile.h"
21#include "chrome/browser/search_engines/template_url.h"
22#include "chrome/browser/search_engines/template_url_model.h"
23#include "chrome/browser/ui/browser.h"
24#include "chrome/browser/ui/browser_window.h"
25#include "chrome/browser/ui/omnibox/location_bar.h"
26#include "chrome/common/chrome_paths.h"
27#include "chrome/common/url_constants.h"
28#include "chrome/test/in_process_browser_test.h"
29#include "chrome/test/ui_test_utils.h"
30#include "content/browser/tab_contents/tab_contents.h"
31#include "content/common/notification_service.h"
32#include "net/base/mock_host_resolver.h"
33#include "ui/base/events.h"
34#include "ui/base/keycodes/keyboard_codes.h"
35
36#if defined(OS_LINUX)
37#include <gdk/gdk.h>
38#include <gtk/gtk.h>
39#endif
40
41#if defined(TOOLKIT_VIEWS)
42#include "views/controls/textfield/native_textfield_views.h"
43#include "views/events/event.h"
44#endif
45
46using base::Time;
47using base::TimeDelta;
48
49namespace {
50
51const char kSearchKeyword[] = "foo";
52const wchar_t kSearchKeywordKeys[] = {
53  ui::VKEY_F, ui::VKEY_O, ui::VKEY_O, 0
54};
55const char kSearchURL[] = "http://www.foo.com/search?q={searchTerms}";
56const char kSearchShortName[] = "foo";
57const char kSearchText[] = "abc";
58const wchar_t kSearchTextKeys[] = {
59  ui::VKEY_A, ui::VKEY_B, ui::VKEY_C, 0
60};
61const char kSearchTextURL[] = "http://www.foo.com/search?q=abc";
62const char kSearchSingleChar[] = "z";
63const wchar_t kSearchSingleCharKeys[] = { ui::VKEY_Z, 0 };
64const char kSearchSingleCharURL[] = "http://www.foo.com/search?q=z";
65
66const char kHistoryPageURL[] = "chrome://history/#q=abc";
67
68const char kDesiredTLDHostname[] = "www.bar.com";
69const wchar_t kDesiredTLDKeys[] = {
70  ui::VKEY_B, ui::VKEY_A, ui::VKEY_R, 0
71};
72
73const char kInlineAutocompleteText[] = "def";
74const wchar_t kInlineAutocompleteTextKeys[] = {
75  ui::VKEY_D, ui::VKEY_E, ui::VKEY_F, 0
76};
77
78// Hostnames that shall be blocked by host resolver.
79const char *kBlockedHostnames[] = {
80  "foo",
81  "*.foo.com",
82  "bar",
83  "*.bar.com",
84  "abc",
85  "*.abc.com",
86  "def",
87  "*.def.com",
88  "history",
89  "z"
90};
91
92const struct TestHistoryEntry {
93  const char* url;
94  const char* title;
95  const char* body;
96  int visit_count;
97  int typed_count;
98  bool starred;
99} kHistoryEntries[] = {
100  {"http://www.bar.com/1", "Page 1", kSearchText, 10, 10, false },
101  {"http://www.bar.com/2", "Page 2", kSearchText, 9, 9, false },
102  {"http://www.bar.com/3", "Page 3", kSearchText, 8, 8, false },
103  {"http://www.bar.com/4", "Page 4", kSearchText, 7, 7, false },
104  {"http://www.bar.com/5", "Page 5", kSearchText, 6, 6, false },
105  {"http://www.bar.com/6", "Page 6", kSearchText, 5, 5, false },
106  {"http://www.bar.com/7", "Page 7", kSearchText, 4, 4, false },
107  {"http://www.bar.com/8", "Page 8", kSearchText, 3, 3, false },
108  {"http://www.bar.com/9", "Page 9", kSearchText, 2, 2, false },
109
110  // To trigger inline autocomplete.
111  {"http://www.def.com", "Page def", kSearchText, 10000, 10000, true },
112};
113
114#if defined(OS_LINUX)
115// Returns the text stored in the PRIMARY clipboard.
116std::string GetPrimarySelectionText() {
117  GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
118  DCHECK(clipboard);
119
120  gchar* selection_text = gtk_clipboard_wait_for_text(clipboard);
121  std::string result(selection_text ? selection_text : "");
122  g_free(selection_text);
123  return result;
124}
125
126// Stores the given text to clipboard.
127void SetClipboardText(const char* text) {
128  GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
129  DCHECK(clipboard);
130
131  gtk_clipboard_set_text(clipboard, text, -1);
132}
133#endif
134
135#if defined(OS_MACOSX)
136const int kCtrlOrCmdMask = ui::EF_COMMAND_DOWN;
137#else
138const int kCtrlOrCmdMask = ui::EF_CONTROL_DOWN;
139#endif
140
141}  // namespace
142
143class AutocompleteEditViewTest : public InProcessBrowserTest,
144                                 public NotificationObserver {
145 protected:
146  AutocompleteEditViewTest() {
147    set_show_window(true);
148  }
149
150  virtual void SetUpOnMainThread() {
151    ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
152    ASSERT_NO_FATAL_FAILURE(SetupComponents());
153    browser()->FocusLocationBar();
154#if defined(TOOLKIT_VIEWS)
155    if (views::NativeTextfieldViews::IsTextfieldViewsEnabled())
156      return;
157#endif
158    ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(),
159                                             VIEW_ID_LOCATION_BAR));
160  }
161
162  static void GetAutocompleteEditViewForBrowser(
163      const Browser* browser,
164      AutocompleteEditView** edit_view) {
165    BrowserWindow* window = browser->window();
166    ASSERT_TRUE(window);
167    LocationBar* loc_bar = window->GetLocationBar();
168    ASSERT_TRUE(loc_bar);
169    *edit_view = loc_bar->location_entry();
170    ASSERT_TRUE(*edit_view);
171  }
172
173  void GetAutocompleteEditView(AutocompleteEditView** edit_view) {
174    GetAutocompleteEditViewForBrowser(browser(), edit_view);
175  }
176
177  static void SendKeyForBrowser(const Browser* browser,
178                                ui::KeyboardCode key,
179                                int modifiers) {
180    ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
181        browser, key,
182        (modifiers & ui::EF_CONTROL_DOWN) != 0,
183        (modifiers & ui::EF_SHIFT_DOWN) != 0,
184        (modifiers & ui::EF_ALT_DOWN) != 0,
185        (modifiers & ui::EF_COMMAND_DOWN) != 0));
186  }
187
188  void SendKey(ui::KeyboardCode key, int modifiers) {
189    SendKeyForBrowser(browser(), key, modifiers);
190  }
191
192  void SendKeySequence(const wchar_t* keys) {
193    for (; *keys; ++keys)
194      ASSERT_NO_FATAL_FAILURE(SendKey(static_cast<ui::KeyboardCode>(*keys), 0));
195  }
196
197  bool SendKeyAndWait(const Browser* browser,
198                      ui::KeyboardCode key,
199                      int modifiers,
200                      NotificationType type,
201                      const NotificationSource& source) WARN_UNUSED_RESULT {
202    return ui_test_utils::SendKeyPressAndWait(
203        browser, key,
204        (modifiers & ui::EF_CONTROL_DOWN) != 0,
205        (modifiers & ui::EF_SHIFT_DOWN) != 0,
206        (modifiers & ui::EF_ALT_DOWN) != 0,
207        (modifiers & ui::EF_COMMAND_DOWN) != 0,
208        type, source);
209  }
210
211  void WaitForTabOpenOrCloseForBrowser(const Browser* browser,
212                                       int expected_tab_count) {
213    int tab_count = browser->tab_count();
214    if (tab_count == expected_tab_count)
215      return;
216
217    NotificationRegistrar registrar;
218    registrar.Add(this,
219                  (tab_count < expected_tab_count ?
220                   NotificationType::TAB_PARENTED :
221                   NotificationType::TAB_CLOSED),
222                   NotificationService::AllSources());
223
224    while (!HasFailure() && browser->tab_count() != expected_tab_count)
225      ui_test_utils::RunMessageLoop();
226
227    ASSERT_EQ(expected_tab_count, browser->tab_count());
228  }
229
230  void WaitForTabOpenOrClose(int expected_tab_count) {
231    WaitForTabOpenOrCloseForBrowser(browser(), expected_tab_count);
232  }
233
234  void WaitForAutocompleteControllerDone() {
235    AutocompleteEditView* edit_view = NULL;
236    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
237
238    AutocompleteController* controller =
239        edit_view->model()->popup_model()->autocomplete_controller();
240    ASSERT_TRUE(controller);
241
242    if (controller->done())
243      return;
244
245    NotificationRegistrar registrar;
246    registrar.Add(this,
247                  NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_READY,
248                  Source<AutocompleteController>(controller));
249
250    while (!HasFailure() && !controller->done())
251      ui_test_utils::RunMessageLoop();
252
253    ASSERT_TRUE(controller->done());
254  }
255
256  void SetupSearchEngine() {
257    TemplateURLModel* model = browser()->profile()->GetTemplateURLModel();
258    ASSERT_TRUE(model);
259
260    if (!model->loaded()) {
261      NotificationRegistrar registrar;
262      registrar.Add(this, NotificationType::TEMPLATE_URL_MODEL_LOADED,
263                    Source<TemplateURLModel>(model));
264      model->Load();
265      ui_test_utils::RunMessageLoop();
266    }
267
268    ASSERT_TRUE(model->loaded());
269    // Remove built-in template urls, like google.com, bing.com etc., as they
270    // may appear as autocomplete suggests and interfere with our tests.
271    model->SetDefaultSearchProvider(NULL);
272    TemplateURLModel::TemplateURLVector builtins = model->GetTemplateURLs();
273    for (TemplateURLModel::TemplateURLVector::const_iterator
274         i = builtins.begin(); i != builtins.end(); ++i)
275      model->Remove(*i);
276
277    TemplateURL* template_url = new TemplateURL();
278    template_url->SetURL(kSearchURL, 0, 0);
279    template_url->set_keyword(UTF8ToUTF16(kSearchKeyword));
280    template_url->set_short_name(UTF8ToUTF16(kSearchShortName));
281
282    model->Add(template_url);
283    model->SetDefaultSearchProvider(template_url);
284  }
285
286  void AddHistoryEntry(const TestHistoryEntry& entry, const Time& time) {
287    Profile* profile = browser()->profile();
288    HistoryService* history_service =
289        profile->GetHistoryService(Profile::EXPLICIT_ACCESS);
290    ASSERT_TRUE(history_service);
291
292    if (!history_service->BackendLoaded()) {
293      NotificationRegistrar registrar;
294      registrar.Add(this, NotificationType::HISTORY_LOADED,
295                    Source<Profile>(profile));
296      ui_test_utils::RunMessageLoop();
297    }
298
299    BookmarkModel* bookmark_model = profile->GetBookmarkModel();
300    ASSERT_TRUE(bookmark_model);
301
302    if (!bookmark_model->IsLoaded()) {
303      NotificationRegistrar registrar;
304      registrar.Add(this, NotificationType::BOOKMARK_MODEL_LOADED,
305                    Source<Profile>(profile));
306      ui_test_utils::RunMessageLoop();
307    }
308
309    GURL url(entry.url);
310    // Add everything in order of time. We don't want to have a time that
311    // is "right now" or it will nondeterministically appear in the results.
312    history_service->AddPageWithDetails(url, UTF8ToUTF16(entry.title),
313                                        entry.visit_count,
314                                        entry.typed_count, time, false,
315                                        history::SOURCE_BROWSED);
316    history_service->SetPageContents(url, UTF8ToUTF16(entry.body));
317    if (entry.starred)
318      bookmark_model->SetURLStarred(url, string16(), true);
319  }
320
321  void SetupHistory() {
322    // Add enough history pages containing |kSearchText| to trigger
323    // open history page url in autocomplete result.
324    for (size_t i = 0; i < arraysize(kHistoryEntries); i++) {
325      // Add everything in order of time. We don't want to have a time that
326      // is "right now" or it will nondeterministically appear in the results.
327      Time t = Time::Now() - TimeDelta::FromHours(i + 1);
328      ASSERT_NO_FATAL_FAILURE(AddHistoryEntry(kHistoryEntries[i], t));
329    }
330  }
331
332  void SetupHostResolver() {
333    for (size_t i = 0; i < arraysize(kBlockedHostnames); ++i)
334      host_resolver()->AddSimulatedFailure(kBlockedHostnames[i]);
335  }
336
337  void SetupComponents() {
338    ASSERT_NO_FATAL_FAILURE(SetupHostResolver());
339    ASSERT_NO_FATAL_FAILURE(SetupSearchEngine());
340    ASSERT_NO_FATAL_FAILURE(SetupHistory());
341  }
342
343  virtual void Observe(NotificationType type,
344                       const NotificationSource& source,
345                       const NotificationDetails& details) {
346    switch (type.value) {
347      case NotificationType::TAB_PARENTED:
348      case NotificationType::TAB_CLOSED:
349      case NotificationType::TEMPLATE_URL_MODEL_LOADED:
350      case NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_READY:
351      case NotificationType::HISTORY_LOADED:
352      case NotificationType::BOOKMARK_MODEL_LOADED:
353        break;
354      default:
355        FAIL() << "Unexpected notification type";
356    }
357    MessageLoopForUI::current()->Quit();
358  }
359
360  void BrowserAcceleratorsTest() {
361    AutocompleteEditView* edit_view = NULL;
362    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
363
364    int tab_count = browser()->tab_count();
365
366    // Create a new Tab.
367    browser()->NewTab();
368    ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count + 1));
369
370    // Select the first Tab.
371    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_1, kCtrlOrCmdMask));
372    ASSERT_EQ(0, browser()->active_index());
373
374    browser()->FocusLocationBar();
375
376    // Select the second Tab.
377    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_2, kCtrlOrCmdMask));
378    ASSERT_EQ(1, browser()->active_index());
379
380    browser()->FocusLocationBar();
381
382    // Try ctrl-w to close a Tab.
383    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_W, kCtrlOrCmdMask));
384    ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count));
385
386    // Try ctrl-l to focus location bar.
387    edit_view->SetUserText(ASCIIToUTF16("Hello world"));
388    EXPECT_FALSE(edit_view->IsSelectAll());
389    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_L, kCtrlOrCmdMask));
390    EXPECT_TRUE(edit_view->IsSelectAll());
391
392    // Try editing the location bar text.
393    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RIGHT, 0));
394    EXPECT_FALSE(edit_view->IsSelectAll());
395    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_S, 0));
396    EXPECT_EQ(ASCIIToUTF16("Hello worlds"), edit_view->GetText());
397
398    // Try ctrl-x to cut text.
399#if defined(OS_MACOSX)
400    // Mac uses alt-left/right to select a word.
401    ASSERT_NO_FATAL_FAILURE(
402        SendKey(ui::VKEY_LEFT, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN));
403#else
404    ASSERT_NO_FATAL_FAILURE(
405        SendKey(ui::VKEY_LEFT, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN));
406#endif
407    EXPECT_FALSE(edit_view->IsSelectAll());
408    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_X, kCtrlOrCmdMask));
409    EXPECT_EQ(ASCIIToUTF16("Hello "), edit_view->GetText());
410
411#if !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
412    // Try alt-f4 to close the browser.
413    ASSERT_TRUE(SendKeyAndWait(
414        browser(), ui::VKEY_F4, ui::EF_ALT_DOWN,
415        NotificationType::BROWSER_CLOSED, Source<Browser>(browser())));
416#endif
417  }
418
419  void PopupAcceleratorsTest() {
420    // Create a popup.
421    Browser* popup = CreateBrowserForPopup(browser()->profile());
422    ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(popup));
423    AutocompleteEditView* edit_view = NULL;
424    ASSERT_NO_FATAL_FAILURE(
425        GetAutocompleteEditViewForBrowser(popup, &edit_view));
426    popup->FocusLocationBar();
427    EXPECT_TRUE(edit_view->IsSelectAll());
428
429#if !defined(OS_MACOSX)
430    // Try ctrl-w to close the popup.
431    // This piece of code doesn't work on Mac, because the Browser object won't
432    // be destroyed before finishing the current message loop iteration, thus
433    // No BROWSER_CLOSED notification will be sent.
434    ASSERT_TRUE(SendKeyAndWait(
435        popup, ui::VKEY_W, ui::EF_CONTROL_DOWN,
436        NotificationType::BROWSER_CLOSED, Source<Browser>(popup)));
437
438    // Create another popup.
439    popup = CreateBrowserForPopup(browser()->profile());
440    ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(popup));
441    ASSERT_NO_FATAL_FAILURE(
442        GetAutocompleteEditViewForBrowser(popup, &edit_view));
443#endif
444
445    // Set the edit text to "Hello world".
446    edit_view->SetUserText(ASCIIToUTF16("Hello world"));
447    popup->FocusLocationBar();
448    EXPECT_TRUE(edit_view->IsSelectAll());
449
450    // Try editing the location bar text -- should be disallowed.
451    ASSERT_NO_FATAL_FAILURE(SendKeyForBrowser(popup, ui::VKEY_S, 0));
452    EXPECT_EQ(ASCIIToUTF16("Hello world"), edit_view->GetText());
453    EXPECT_TRUE(edit_view->IsSelectAll());
454
455    ASSERT_NO_FATAL_FAILURE(
456        SendKeyForBrowser(popup, ui::VKEY_X, kCtrlOrCmdMask));
457    EXPECT_EQ(ASCIIToUTF16("Hello world"), edit_view->GetText());
458    EXPECT_TRUE(edit_view->IsSelectAll());
459
460#if !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
461    // Try alt-f4 to close the popup.
462    ASSERT_TRUE(SendKeyAndWait(
463        popup, ui::VKEY_F4, ui::EF_ALT_DOWN,
464        NotificationType::BROWSER_CLOSED, Source<Browser>(popup)));
465#endif
466  }
467
468  void BackspaceInKeywordModeTest() {
469    AutocompleteEditView* edit_view = NULL;
470    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
471
472    // Trigger keyword hint mode.
473    ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
474    ASSERT_TRUE(edit_view->model()->is_keyword_hint());
475    ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword()));
476
477    // Trigger keyword mode.
478    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
479    ASSERT_FALSE(edit_view->model()->is_keyword_hint());
480    ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword()));
481
482    // Backspace without search text should bring back keyword hint mode.
483    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
484    ASSERT_TRUE(edit_view->model()->is_keyword_hint());
485    ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword()));
486
487    // Trigger keyword mode again.
488    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
489    ASSERT_FALSE(edit_view->model()->is_keyword_hint());
490    ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword()));
491
492    // Input something as search text.
493    ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
494
495    // Should stay in keyword mode while deleting search text by pressing
496    // backspace.
497    for (size_t i = 0; i < arraysize(kSearchText) - 1; ++i) {
498      ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
499      ASSERT_FALSE(edit_view->model()->is_keyword_hint());
500      ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword()));
501    }
502
503    // Input something as search text.
504    ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
505
506    // Move cursor to the beginning of the search text.
507#if defined(OS_MACOSX)
508    // Home doesn't work on Mac trybot.
509    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, ui::EF_CONTROL_DOWN));
510#else
511    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_HOME, 0));
512#endif
513    // Backspace at the beginning of the search text shall turn off
514    // the keyword mode.
515    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
516    ASSERT_FALSE(edit_view->model()->is_keyword_hint());
517    ASSERT_EQ(string16(), edit_view->model()->keyword());
518    ASSERT_EQ(std::string(kSearchKeyword) + kSearchText,
519              UTF16ToUTF8(edit_view->GetText()));
520  }
521
522  void EscapeTest() {
523    ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIHistoryURL));
524    browser()->FocusLocationBar();
525
526    AutocompleteEditView* edit_view = NULL;
527    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
528
529    string16 old_text = edit_view->GetText();
530    EXPECT_FALSE(old_text.empty());
531    EXPECT_TRUE(edit_view->IsSelectAll());
532
533    // Delete all text in omnibox.
534    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
535    EXPECT_TRUE(edit_view->GetText().empty());
536
537    // Escape shall revert the text in omnibox.
538    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_ESCAPE, 0));
539    EXPECT_EQ(old_text, edit_view->GetText());
540    EXPECT_TRUE(edit_view->IsSelectAll());
541  }
542
543  void DesiredTLDTest() {
544    AutocompleteEditView* edit_view = NULL;
545    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
546    AutocompletePopupModel* popup_model = edit_view->model()->popup_model();
547    ASSERT_TRUE(popup_model);
548
549    // Test ctrl-Enter.
550    ASSERT_NO_FATAL_FAILURE(SendKeySequence(kDesiredTLDKeys));
551    ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
552    ASSERT_TRUE(popup_model->IsOpen());
553    // ctrl-Enter triggers desired_tld feature, thus www.bar.com shall be
554    // opened.
555    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, ui::EF_CONTROL_DOWN));
556
557    GURL url = browser()->GetSelectedTabContents()->GetURL();
558    EXPECT_STREQ(kDesiredTLDHostname, url.host().c_str());
559  }
560
561  void AltEnterTest() {
562    AutocompleteEditView* edit_view = NULL;
563    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
564
565    edit_view->SetUserText(ASCIIToUTF16(chrome::kChromeUIHistoryURL));
566    int tab_count = browser()->tab_count();
567    // alt-Enter opens a new tab.
568    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, ui::EF_ALT_DOWN));
569    ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count + 1));
570  }
571
572  void EnterToSearchTest() {
573    AutocompleteEditView* edit_view = NULL;
574    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
575    AutocompletePopupModel* popup_model = edit_view->model()->popup_model();
576    ASSERT_TRUE(popup_model);
577
578    // Test Enter to search.
579    ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
580    ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
581    ASSERT_TRUE(popup_model->IsOpen());
582
583    // Check if the default match result is Search Primary Provider.
584    ASSERT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED,
585              popup_model->result().default_match()->type);
586
587    // Open the default match.
588    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, 0));
589    GURL url = browser()->GetSelectedTabContents()->GetURL();
590    EXPECT_STREQ(kSearchTextURL, url.spec().c_str());
591
592    // Test that entering a single character then Enter performs a search.
593    browser()->FocusLocationBar();
594    EXPECT_TRUE(edit_view->IsSelectAll());
595    ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchSingleCharKeys));
596    ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
597    ASSERT_TRUE(popup_model->IsOpen());
598    EXPECT_EQ(kSearchSingleChar, UTF16ToUTF8(edit_view->GetText()));
599
600    // Check if the default match result is Search Primary Provider.
601    ASSERT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED,
602              popup_model->result().default_match()->type);
603
604    // Open the default match.
605    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, 0));
606    url = browser()->GetSelectedTabContents()->GetURL();
607    EXPECT_STREQ(kSearchSingleCharURL, url.spec().c_str());
608  }
609
610  void EscapeToDefaultMatchTest() {
611    AutocompleteEditView* edit_view = NULL;
612    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
613    AutocompletePopupModel* popup_model = edit_view->model()->popup_model();
614    ASSERT_TRUE(popup_model);
615
616    // Input something to trigger inline autocomplete.
617    ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys));
618    ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
619    ASSERT_TRUE(popup_model->IsOpen());
620
621    string16 old_text = edit_view->GetText();
622
623    // Make sure inline autocomplete is triggerred.
624    EXPECT_GT(old_text.length(), arraysize(kInlineAutocompleteText) - 1);
625
626    size_t old_selected_line = popup_model->selected_line();
627    EXPECT_EQ(0U, old_selected_line);
628
629    // Move to another line with different text.
630    size_t size = popup_model->result().size();
631    while (popup_model->selected_line() < size - 1) {
632      ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DOWN, 0));
633      ASSERT_NE(old_selected_line, popup_model->selected_line());
634      if (old_text != edit_view->GetText())
635        break;
636    }
637
638    EXPECT_NE(old_text, edit_view->GetText());
639
640    // Escape shall revert back to the default match item.
641    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_ESCAPE, 0));
642    EXPECT_EQ(old_text, edit_view->GetText());
643    EXPECT_EQ(old_selected_line, popup_model->selected_line());
644  }
645
646  void BasicTextOperationsTest() {
647    ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutBlankURL));
648    browser()->FocusLocationBar();
649
650    AutocompleteEditView* edit_view = NULL;
651    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
652
653    string16 old_text = edit_view->GetText();
654    EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL), old_text);
655    EXPECT_TRUE(edit_view->IsSelectAll());
656
657    string16::size_type start, end;
658    edit_view->GetSelectionBounds(&start, &end);
659    EXPECT_EQ(0U, start);
660    EXPECT_EQ(old_text.size(), end);
661
662    // Move the cursor to the end.
663#if defined(OS_MACOSX)
664    // End doesn't work on Mac trybot.
665    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_E, ui::EF_CONTROL_DOWN));
666#else
667    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_END, 0));
668#endif
669    EXPECT_FALSE(edit_view->IsSelectAll());
670
671    // Make sure the cursor is placed correctly.
672    edit_view->GetSelectionBounds(&start, &end);
673    EXPECT_EQ(old_text.size(), start);
674    EXPECT_EQ(old_text.size(), end);
675
676    // Insert one character at the end. Make sure we won't insert
677    // anything after the special ZWS mark used in gtk implementation.
678    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, 0));
679    EXPECT_EQ(old_text + char16('a'), edit_view->GetText());
680
681    // Delete one character from the end. Make sure we won't delete the special
682    // ZWS mark used in gtk implementation.
683    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
684    EXPECT_EQ(old_text, edit_view->GetText());
685
686    edit_view->SelectAll(true);
687    EXPECT_TRUE(edit_view->IsSelectAll());
688    edit_view->GetSelectionBounds(&start, &end);
689    EXPECT_EQ(0U, start);
690    EXPECT_EQ(old_text.size(), end);
691
692    // Delete the content
693    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DELETE, 0));
694    EXPECT_TRUE(edit_view->IsSelectAll());
695    edit_view->GetSelectionBounds(&start, &end);
696    EXPECT_EQ(0U, start);
697    EXPECT_EQ(0U, end);
698    EXPECT_TRUE(edit_view->GetText().empty());
699
700    // Check if RevertAll() can set text and cursor correctly.
701    edit_view->RevertAll();
702    EXPECT_FALSE(edit_view->IsSelectAll());
703    EXPECT_EQ(old_text, edit_view->GetText());
704    edit_view->GetSelectionBounds(&start, &end);
705    EXPECT_EQ(old_text.size(), start);
706    EXPECT_EQ(old_text.size(), end);
707  }
708
709  void AcceptKeywordBySpaceTest() {
710    AutocompleteEditView* edit_view = NULL;
711    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
712
713    string16 text = UTF8ToUTF16(kSearchKeyword);
714
715    // Trigger keyword hint mode.
716    ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
717    ASSERT_TRUE(edit_view->model()->is_keyword_hint());
718    ASSERT_EQ(text, edit_view->model()->keyword());
719    ASSERT_EQ(text, edit_view->GetText());
720
721    // Trigger keyword mode by space.
722    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
723    ASSERT_FALSE(edit_view->model()->is_keyword_hint());
724    ASSERT_EQ(text, edit_view->model()->keyword());
725    ASSERT_TRUE(edit_view->GetText().empty());
726
727    // Revert to keyword hint mode.
728    edit_view->model()->ClearKeyword(string16());
729    ASSERT_TRUE(edit_view->model()->is_keyword_hint());
730    ASSERT_EQ(text, edit_view->model()->keyword());
731    ASSERT_EQ(text, edit_view->GetText());
732
733    // Keyword should also be accepted by typing an ideographic space.
734    edit_view->OnBeforePossibleChange();
735    edit_view->SetWindowTextAndCaretPos(text + WideToUTF16(L"\x3000"),
736                                        text.length() + 1);
737    edit_view->OnAfterPossibleChange();
738    ASSERT_FALSE(edit_view->model()->is_keyword_hint());
739    ASSERT_EQ(text, edit_view->model()->keyword());
740    ASSERT_TRUE(edit_view->GetText().empty());
741
742    // Revert to keyword hint mode.
743    edit_view->model()->ClearKeyword(string16());
744    ASSERT_TRUE(edit_view->model()->is_keyword_hint());
745    ASSERT_EQ(text, edit_view->model()->keyword());
746    ASSERT_EQ(text, edit_view->GetText());
747
748    // Keyword shouldn't be accepted by pasting.
749    // Simulate pasting a whitespace to the end of content.
750    edit_view->OnBeforePossibleChange();
751    edit_view->model()->on_paste();
752    edit_view->SetWindowTextAndCaretPos(text + char16(' '), text.length() + 1);
753    edit_view->OnAfterPossibleChange();
754    // Should be still in keyword hint mode.
755    ASSERT_TRUE(edit_view->model()->is_keyword_hint());
756    ASSERT_EQ(text, edit_view->model()->keyword());
757    ASSERT_EQ(text + char16(' '), edit_view->GetText());
758
759    // Keyword shouldn't be accepted by pressing space with a trailing
760    // whitespace.
761    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
762    ASSERT_TRUE(edit_view->model()->is_keyword_hint());
763    ASSERT_EQ(text, edit_view->model()->keyword());
764    ASSERT_EQ(text + ASCIIToUTF16("  "), edit_view->GetText());
765
766    // Keyword shouldn't be accepted by deleting the trailing space.
767    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
768    ASSERT_TRUE(edit_view->model()->is_keyword_hint());
769    ASSERT_EQ(text, edit_view->model()->keyword());
770    ASSERT_EQ(text + char16(' '), edit_view->GetText());
771
772    // Keyword shouldn't be accepted by pressing space before a trailing space.
773    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
774    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
775    ASSERT_TRUE(edit_view->model()->is_keyword_hint());
776    ASSERT_EQ(text, edit_view->model()->keyword());
777    ASSERT_EQ(text + ASCIIToUTF16("  "), edit_view->GetText());
778
779    // Keyword should be accepted by pressing space in the middle of context and
780    // just after the keyword.
781    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
782    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, 0));
783    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
784    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
785    ASSERT_FALSE(edit_view->model()->is_keyword_hint());
786    ASSERT_EQ(text, edit_view->model()->keyword());
787    ASSERT_EQ(ASCIIToUTF16("a "), edit_view->GetText());
788
789    // Keyword shouldn't be accepted by pasting "foo bar".
790    edit_view->SetUserText(string16());
791    ASSERT_FALSE(edit_view->model()->is_keyword_hint());
792    ASSERT_TRUE(edit_view->model()->keyword().empty());
793
794    edit_view->OnBeforePossibleChange();
795    edit_view->model()->on_paste();
796    edit_view->SetWindowTextAndCaretPos(text + ASCIIToUTF16(" bar"),
797                                        text.length() + 4);
798    edit_view->OnAfterPossibleChange();
799    ASSERT_FALSE(edit_view->model()->is_keyword_hint());
800    ASSERT_TRUE(edit_view->model()->keyword().empty());
801    ASSERT_EQ(text + ASCIIToUTF16(" bar"), edit_view->GetText());
802
803    // Keyword shouldn't be accepted for case like: "foo b|ar" -> "foo b |ar".
804    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
805    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
806    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
807    ASSERT_FALSE(edit_view->model()->is_keyword_hint());
808    ASSERT_TRUE(edit_view->model()->keyword().empty());
809    ASSERT_EQ(text + ASCIIToUTF16(" b ar"), edit_view->GetText());
810
811    // Keyword could be accepted by pressing space with a selected range at the
812    // end of text.
813    edit_view->OnBeforePossibleChange();
814    edit_view->OnInlineAutocompleteTextMaybeChanged(
815        text + ASCIIToUTF16("  "), text.length());
816    edit_view->OnAfterPossibleChange();
817    ASSERT_TRUE(edit_view->model()->is_keyword_hint());
818    ASSERT_EQ(text, edit_view->model()->keyword());
819    ASSERT_EQ(text + ASCIIToUTF16("  "), edit_view->GetText());
820
821    string16::size_type start, end;
822    edit_view->GetSelectionBounds(&start, &end);
823    ASSERT_NE(start, end);
824    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
825    ASSERT_FALSE(edit_view->model()->is_keyword_hint());
826    ASSERT_EQ(text, edit_view->model()->keyword());
827    ASSERT_EQ(string16(), edit_view->GetText());
828
829    edit_view->SetUserText(string16());
830
831    // Space should accept keyword even when inline autocomplete is available.
832    const TestHistoryEntry kHistoryFoobar = {
833      "http://www.foobar.com", "Page foobar", kSearchText, 10000, 10000, true
834    };
835
836    // Add a history entry to trigger inline autocomplete when typing "foo".
837    ASSERT_NO_FATAL_FAILURE(
838        AddHistoryEntry(kHistoryFoobar, Time::Now() - TimeDelta::FromHours(1)));
839
840    // Type "foo" to trigger inline autocomplete.
841    ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
842    ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
843    ASSERT_TRUE(edit_view->model()->popup_model()->IsOpen());
844    ASSERT_NE(text, edit_view->GetText());
845
846    // Keyword hint shouldn't be visible.
847    ASSERT_FALSE(edit_view->model()->is_keyword_hint());
848    ASSERT_TRUE(edit_view->model()->keyword().empty());
849
850    // Trigger keyword mode by space.
851    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
852    ASSERT_FALSE(edit_view->model()->is_keyword_hint());
853    ASSERT_EQ(text, edit_view->model()->keyword());
854    ASSERT_TRUE(edit_view->GetText().empty());
855  }
856
857  void NonSubstitutingKeywordTest() {
858    AutocompleteEditView* edit_view = NULL;
859    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
860    AutocompletePopupModel* popup_model = edit_view->model()->popup_model();
861    ASSERT_TRUE(popup_model);
862
863    TemplateURLModel* template_url_model =
864        browser()->profile()->GetTemplateURLModel();
865
866    // Add a non-default substituting keyword.
867    TemplateURL* template_url = new TemplateURL();
868    template_url->SetURL("http://abc.com/{searchTerms}", 0, 0);
869    template_url->set_keyword(UTF8ToUTF16(kSearchText));
870    template_url->set_short_name(UTF8ToUTF16("Search abc"));
871    template_url_model->Add(template_url);
872
873    edit_view->SetUserText(string16());
874
875    // Non-default substituting keyword shouldn't be matched by default.
876    ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
877    ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
878    ASSERT_TRUE(popup_model->IsOpen());
879
880    // Check if the default match result is Search Primary Provider.
881    ASSERT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED,
882              popup_model->result().default_match()->type);
883    ASSERT_EQ(kSearchTextURL,
884              popup_model->result().default_match()->destination_url.spec());
885
886    edit_view->SetUserText(string16());
887    ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
888    ASSERT_FALSE(popup_model->IsOpen());
889
890    // Try a non-substituting keyword.
891    template_url_model->Remove(template_url);
892    template_url = new TemplateURL();
893    template_url->SetURL("http://abc.com/", 0, 0);
894    template_url->set_keyword(UTF8ToUTF16(kSearchText));
895    template_url->set_short_name(UTF8ToUTF16("abc"));
896    template_url_model->Add(template_url);
897
898    // We always allow exact matches for non-substituting keywords.
899    ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
900    ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
901    ASSERT_TRUE(popup_model->IsOpen());
902    ASSERT_EQ(AutocompleteMatch::HISTORY_KEYWORD,
903              popup_model->result().default_match()->type);
904    ASSERT_EQ("http://abc.com/",
905              popup_model->result().default_match()->destination_url.spec());
906  }
907
908  void DeleteItemTest() {
909    // Disable the search provider, to make sure the popup contains only history
910    // items.
911    TemplateURLModel* model = browser()->profile()->GetTemplateURLModel();
912    model->SetDefaultSearchProvider(NULL);
913
914    ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutBlankURL));
915    browser()->FocusLocationBar();
916
917    AutocompleteEditView* edit_view = NULL;
918    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
919
920    AutocompletePopupModel* popup_model = edit_view->model()->popup_model();
921    ASSERT_TRUE(popup_model);
922
923    string16 old_text = edit_view->GetText();
924
925    // Input something that can match history items.
926    edit_view->SetUserText(ASCIIToUTF16("bar"));
927    ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
928    ASSERT_TRUE(popup_model->IsOpen());
929
930    // Delete the inline autocomplete part.
931    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DELETE, 0));
932    ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
933    ASSERT_TRUE(popup_model->IsOpen());
934    ASSERT_GE(popup_model->result().size(), 3U);
935
936    string16 user_text = edit_view->GetText();
937    ASSERT_EQ(ASCIIToUTF16("bar"), user_text);
938    edit_view->SelectAll(true);
939    ASSERT_TRUE(edit_view->IsSelectAll());
940
941    // The first item should be the default match.
942    size_t default_line = popup_model->selected_line();
943    std::string default_url =
944        popup_model->result().match_at(default_line).destination_url.spec();
945
946    // Move down.
947    edit_view->model()->OnUpOrDownKeyPressed(1);
948    ASSERT_EQ(default_line + 1, popup_model->selected_line());
949    string16 selected_text =
950        popup_model->result().match_at(default_line + 1).fill_into_edit;
951    // Temporary text is shown.
952    ASSERT_EQ(selected_text, edit_view->GetText());
953    ASSERT_FALSE(edit_view->IsSelectAll());
954
955    // Delete the item.
956    popup_model->TryDeletingCurrentItem();
957    ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
958    // The selected line shouldn't be changed, because we have more than two
959    // items.
960    ASSERT_EQ(default_line + 1, popup_model->selected_line());
961    // Make sure the item is really deleted.
962    ASSERT_NE(selected_text,
963              popup_model->result().match_at(default_line + 1).fill_into_edit);
964    selected_text =
965        popup_model->result().match_at(default_line + 1).fill_into_edit;
966    // New temporary text is shown.
967    ASSERT_EQ(selected_text, edit_view->GetText());
968
969    // Revert to the default match.
970    ASSERT_TRUE(edit_view->model()->OnEscapeKeyPressed());
971    ASSERT_EQ(default_line, popup_model->selected_line());
972    ASSERT_EQ(user_text, edit_view->GetText());
973    ASSERT_TRUE(edit_view->IsSelectAll());
974
975    // Move down and up to select the default match as temporary text.
976    edit_view->model()->OnUpOrDownKeyPressed(1);
977    ASSERT_EQ(default_line + 1, popup_model->selected_line());
978    edit_view->model()->OnUpOrDownKeyPressed(-1);
979    ASSERT_EQ(default_line, popup_model->selected_line());
980
981    selected_text = popup_model->result().match_at(default_line).fill_into_edit;
982    // New temporary text is shown.
983    ASSERT_EQ(selected_text, edit_view->GetText());
984    ASSERT_FALSE(edit_view->IsSelectAll());
985
986    // Delete the default item.
987    popup_model->TryDeletingCurrentItem();
988    ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
989    // The selected line shouldn't be changed, but the default item should have
990    // been changed.
991    ASSERT_EQ(default_line, popup_model->selected_line());
992    // Make sure the item is really deleted.
993    ASSERT_NE(selected_text,
994              popup_model->result().match_at(default_line).fill_into_edit);
995    selected_text =
996        popup_model->result().match_at(default_line).fill_into_edit;
997    // New temporary text is shown.
998    ASSERT_EQ(selected_text, edit_view->GetText());
999
1000    // As the current selected item is the new default item, pressing Escape key
1001    // should revert all directly.
1002    ASSERT_TRUE(edit_view->model()->OnEscapeKeyPressed());
1003    ASSERT_EQ(old_text, edit_view->GetText());
1004    ASSERT_TRUE(edit_view->IsSelectAll());
1005  }
1006
1007  void TabMoveCursorToEndTest() {
1008    AutocompleteEditView* edit_view = NULL;
1009    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
1010
1011    edit_view->SetUserText(ASCIIToUTF16("Hello world"));
1012
1013    // Move cursor to the beginning.
1014#if defined(OS_MACOSX)
1015    // Home doesn't work on Mac trybot.
1016    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, ui::EF_CONTROL_DOWN));
1017#else
1018    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_HOME, 0));
1019#endif
1020
1021    string16::size_type start, end;
1022    edit_view->GetSelectionBounds(&start, &end);
1023    EXPECT_EQ(0U, start);
1024    EXPECT_EQ(0U, end);
1025
1026    // Pressing tab should move cursor to the end.
1027    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
1028
1029    edit_view->GetSelectionBounds(&start, &end);
1030    EXPECT_EQ(edit_view->GetText().size(), start);
1031    EXPECT_EQ(edit_view->GetText().size(), end);
1032
1033    // The location bar should still have focus.
1034    ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_LOCATION_BAR));
1035
1036    // Select all text.
1037    edit_view->SelectAll(true);
1038    EXPECT_TRUE(edit_view->IsSelectAll());
1039    edit_view->GetSelectionBounds(&start, &end);
1040    EXPECT_EQ(0U, start);
1041    EXPECT_EQ(edit_view->GetText().size(), end);
1042
1043    // Pressing tab should move cursor to the end.
1044    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
1045
1046    edit_view->GetSelectionBounds(&start, &end);
1047    EXPECT_EQ(edit_view->GetText().size(), start);
1048    EXPECT_EQ(edit_view->GetText().size(), end);
1049
1050    // The location bar should still have focus.
1051    ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_LOCATION_BAR));
1052
1053    // Pressing tab when cursor is at the end should change focus.
1054    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
1055
1056    ASSERT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_LOCATION_BAR));
1057  }
1058
1059  void PersistKeywordModeOnTabSwitch() {
1060    AutocompleteEditView* edit_view = NULL;
1061    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
1062
1063    // Trigger keyword hint mode.
1064    ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
1065    ASSERT_TRUE(edit_view->model()->is_keyword_hint());
1066    ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword()));
1067
1068    // Trigger keyword mode.
1069    ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
1070    ASSERT_FALSE(edit_view->model()->is_keyword_hint());
1071    ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword()));
1072
1073    // Input something as search text.
1074    ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
1075
1076    // Create a new tab.
1077    browser()->NewTab();
1078
1079    // Switch back to the first tab.
1080    browser()->ActivateTabAt(0, true);
1081
1082    // Make sure we're still in keyword mode.
1083    ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword()));
1084  }
1085
1086  void CtrlKeyPressedWithInlineAutocompleteTest() {
1087    AutocompleteEditView* edit_view = NULL;
1088    ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
1089    AutocompletePopupModel* popup_model = edit_view->model()->popup_model();
1090    ASSERT_TRUE(popup_model);
1091
1092    // Input something to trigger inline autocomplete.
1093    ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys));
1094    ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1095    ASSERT_TRUE(popup_model->IsOpen());
1096
1097    string16 old_text = edit_view->GetText();
1098
1099    // Make sure inline autocomplete is triggerred.
1100    EXPECT_GT(old_text.length(), arraysize(kInlineAutocompleteText) - 1);
1101
1102    // Press ctrl key.
1103    edit_view->model()->OnControlKeyChanged(true);
1104
1105    // Inline autocomplete should still be there.
1106    EXPECT_EQ(old_text, edit_view->GetText());
1107  }
1108
1109};
1110
1111// Test if ctrl-* accelerators are workable in omnibox.
1112// See http://crbug.com/19193: omnibox blocks ctrl-* commands
1113//
1114// Flaky on interactive tests (dbg), http://crbug.com/69433
1115IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, FLAKY_BrowserAccelerators) {
1116  BrowserAcceleratorsTest();
1117}
1118
1119// Flakily fails and times out on Win only.  http://crbug.com/69941
1120#if defined(OS_WIN)
1121#define MAYBE_PopupAccelerators DISABLED_PopupAccelerators
1122#else
1123#define MAYBE_PopupAccelerators PopupAccelerators
1124#endif
1125
1126IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, MAYBE_PopupAccelerators) {
1127  PopupAcceleratorsTest();
1128}
1129
1130IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, BackspaceInKeywordMode) {
1131  BackspaceInKeywordModeTest();
1132}
1133
1134IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, Escape) {
1135  EscapeTest();
1136}
1137
1138IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, DesiredTLD) {
1139  DesiredTLDTest();
1140}
1141
1142IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, AltEnter) {
1143  AltEnterTest();
1144}
1145
1146IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, EnterToSearch) {
1147  EnterToSearchTest();
1148}
1149
1150IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, EscapeToDefaultMatch) {
1151  EscapeToDefaultMatchTest();
1152}
1153
1154IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, BasicTextOperations) {
1155  BasicTextOperationsTest();
1156}
1157
1158IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, AcceptKeywordBySpace) {
1159  AcceptKeywordBySpaceTest();
1160}
1161
1162IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, NonSubstitutingKeywordTest) {
1163  NonSubstitutingKeywordTest();
1164}
1165
1166IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, DeleteItem) {
1167  DeleteItemTest();
1168}
1169
1170IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, TabMoveCursorToEnd) {
1171  TabMoveCursorToEndTest();
1172}
1173
1174IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,
1175                       PersistKeywordModeOnTabSwitch) {
1176  PersistKeywordModeOnTabSwitch();
1177}
1178
1179IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,
1180                       CtrlKeyPressedWithInlineAutocompleteTest) {
1181  CtrlKeyPressedWithInlineAutocompleteTest();
1182}
1183
1184#if defined(OS_LINUX)
1185// TODO(oshima): enable these tests for views-implmentation when
1186// these featuers are supported.
1187
1188IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, UndoRedoLinux) {
1189  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutBlankURL));
1190  browser()->FocusLocationBar();
1191
1192  AutocompleteEditView* edit_view = NULL;
1193  ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
1194
1195  string16 old_text = edit_view->GetText();
1196  EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL), old_text);
1197  EXPECT_TRUE(edit_view->IsSelectAll());
1198
1199  // Undo should clear the omnibox.
1200  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN));
1201  EXPECT_TRUE(edit_view->GetText().empty());
1202
1203  // Nothing should happen if undo again.
1204  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN));
1205  EXPECT_TRUE(edit_view->GetText().empty());
1206
1207  // Redo should restore the original text.
1208  ASSERT_NO_FATAL_FAILURE(
1209      SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN));
1210  EXPECT_EQ(old_text, edit_view->GetText());
1211
1212  // Looks like the undo manager doesn't support restoring selection.
1213  EXPECT_FALSE(edit_view->IsSelectAll());
1214
1215  // The cursor should be at the end.
1216  string16::size_type start, end;
1217  edit_view->GetSelectionBounds(&start, &end);
1218  EXPECT_EQ(old_text.size(), start);
1219  EXPECT_EQ(old_text.size(), end);
1220
1221  // Delete two characters.
1222  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
1223  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
1224  EXPECT_EQ(old_text.substr(0, old_text.size() - 2), edit_view->GetText());
1225
1226  // Undo delete.
1227  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN));
1228  EXPECT_EQ(old_text, edit_view->GetText());
1229
1230  // Redo delete.
1231  ASSERT_NO_FATAL_FAILURE(
1232      SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN));
1233  EXPECT_EQ(old_text.substr(0, old_text.size() - 2), edit_view->GetText());
1234
1235  // Delete everything.
1236  edit_view->SelectAll(true);
1237  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
1238  EXPECT_TRUE(edit_view->GetText().empty());
1239
1240  // Undo delete everything.
1241  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN));
1242  EXPECT_EQ(old_text.substr(0, old_text.size() - 2), edit_view->GetText());
1243
1244  // Undo delete two characters.
1245  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN));
1246  EXPECT_EQ(old_text, edit_view->GetText());
1247
1248  // Undo again.
1249  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN));
1250  EXPECT_TRUE(edit_view->GetText().empty());
1251}
1252
1253// See http://crbug.com/63860
1254IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, PrimarySelection) {
1255  AutocompleteEditView* edit_view = NULL;
1256  ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
1257  edit_view->SetUserText(ASCIIToUTF16("Hello world"));
1258  EXPECT_FALSE(edit_view->IsSelectAll());
1259
1260  // Move the cursor to the end.
1261  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_END, 0));
1262
1263  // Select all text by pressing Shift+Home
1264  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_HOME, ui::EF_SHIFT_DOWN));
1265  EXPECT_TRUE(edit_view->IsSelectAll());
1266
1267  // The selected content should be saved to the PRIMARY clipboard.
1268  EXPECT_EQ("Hello world", GetPrimarySelectionText());
1269
1270  // Move the cursor to the end.
1271  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_END, 0));
1272  EXPECT_FALSE(edit_view->IsSelectAll());
1273
1274  // The content in the PRIMARY clipboard should not be cleared.
1275  EXPECT_EQ("Hello world", GetPrimarySelectionText());
1276}
1277
1278// See http://crosbug.com/10306
1279IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,
1280                       BackspaceDeleteHalfWidthKatakana) {
1281  AutocompleteEditView* edit_view = NULL;
1282  ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
1283  // Insert text: ダ
1284  edit_view->SetUserText(UTF8ToUTF16("\357\276\200\357\276\236"));
1285
1286  // Move the cursor to the end.
1287  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_END, 0));
1288
1289  // Backspace should delete one character.
1290  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
1291  EXPECT_EQ(UTF8ToUTF16("\357\276\200"), edit_view->GetText());
1292}
1293
1294// http://crbug.com/12316
1295IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, PasteReplacingAll) {
1296  AutocompleteEditView* edit_view = NULL;
1297  ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view));
1298  AutocompletePopupModel* popup_model = edit_view->model()->popup_model();
1299  ASSERT_TRUE(popup_model);
1300
1301  SetClipboardText(kSearchText);
1302
1303  // Paste text.
1304  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_V, ui::EF_CONTROL_DOWN));
1305  ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1306  ASSERT_TRUE(popup_model->IsOpen());
1307
1308  // Inline autocomplete shouldn't be triggered.
1309  ASSERT_EQ(ASCIIToUTF16("abc"), edit_view->GetText());
1310}
1311#endif
1312
1313#if defined(TOOLKIT_VIEWS)
1314class AutocompleteEditViewViewsTest : public AutocompleteEditViewTest {
1315 public:
1316  AutocompleteEditViewViewsTest() {
1317    views::NativeTextfieldViews::SetEnableTextfieldViews(true);
1318  }
1319};
1320
1321IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,
1322                       FLAKY_BrowserAccelerators) {
1323  BrowserAcceleratorsTest();
1324}
1325
1326IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, MAYBE_PopupAccelerators) {
1327  PopupAcceleratorsTest();
1328}
1329
1330IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, BackspaceInKeywordMode) {
1331  BackspaceInKeywordModeTest();
1332}
1333
1334IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, Escape) {
1335  EscapeTest();
1336}
1337
1338IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, DesiredTLD) {
1339  DesiredTLDTest();
1340}
1341
1342IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, AltEnter) {
1343  AltEnterTest();
1344}
1345
1346IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, EnterToSearch) {
1347  EnterToSearchTest();
1348}
1349
1350IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, EscapeToDefaultMatch) {
1351  EscapeToDefaultMatchTest();
1352}
1353
1354IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, BasicTextOperations) {
1355  BasicTextOperationsTest();
1356}
1357
1358IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, AcceptKeywordBySpace) {
1359  AcceptKeywordBySpaceTest();
1360}
1361
1362IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,
1363                       NonSubstitutingKeywordTest) {
1364  NonSubstitutingKeywordTest();
1365}
1366
1367IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, DeleteItem) {
1368  DeleteItemTest();
1369}
1370
1371// TODO(suzhe): This test is broken because of broken ViewID support when
1372// enabling AutocompleteEditViewViews.
1373IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,
1374                       DISABLED_TabMoveCursorToEnd) {
1375  TabMoveCursorToEndTest();
1376}
1377
1378IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,
1379                       PersistKeywordModeOnTabSwitch) {
1380  PersistKeywordModeOnTabSwitch();
1381}
1382
1383IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,
1384                       CtrlKeyPressedWithInlineAutocompleteTest) {
1385  CtrlKeyPressedWithInlineAutocompleteTest();
1386}
1387
1388#endif
1389