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