• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
46 using base::Time;
47 using base::TimeDelta;
48 
49 namespace {
50 
51 const char kSearchKeyword[] = "foo";
52 const wchar_t kSearchKeywordKeys[] = {
53   ui::VKEY_F, ui::VKEY_O, ui::VKEY_O, 0
54 };
55 const char kSearchURL[] = "http://www.foo.com/search?q={searchTerms}";
56 const char kSearchShortName[] = "foo";
57 const char kSearchText[] = "abc";
58 const wchar_t kSearchTextKeys[] = {
59   ui::VKEY_A, ui::VKEY_B, ui::VKEY_C, 0
60 };
61 const char kSearchTextURL[] = "http://www.foo.com/search?q=abc";
62 const char kSearchSingleChar[] = "z";
63 const wchar_t kSearchSingleCharKeys[] = { ui::VKEY_Z, 0 };
64 const char kSearchSingleCharURL[] = "http://www.foo.com/search?q=z";
65 
66 const char kHistoryPageURL[] = "chrome://history/#q=abc";
67 
68 const char kDesiredTLDHostname[] = "www.bar.com";
69 const wchar_t kDesiredTLDKeys[] = {
70   ui::VKEY_B, ui::VKEY_A, ui::VKEY_R, 0
71 };
72 
73 const char kInlineAutocompleteText[] = "def";
74 const 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.
79 const 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 
92 const 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.
GetPrimarySelectionText()116 std::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.
SetClipboardText(const char * text)127 void 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)
136 const int kCtrlOrCmdMask = ui::EF_COMMAND_DOWN;
137 #else
138 const int kCtrlOrCmdMask = ui::EF_CONTROL_DOWN;
139 #endif
140 
141 }  // namespace
142 
143 class AutocompleteEditViewTest : public InProcessBrowserTest,
144                                  public NotificationObserver {
145  protected:
AutocompleteEditViewTest()146   AutocompleteEditViewTest() {
147     set_show_window(true);
148   }
149 
SetUpOnMainThread()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 
GetAutocompleteEditViewForBrowser(const Browser * browser,AutocompleteEditView ** edit_view)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 
GetAutocompleteEditView(AutocompleteEditView ** edit_view)173   void GetAutocompleteEditView(AutocompleteEditView** edit_view) {
174     GetAutocompleteEditViewForBrowser(browser(), edit_view);
175   }
176 
SendKeyForBrowser(const Browser * browser,ui::KeyboardCode key,int modifiers)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 
SendKey(ui::KeyboardCode key,int modifiers)188   void SendKey(ui::KeyboardCode key, int modifiers) {
189     SendKeyForBrowser(browser(), key, modifiers);
190   }
191 
SendKeySequence(const wchar_t * keys)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 
SendKeyAndWait(const Browser * browser,ui::KeyboardCode key,int modifiers,NotificationType type,const NotificationSource & source)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 
WaitForTabOpenOrCloseForBrowser(const Browser * browser,int expected_tab_count)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 
WaitForTabOpenOrClose(int expected_tab_count)230   void WaitForTabOpenOrClose(int expected_tab_count) {
231     WaitForTabOpenOrCloseForBrowser(browser(), expected_tab_count);
232   }
233 
WaitForAutocompleteControllerDone()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 
SetupSearchEngine()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 
AddHistoryEntry(const TestHistoryEntry & entry,const Time & time)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 
SetupHistory()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 
SetupHostResolver()332   void SetupHostResolver() {
333     for (size_t i = 0; i < arraysize(kBlockedHostnames); ++i)
334       host_resolver()->AddSimulatedFailure(kBlockedHostnames[i]);
335   }
336 
SetupComponents()337   void SetupComponents() {
338     ASSERT_NO_FATAL_FAILURE(SetupHostResolver());
339     ASSERT_NO_FATAL_FAILURE(SetupSearchEngine());
340     ASSERT_NO_FATAL_FAILURE(SetupHistory());
341   }
342 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)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 
BrowserAcceleratorsTest()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 
PopupAcceleratorsTest()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 
BackspaceInKeywordModeTest()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 
EscapeTest()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 
DesiredTLDTest()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 
AltEnterTest()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 
EnterToSearchTest()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 
EscapeToDefaultMatchTest()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 
BasicTextOperationsTest()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 
AcceptKeywordBySpaceTest()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 
NonSubstitutingKeywordTest()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 
DeleteItemTest()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 
TabMoveCursorToEndTest()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 
PersistKeywordModeOnTabSwitch()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 
CtrlKeyPressedWithInlineAutocompleteTest()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
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,FLAKY_BrowserAccelerators)1115 IN_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 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,MAYBE_PopupAccelerators)1126 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, MAYBE_PopupAccelerators) {
1127   PopupAcceleratorsTest();
1128 }
1129 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,BackspaceInKeywordMode)1130 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, BackspaceInKeywordMode) {
1131   BackspaceInKeywordModeTest();
1132 }
1133 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,Escape)1134 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, Escape) {
1135   EscapeTest();
1136 }
1137 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,DesiredTLD)1138 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, DesiredTLD) {
1139   DesiredTLDTest();
1140 }
1141 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,AltEnter)1142 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, AltEnter) {
1143   AltEnterTest();
1144 }
1145 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,EnterToSearch)1146 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, EnterToSearch) {
1147   EnterToSearchTest();
1148 }
1149 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,EscapeToDefaultMatch)1150 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, EscapeToDefaultMatch) {
1151   EscapeToDefaultMatchTest();
1152 }
1153 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,BasicTextOperations)1154 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, BasicTextOperations) {
1155   BasicTextOperationsTest();
1156 }
1157 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,AcceptKeywordBySpace)1158 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, AcceptKeywordBySpace) {
1159   AcceptKeywordBySpaceTest();
1160 }
1161 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,NonSubstitutingKeywordTest)1162 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, NonSubstitutingKeywordTest) {
1163   NonSubstitutingKeywordTest();
1164 }
1165 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,DeleteItem)1166 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, DeleteItem) {
1167   DeleteItemTest();
1168 }
1169 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,TabMoveCursorToEnd)1170 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, TabMoveCursorToEnd) {
1171   TabMoveCursorToEndTest();
1172 }
1173 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,PersistKeywordModeOnTabSwitch)1174 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,
1175                        PersistKeywordModeOnTabSwitch) {
1176   PersistKeywordModeOnTabSwitch();
1177 }
1178 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,CtrlKeyPressedWithInlineAutocompleteTest)1179 IN_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 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,UndoRedoLinux)1188 IN_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
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,PrimarySelection)1254 IN_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
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,BackspaceDeleteHalfWidthKatakana)1279 IN_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
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest,PasteReplacingAll)1295 IN_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)
1314 class AutocompleteEditViewViewsTest : public AutocompleteEditViewTest {
1315  public:
AutocompleteEditViewViewsTest()1316   AutocompleteEditViewViewsTest() {
1317     views::NativeTextfieldViews::SetEnableTextfieldViews(true);
1318   }
1319 };
1320 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,FLAKY_BrowserAccelerators)1321 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,
1322                        FLAKY_BrowserAccelerators) {
1323   BrowserAcceleratorsTest();
1324 }
1325 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,MAYBE_PopupAccelerators)1326 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, MAYBE_PopupAccelerators) {
1327   PopupAcceleratorsTest();
1328 }
1329 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,BackspaceInKeywordMode)1330 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, BackspaceInKeywordMode) {
1331   BackspaceInKeywordModeTest();
1332 }
1333 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,Escape)1334 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, Escape) {
1335   EscapeTest();
1336 }
1337 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,DesiredTLD)1338 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, DesiredTLD) {
1339   DesiredTLDTest();
1340 }
1341 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,AltEnter)1342 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, AltEnter) {
1343   AltEnterTest();
1344 }
1345 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,EnterToSearch)1346 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, EnterToSearch) {
1347   EnterToSearchTest();
1348 }
1349 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,EscapeToDefaultMatch)1350 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, EscapeToDefaultMatch) {
1351   EscapeToDefaultMatchTest();
1352 }
1353 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,BasicTextOperations)1354 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, BasicTextOperations) {
1355   BasicTextOperationsTest();
1356 }
1357 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,AcceptKeywordBySpace)1358 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, AcceptKeywordBySpace) {
1359   AcceptKeywordBySpaceTest();
1360 }
1361 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,NonSubstitutingKeywordTest)1362 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,
1363                        NonSubstitutingKeywordTest) {
1364   NonSubstitutingKeywordTest();
1365 }
1366 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,DeleteItem)1367 IN_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.
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,DISABLED_TabMoveCursorToEnd)1373 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,
1374                        DISABLED_TabMoveCursorToEnd) {
1375   TabMoveCursorToEndTest();
1376 }
1377 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,PersistKeywordModeOnTabSwitch)1378 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,
1379                        PersistKeywordModeOnTabSwitch) {
1380   PersistKeywordModeOnTabSwitch();
1381 }
1382 
IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,CtrlKeyPressedWithInlineAutocompleteTest)1383 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest,
1384                        CtrlKeyPressedWithInlineAutocompleteTest) {
1385   CtrlKeyPressedWithInlineAutocompleteTest();
1386 }
1387 
1388 #endif
1389