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. 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. 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: 146 AutocompleteEditViewTest() { 147 set_show_window(true); 148 } 149 150 virtual void SetUpOnMainThread() { 151 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 152 ASSERT_NO_FATAL_FAILURE(SetupComponents()); 153 browser()->FocusLocationBar(); 154 #if defined(TOOLKIT_VIEWS) 155 if (views::NativeTextfieldViews::IsTextfieldViewsEnabled()) 156 return; 157 #endif 158 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), 159 VIEW_ID_LOCATION_BAR)); 160 } 161 162 static void GetAutocompleteEditViewForBrowser( 163 const Browser* browser, 164 AutocompleteEditView** edit_view) { 165 BrowserWindow* window = browser->window(); 166 ASSERT_TRUE(window); 167 LocationBar* loc_bar = window->GetLocationBar(); 168 ASSERT_TRUE(loc_bar); 169 *edit_view = loc_bar->location_entry(); 170 ASSERT_TRUE(*edit_view); 171 } 172 173 void GetAutocompleteEditView(AutocompleteEditView** edit_view) { 174 GetAutocompleteEditViewForBrowser(browser(), edit_view); 175 } 176 177 static void SendKeyForBrowser(const Browser* browser, 178 ui::KeyboardCode key, 179 int modifiers) { 180 ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 181 browser, key, 182 (modifiers & ui::EF_CONTROL_DOWN) != 0, 183 (modifiers & ui::EF_SHIFT_DOWN) != 0, 184 (modifiers & ui::EF_ALT_DOWN) != 0, 185 (modifiers & ui::EF_COMMAND_DOWN) != 0)); 186 } 187 188 void SendKey(ui::KeyboardCode key, int modifiers) { 189 SendKeyForBrowser(browser(), key, modifiers); 190 } 191 192 void SendKeySequence(const wchar_t* keys) { 193 for (; *keys; ++keys) 194 ASSERT_NO_FATAL_FAILURE(SendKey(static_cast<ui::KeyboardCode>(*keys), 0)); 195 } 196 197 bool SendKeyAndWait(const Browser* browser, 198 ui::KeyboardCode key, 199 int modifiers, 200 NotificationType type, 201 const NotificationSource& source) WARN_UNUSED_RESULT { 202 return ui_test_utils::SendKeyPressAndWait( 203 browser, key, 204 (modifiers & ui::EF_CONTROL_DOWN) != 0, 205 (modifiers & ui::EF_SHIFT_DOWN) != 0, 206 (modifiers & ui::EF_ALT_DOWN) != 0, 207 (modifiers & ui::EF_COMMAND_DOWN) != 0, 208 type, source); 209 } 210 211 void WaitForTabOpenOrCloseForBrowser(const Browser* browser, 212 int expected_tab_count) { 213 int tab_count = browser->tab_count(); 214 if (tab_count == expected_tab_count) 215 return; 216 217 NotificationRegistrar registrar; 218 registrar.Add(this, 219 (tab_count < expected_tab_count ? 220 NotificationType::TAB_PARENTED : 221 NotificationType::TAB_CLOSED), 222 NotificationService::AllSources()); 223 224 while (!HasFailure() && browser->tab_count() != expected_tab_count) 225 ui_test_utils::RunMessageLoop(); 226 227 ASSERT_EQ(expected_tab_count, browser->tab_count()); 228 } 229 230 void WaitForTabOpenOrClose(int expected_tab_count) { 231 WaitForTabOpenOrCloseForBrowser(browser(), expected_tab_count); 232 } 233 234 void WaitForAutocompleteControllerDone() { 235 AutocompleteEditView* edit_view = NULL; 236 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 237 238 AutocompleteController* controller = 239 edit_view->model()->popup_model()->autocomplete_controller(); 240 ASSERT_TRUE(controller); 241 242 if (controller->done()) 243 return; 244 245 NotificationRegistrar registrar; 246 registrar.Add(this, 247 NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_READY, 248 Source<AutocompleteController>(controller)); 249 250 while (!HasFailure() && !controller->done()) 251 ui_test_utils::RunMessageLoop(); 252 253 ASSERT_TRUE(controller->done()); 254 } 255 256 void SetupSearchEngine() { 257 TemplateURLModel* model = browser()->profile()->GetTemplateURLModel(); 258 ASSERT_TRUE(model); 259 260 if (!model->loaded()) { 261 NotificationRegistrar registrar; 262 registrar.Add(this, NotificationType::TEMPLATE_URL_MODEL_LOADED, 263 Source<TemplateURLModel>(model)); 264 model->Load(); 265 ui_test_utils::RunMessageLoop(); 266 } 267 268 ASSERT_TRUE(model->loaded()); 269 // Remove built-in template urls, like google.com, bing.com etc., as they 270 // may appear as autocomplete suggests and interfere with our tests. 271 model->SetDefaultSearchProvider(NULL); 272 TemplateURLModel::TemplateURLVector builtins = model->GetTemplateURLs(); 273 for (TemplateURLModel::TemplateURLVector::const_iterator 274 i = builtins.begin(); i != builtins.end(); ++i) 275 model->Remove(*i); 276 277 TemplateURL* template_url = new TemplateURL(); 278 template_url->SetURL(kSearchURL, 0, 0); 279 template_url->set_keyword(UTF8ToUTF16(kSearchKeyword)); 280 template_url->set_short_name(UTF8ToUTF16(kSearchShortName)); 281 282 model->Add(template_url); 283 model->SetDefaultSearchProvider(template_url); 284 } 285 286 void AddHistoryEntry(const TestHistoryEntry& entry, const Time& time) { 287 Profile* profile = browser()->profile(); 288 HistoryService* history_service = 289 profile->GetHistoryService(Profile::EXPLICIT_ACCESS); 290 ASSERT_TRUE(history_service); 291 292 if (!history_service->BackendLoaded()) { 293 NotificationRegistrar registrar; 294 registrar.Add(this, NotificationType::HISTORY_LOADED, 295 Source<Profile>(profile)); 296 ui_test_utils::RunMessageLoop(); 297 } 298 299 BookmarkModel* bookmark_model = profile->GetBookmarkModel(); 300 ASSERT_TRUE(bookmark_model); 301 302 if (!bookmark_model->IsLoaded()) { 303 NotificationRegistrar registrar; 304 registrar.Add(this, NotificationType::BOOKMARK_MODEL_LOADED, 305 Source<Profile>(profile)); 306 ui_test_utils::RunMessageLoop(); 307 } 308 309 GURL url(entry.url); 310 // Add everything in order of time. We don't want to have a time that 311 // is "right now" or it will nondeterministically appear in the results. 312 history_service->AddPageWithDetails(url, UTF8ToUTF16(entry.title), 313 entry.visit_count, 314 entry.typed_count, time, false, 315 history::SOURCE_BROWSED); 316 history_service->SetPageContents(url, UTF8ToUTF16(entry.body)); 317 if (entry.starred) 318 bookmark_model->SetURLStarred(url, string16(), true); 319 } 320 321 void SetupHistory() { 322 // Add enough history pages containing |kSearchText| to trigger 323 // open history page url in autocomplete result. 324 for (size_t i = 0; i < arraysize(kHistoryEntries); i++) { 325 // Add everything in order of time. We don't want to have a time that 326 // is "right now" or it will nondeterministically appear in the results. 327 Time t = Time::Now() - TimeDelta::FromHours(i + 1); 328 ASSERT_NO_FATAL_FAILURE(AddHistoryEntry(kHistoryEntries[i], t)); 329 } 330 } 331 332 void SetupHostResolver() { 333 for (size_t i = 0; i < arraysize(kBlockedHostnames); ++i) 334 host_resolver()->AddSimulatedFailure(kBlockedHostnames[i]); 335 } 336 337 void SetupComponents() { 338 ASSERT_NO_FATAL_FAILURE(SetupHostResolver()); 339 ASSERT_NO_FATAL_FAILURE(SetupSearchEngine()); 340 ASSERT_NO_FATAL_FAILURE(SetupHistory()); 341 } 342 343 virtual void Observe(NotificationType type, 344 const NotificationSource& source, 345 const NotificationDetails& details) { 346 switch (type.value) { 347 case NotificationType::TAB_PARENTED: 348 case NotificationType::TAB_CLOSED: 349 case NotificationType::TEMPLATE_URL_MODEL_LOADED: 350 case NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_READY: 351 case NotificationType::HISTORY_LOADED: 352 case NotificationType::BOOKMARK_MODEL_LOADED: 353 break; 354 default: 355 FAIL() << "Unexpected notification type"; 356 } 357 MessageLoopForUI::current()->Quit(); 358 } 359 360 void BrowserAcceleratorsTest() { 361 AutocompleteEditView* edit_view = NULL; 362 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 363 364 int tab_count = browser()->tab_count(); 365 366 // Create a new Tab. 367 browser()->NewTab(); 368 ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count + 1)); 369 370 // Select the first Tab. 371 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_1, kCtrlOrCmdMask)); 372 ASSERT_EQ(0, browser()->active_index()); 373 374 browser()->FocusLocationBar(); 375 376 // Select the second Tab. 377 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_2, kCtrlOrCmdMask)); 378 ASSERT_EQ(1, browser()->active_index()); 379 380 browser()->FocusLocationBar(); 381 382 // Try ctrl-w to close a Tab. 383 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_W, kCtrlOrCmdMask)); 384 ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count)); 385 386 // Try ctrl-l to focus location bar. 387 edit_view->SetUserText(ASCIIToUTF16("Hello world")); 388 EXPECT_FALSE(edit_view->IsSelectAll()); 389 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_L, kCtrlOrCmdMask)); 390 EXPECT_TRUE(edit_view->IsSelectAll()); 391 392 // Try editing the location bar text. 393 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RIGHT, 0)); 394 EXPECT_FALSE(edit_view->IsSelectAll()); 395 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_S, 0)); 396 EXPECT_EQ(ASCIIToUTF16("Hello worlds"), edit_view->GetText()); 397 398 // Try ctrl-x to cut text. 399 #if defined(OS_MACOSX) 400 // Mac uses alt-left/right to select a word. 401 ASSERT_NO_FATAL_FAILURE( 402 SendKey(ui::VKEY_LEFT, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)); 403 #else 404 ASSERT_NO_FATAL_FAILURE( 405 SendKey(ui::VKEY_LEFT, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)); 406 #endif 407 EXPECT_FALSE(edit_view->IsSelectAll()); 408 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_X, kCtrlOrCmdMask)); 409 EXPECT_EQ(ASCIIToUTF16("Hello "), edit_view->GetText()); 410 411 #if !defined(OS_CHROMEOS) && !defined(OS_MACOSX) 412 // Try alt-f4 to close the browser. 413 ASSERT_TRUE(SendKeyAndWait( 414 browser(), ui::VKEY_F4, ui::EF_ALT_DOWN, 415 NotificationType::BROWSER_CLOSED, Source<Browser>(browser()))); 416 #endif 417 } 418 419 void PopupAcceleratorsTest() { 420 // Create a popup. 421 Browser* popup = CreateBrowserForPopup(browser()->profile()); 422 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(popup)); 423 AutocompleteEditView* edit_view = NULL; 424 ASSERT_NO_FATAL_FAILURE( 425 GetAutocompleteEditViewForBrowser(popup, &edit_view)); 426 popup->FocusLocationBar(); 427 EXPECT_TRUE(edit_view->IsSelectAll()); 428 429 #if !defined(OS_MACOSX) 430 // Try ctrl-w to close the popup. 431 // This piece of code doesn't work on Mac, because the Browser object won't 432 // be destroyed before finishing the current message loop iteration, thus 433 // No BROWSER_CLOSED notification will be sent. 434 ASSERT_TRUE(SendKeyAndWait( 435 popup, ui::VKEY_W, ui::EF_CONTROL_DOWN, 436 NotificationType::BROWSER_CLOSED, Source<Browser>(popup))); 437 438 // Create another popup. 439 popup = CreateBrowserForPopup(browser()->profile()); 440 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(popup)); 441 ASSERT_NO_FATAL_FAILURE( 442 GetAutocompleteEditViewForBrowser(popup, &edit_view)); 443 #endif 444 445 // Set the edit text to "Hello world". 446 edit_view->SetUserText(ASCIIToUTF16("Hello world")); 447 popup->FocusLocationBar(); 448 EXPECT_TRUE(edit_view->IsSelectAll()); 449 450 // Try editing the location bar text -- should be disallowed. 451 ASSERT_NO_FATAL_FAILURE(SendKeyForBrowser(popup, ui::VKEY_S, 0)); 452 EXPECT_EQ(ASCIIToUTF16("Hello world"), edit_view->GetText()); 453 EXPECT_TRUE(edit_view->IsSelectAll()); 454 455 ASSERT_NO_FATAL_FAILURE( 456 SendKeyForBrowser(popup, ui::VKEY_X, kCtrlOrCmdMask)); 457 EXPECT_EQ(ASCIIToUTF16("Hello world"), edit_view->GetText()); 458 EXPECT_TRUE(edit_view->IsSelectAll()); 459 460 #if !defined(OS_CHROMEOS) && !defined(OS_MACOSX) 461 // Try alt-f4 to close the popup. 462 ASSERT_TRUE(SendKeyAndWait( 463 popup, ui::VKEY_F4, ui::EF_ALT_DOWN, 464 NotificationType::BROWSER_CLOSED, Source<Browser>(popup))); 465 #endif 466 } 467 468 void BackspaceInKeywordModeTest() { 469 AutocompleteEditView* edit_view = NULL; 470 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 471 472 // Trigger keyword hint mode. 473 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys)); 474 ASSERT_TRUE(edit_view->model()->is_keyword_hint()); 475 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword())); 476 477 // Trigger keyword mode. 478 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); 479 ASSERT_FALSE(edit_view->model()->is_keyword_hint()); 480 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword())); 481 482 // Backspace without search text should bring back keyword hint mode. 483 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); 484 ASSERT_TRUE(edit_view->model()->is_keyword_hint()); 485 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword())); 486 487 // Trigger keyword mode again. 488 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); 489 ASSERT_FALSE(edit_view->model()->is_keyword_hint()); 490 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword())); 491 492 // Input something as search text. 493 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); 494 495 // Should stay in keyword mode while deleting search text by pressing 496 // backspace. 497 for (size_t i = 0; i < arraysize(kSearchText) - 1; ++i) { 498 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); 499 ASSERT_FALSE(edit_view->model()->is_keyword_hint()); 500 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword())); 501 } 502 503 // Input something as search text. 504 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); 505 506 // Move cursor to the beginning of the search text. 507 #if defined(OS_MACOSX) 508 // Home doesn't work on Mac trybot. 509 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, ui::EF_CONTROL_DOWN)); 510 #else 511 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_HOME, 0)); 512 #endif 513 // Backspace at the beginning of the search text shall turn off 514 // the keyword mode. 515 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); 516 ASSERT_FALSE(edit_view->model()->is_keyword_hint()); 517 ASSERT_EQ(string16(), edit_view->model()->keyword()); 518 ASSERT_EQ(std::string(kSearchKeyword) + kSearchText, 519 UTF16ToUTF8(edit_view->GetText())); 520 } 521 522 void EscapeTest() { 523 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIHistoryURL)); 524 browser()->FocusLocationBar(); 525 526 AutocompleteEditView* edit_view = NULL; 527 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 528 529 string16 old_text = edit_view->GetText(); 530 EXPECT_FALSE(old_text.empty()); 531 EXPECT_TRUE(edit_view->IsSelectAll()); 532 533 // Delete all text in omnibox. 534 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); 535 EXPECT_TRUE(edit_view->GetText().empty()); 536 537 // Escape shall revert the text in omnibox. 538 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_ESCAPE, 0)); 539 EXPECT_EQ(old_text, edit_view->GetText()); 540 EXPECT_TRUE(edit_view->IsSelectAll()); 541 } 542 543 void DesiredTLDTest() { 544 AutocompleteEditView* edit_view = NULL; 545 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 546 AutocompletePopupModel* popup_model = edit_view->model()->popup_model(); 547 ASSERT_TRUE(popup_model); 548 549 // Test ctrl-Enter. 550 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kDesiredTLDKeys)); 551 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); 552 ASSERT_TRUE(popup_model->IsOpen()); 553 // ctrl-Enter triggers desired_tld feature, thus www.bar.com shall be 554 // opened. 555 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, ui::EF_CONTROL_DOWN)); 556 557 GURL url = browser()->GetSelectedTabContents()->GetURL(); 558 EXPECT_STREQ(kDesiredTLDHostname, url.host().c_str()); 559 } 560 561 void AltEnterTest() { 562 AutocompleteEditView* edit_view = NULL; 563 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 564 565 edit_view->SetUserText(ASCIIToUTF16(chrome::kChromeUIHistoryURL)); 566 int tab_count = browser()->tab_count(); 567 // alt-Enter opens a new tab. 568 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, ui::EF_ALT_DOWN)); 569 ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count + 1)); 570 } 571 572 void EnterToSearchTest() { 573 AutocompleteEditView* edit_view = NULL; 574 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 575 AutocompletePopupModel* popup_model = edit_view->model()->popup_model(); 576 ASSERT_TRUE(popup_model); 577 578 // Test Enter to search. 579 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); 580 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); 581 ASSERT_TRUE(popup_model->IsOpen()); 582 583 // Check if the default match result is Search Primary Provider. 584 ASSERT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, 585 popup_model->result().default_match()->type); 586 587 // Open the default match. 588 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, 0)); 589 GURL url = browser()->GetSelectedTabContents()->GetURL(); 590 EXPECT_STREQ(kSearchTextURL, url.spec().c_str()); 591 592 // Test that entering a single character then Enter performs a search. 593 browser()->FocusLocationBar(); 594 EXPECT_TRUE(edit_view->IsSelectAll()); 595 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchSingleCharKeys)); 596 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); 597 ASSERT_TRUE(popup_model->IsOpen()); 598 EXPECT_EQ(kSearchSingleChar, UTF16ToUTF8(edit_view->GetText())); 599 600 // Check if the default match result is Search Primary Provider. 601 ASSERT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, 602 popup_model->result().default_match()->type); 603 604 // Open the default match. 605 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, 0)); 606 url = browser()->GetSelectedTabContents()->GetURL(); 607 EXPECT_STREQ(kSearchSingleCharURL, url.spec().c_str()); 608 } 609 610 void EscapeToDefaultMatchTest() { 611 AutocompleteEditView* edit_view = NULL; 612 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 613 AutocompletePopupModel* popup_model = edit_view->model()->popup_model(); 614 ASSERT_TRUE(popup_model); 615 616 // Input something to trigger inline autocomplete. 617 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys)); 618 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); 619 ASSERT_TRUE(popup_model->IsOpen()); 620 621 string16 old_text = edit_view->GetText(); 622 623 // Make sure inline autocomplete is triggerred. 624 EXPECT_GT(old_text.length(), arraysize(kInlineAutocompleteText) - 1); 625 626 size_t old_selected_line = popup_model->selected_line(); 627 EXPECT_EQ(0U, old_selected_line); 628 629 // Move to another line with different text. 630 size_t size = popup_model->result().size(); 631 while (popup_model->selected_line() < size - 1) { 632 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DOWN, 0)); 633 ASSERT_NE(old_selected_line, popup_model->selected_line()); 634 if (old_text != edit_view->GetText()) 635 break; 636 } 637 638 EXPECT_NE(old_text, edit_view->GetText()); 639 640 // Escape shall revert back to the default match item. 641 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_ESCAPE, 0)); 642 EXPECT_EQ(old_text, edit_view->GetText()); 643 EXPECT_EQ(old_selected_line, popup_model->selected_line()); 644 } 645 646 void BasicTextOperationsTest() { 647 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutBlankURL)); 648 browser()->FocusLocationBar(); 649 650 AutocompleteEditView* edit_view = NULL; 651 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 652 653 string16 old_text = edit_view->GetText(); 654 EXPECT_EQ(UTF8ToUTF16(chrome::kAboutBlankURL), old_text); 655 EXPECT_TRUE(edit_view->IsSelectAll()); 656 657 string16::size_type start, end; 658 edit_view->GetSelectionBounds(&start, &end); 659 EXPECT_EQ(0U, start); 660 EXPECT_EQ(old_text.size(), end); 661 662 // Move the cursor to the end. 663 #if defined(OS_MACOSX) 664 // End doesn't work on Mac trybot. 665 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_E, ui::EF_CONTROL_DOWN)); 666 #else 667 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_END, 0)); 668 #endif 669 EXPECT_FALSE(edit_view->IsSelectAll()); 670 671 // Make sure the cursor is placed correctly. 672 edit_view->GetSelectionBounds(&start, &end); 673 EXPECT_EQ(old_text.size(), start); 674 EXPECT_EQ(old_text.size(), end); 675 676 // Insert one character at the end. Make sure we won't insert 677 // anything after the special ZWS mark used in gtk implementation. 678 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, 0)); 679 EXPECT_EQ(old_text + char16('a'), edit_view->GetText()); 680 681 // Delete one character from the end. Make sure we won't delete the special 682 // ZWS mark used in gtk implementation. 683 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); 684 EXPECT_EQ(old_text, edit_view->GetText()); 685 686 edit_view->SelectAll(true); 687 EXPECT_TRUE(edit_view->IsSelectAll()); 688 edit_view->GetSelectionBounds(&start, &end); 689 EXPECT_EQ(0U, start); 690 EXPECT_EQ(old_text.size(), end); 691 692 // Delete the content 693 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DELETE, 0)); 694 EXPECT_TRUE(edit_view->IsSelectAll()); 695 edit_view->GetSelectionBounds(&start, &end); 696 EXPECT_EQ(0U, start); 697 EXPECT_EQ(0U, end); 698 EXPECT_TRUE(edit_view->GetText().empty()); 699 700 // Check if RevertAll() can set text and cursor correctly. 701 edit_view->RevertAll(); 702 EXPECT_FALSE(edit_view->IsSelectAll()); 703 EXPECT_EQ(old_text, edit_view->GetText()); 704 edit_view->GetSelectionBounds(&start, &end); 705 EXPECT_EQ(old_text.size(), start); 706 EXPECT_EQ(old_text.size(), end); 707 } 708 709 void AcceptKeywordBySpaceTest() { 710 AutocompleteEditView* edit_view = NULL; 711 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 712 713 string16 text = UTF8ToUTF16(kSearchKeyword); 714 715 // Trigger keyword hint mode. 716 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys)); 717 ASSERT_TRUE(edit_view->model()->is_keyword_hint()); 718 ASSERT_EQ(text, edit_view->model()->keyword()); 719 ASSERT_EQ(text, edit_view->GetText()); 720 721 // Trigger keyword mode by space. 722 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0)); 723 ASSERT_FALSE(edit_view->model()->is_keyword_hint()); 724 ASSERT_EQ(text, edit_view->model()->keyword()); 725 ASSERT_TRUE(edit_view->GetText().empty()); 726 727 // Revert to keyword hint mode. 728 edit_view->model()->ClearKeyword(string16()); 729 ASSERT_TRUE(edit_view->model()->is_keyword_hint()); 730 ASSERT_EQ(text, edit_view->model()->keyword()); 731 ASSERT_EQ(text, edit_view->GetText()); 732 733 // Keyword should also be accepted by typing an ideographic space. 734 edit_view->OnBeforePossibleChange(); 735 edit_view->SetWindowTextAndCaretPos(text + WideToUTF16(L"\x3000"), 736 text.length() + 1); 737 edit_view->OnAfterPossibleChange(); 738 ASSERT_FALSE(edit_view->model()->is_keyword_hint()); 739 ASSERT_EQ(text, edit_view->model()->keyword()); 740 ASSERT_TRUE(edit_view->GetText().empty()); 741 742 // Revert to keyword hint mode. 743 edit_view->model()->ClearKeyword(string16()); 744 ASSERT_TRUE(edit_view->model()->is_keyword_hint()); 745 ASSERT_EQ(text, edit_view->model()->keyword()); 746 ASSERT_EQ(text, edit_view->GetText()); 747 748 // Keyword shouldn't be accepted by pasting. 749 // Simulate pasting a whitespace to the end of content. 750 edit_view->OnBeforePossibleChange(); 751 edit_view->model()->on_paste(); 752 edit_view->SetWindowTextAndCaretPos(text + char16(' '), text.length() + 1); 753 edit_view->OnAfterPossibleChange(); 754 // Should be still in keyword hint mode. 755 ASSERT_TRUE(edit_view->model()->is_keyword_hint()); 756 ASSERT_EQ(text, edit_view->model()->keyword()); 757 ASSERT_EQ(text + char16(' '), edit_view->GetText()); 758 759 // Keyword shouldn't be accepted by pressing space with a trailing 760 // whitespace. 761 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0)); 762 ASSERT_TRUE(edit_view->model()->is_keyword_hint()); 763 ASSERT_EQ(text, edit_view->model()->keyword()); 764 ASSERT_EQ(text + ASCIIToUTF16(" "), edit_view->GetText()); 765 766 // Keyword shouldn't be accepted by deleting the trailing space. 767 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); 768 ASSERT_TRUE(edit_view->model()->is_keyword_hint()); 769 ASSERT_EQ(text, edit_view->model()->keyword()); 770 ASSERT_EQ(text + char16(' '), edit_view->GetText()); 771 772 // Keyword shouldn't be accepted by pressing space before a trailing space. 773 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0)); 774 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0)); 775 ASSERT_TRUE(edit_view->model()->is_keyword_hint()); 776 ASSERT_EQ(text, edit_view->model()->keyword()); 777 ASSERT_EQ(text + ASCIIToUTF16(" "), edit_view->GetText()); 778 779 // Keyword should be accepted by pressing space in the middle of context and 780 // just after the keyword. 781 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0)); 782 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, 0)); 783 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0)); 784 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0)); 785 ASSERT_FALSE(edit_view->model()->is_keyword_hint()); 786 ASSERT_EQ(text, edit_view->model()->keyword()); 787 ASSERT_EQ(ASCIIToUTF16("a "), edit_view->GetText()); 788 789 // Keyword shouldn't be accepted by pasting "foo bar". 790 edit_view->SetUserText(string16()); 791 ASSERT_FALSE(edit_view->model()->is_keyword_hint()); 792 ASSERT_TRUE(edit_view->model()->keyword().empty()); 793 794 edit_view->OnBeforePossibleChange(); 795 edit_view->model()->on_paste(); 796 edit_view->SetWindowTextAndCaretPos(text + ASCIIToUTF16(" bar"), 797 text.length() + 4); 798 edit_view->OnAfterPossibleChange(); 799 ASSERT_FALSE(edit_view->model()->is_keyword_hint()); 800 ASSERT_TRUE(edit_view->model()->keyword().empty()); 801 ASSERT_EQ(text + ASCIIToUTF16(" bar"), edit_view->GetText()); 802 803 // Keyword shouldn't be accepted for case like: "foo b|ar" -> "foo b |ar". 804 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0)); 805 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0)); 806 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0)); 807 ASSERT_FALSE(edit_view->model()->is_keyword_hint()); 808 ASSERT_TRUE(edit_view->model()->keyword().empty()); 809 ASSERT_EQ(text + ASCIIToUTF16(" b ar"), edit_view->GetText()); 810 811 // Keyword could be accepted by pressing space with a selected range at the 812 // end of text. 813 edit_view->OnBeforePossibleChange(); 814 edit_view->OnInlineAutocompleteTextMaybeChanged( 815 text + ASCIIToUTF16(" "), text.length()); 816 edit_view->OnAfterPossibleChange(); 817 ASSERT_TRUE(edit_view->model()->is_keyword_hint()); 818 ASSERT_EQ(text, edit_view->model()->keyword()); 819 ASSERT_EQ(text + ASCIIToUTF16(" "), edit_view->GetText()); 820 821 string16::size_type start, end; 822 edit_view->GetSelectionBounds(&start, &end); 823 ASSERT_NE(start, end); 824 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0)); 825 ASSERT_FALSE(edit_view->model()->is_keyword_hint()); 826 ASSERT_EQ(text, edit_view->model()->keyword()); 827 ASSERT_EQ(string16(), edit_view->GetText()); 828 829 edit_view->SetUserText(string16()); 830 831 // Space should accept keyword even when inline autocomplete is available. 832 const TestHistoryEntry kHistoryFoobar = { 833 "http://www.foobar.com", "Page foobar", kSearchText, 10000, 10000, true 834 }; 835 836 // Add a history entry to trigger inline autocomplete when typing "foo". 837 ASSERT_NO_FATAL_FAILURE( 838 AddHistoryEntry(kHistoryFoobar, Time::Now() - TimeDelta::FromHours(1))); 839 840 // Type "foo" to trigger inline autocomplete. 841 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys)); 842 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); 843 ASSERT_TRUE(edit_view->model()->popup_model()->IsOpen()); 844 ASSERT_NE(text, edit_view->GetText()); 845 846 // Keyword hint shouldn't be visible. 847 ASSERT_FALSE(edit_view->model()->is_keyword_hint()); 848 ASSERT_TRUE(edit_view->model()->keyword().empty()); 849 850 // Trigger keyword mode by space. 851 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0)); 852 ASSERT_FALSE(edit_view->model()->is_keyword_hint()); 853 ASSERT_EQ(text, edit_view->model()->keyword()); 854 ASSERT_TRUE(edit_view->GetText().empty()); 855 } 856 857 void NonSubstitutingKeywordTest() { 858 AutocompleteEditView* edit_view = NULL; 859 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 860 AutocompletePopupModel* popup_model = edit_view->model()->popup_model(); 861 ASSERT_TRUE(popup_model); 862 863 TemplateURLModel* template_url_model = 864 browser()->profile()->GetTemplateURLModel(); 865 866 // Add a non-default substituting keyword. 867 TemplateURL* template_url = new TemplateURL(); 868 template_url->SetURL("http://abc.com/{searchTerms}", 0, 0); 869 template_url->set_keyword(UTF8ToUTF16(kSearchText)); 870 template_url->set_short_name(UTF8ToUTF16("Search abc")); 871 template_url_model->Add(template_url); 872 873 edit_view->SetUserText(string16()); 874 875 // Non-default substituting keyword shouldn't be matched by default. 876 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); 877 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); 878 ASSERT_TRUE(popup_model->IsOpen()); 879 880 // Check if the default match result is Search Primary Provider. 881 ASSERT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, 882 popup_model->result().default_match()->type); 883 ASSERT_EQ(kSearchTextURL, 884 popup_model->result().default_match()->destination_url.spec()); 885 886 edit_view->SetUserText(string16()); 887 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); 888 ASSERT_FALSE(popup_model->IsOpen()); 889 890 // Try a non-substituting keyword. 891 template_url_model->Remove(template_url); 892 template_url = new TemplateURL(); 893 template_url->SetURL("http://abc.com/", 0, 0); 894 template_url->set_keyword(UTF8ToUTF16(kSearchText)); 895 template_url->set_short_name(UTF8ToUTF16("abc")); 896 template_url_model->Add(template_url); 897 898 // We always allow exact matches for non-substituting keywords. 899 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); 900 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); 901 ASSERT_TRUE(popup_model->IsOpen()); 902 ASSERT_EQ(AutocompleteMatch::HISTORY_KEYWORD, 903 popup_model->result().default_match()->type); 904 ASSERT_EQ("http://abc.com/", 905 popup_model->result().default_match()->destination_url.spec()); 906 } 907 908 void DeleteItemTest() { 909 // Disable the search provider, to make sure the popup contains only history 910 // items. 911 TemplateURLModel* model = browser()->profile()->GetTemplateURLModel(); 912 model->SetDefaultSearchProvider(NULL); 913 914 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutBlankURL)); 915 browser()->FocusLocationBar(); 916 917 AutocompleteEditView* edit_view = NULL; 918 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 919 920 AutocompletePopupModel* popup_model = edit_view->model()->popup_model(); 921 ASSERT_TRUE(popup_model); 922 923 string16 old_text = edit_view->GetText(); 924 925 // Input something that can match history items. 926 edit_view->SetUserText(ASCIIToUTF16("bar")); 927 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); 928 ASSERT_TRUE(popup_model->IsOpen()); 929 930 // Delete the inline autocomplete part. 931 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DELETE, 0)); 932 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); 933 ASSERT_TRUE(popup_model->IsOpen()); 934 ASSERT_GE(popup_model->result().size(), 3U); 935 936 string16 user_text = edit_view->GetText(); 937 ASSERT_EQ(ASCIIToUTF16("bar"), user_text); 938 edit_view->SelectAll(true); 939 ASSERT_TRUE(edit_view->IsSelectAll()); 940 941 // The first item should be the default match. 942 size_t default_line = popup_model->selected_line(); 943 std::string default_url = 944 popup_model->result().match_at(default_line).destination_url.spec(); 945 946 // Move down. 947 edit_view->model()->OnUpOrDownKeyPressed(1); 948 ASSERT_EQ(default_line + 1, popup_model->selected_line()); 949 string16 selected_text = 950 popup_model->result().match_at(default_line + 1).fill_into_edit; 951 // Temporary text is shown. 952 ASSERT_EQ(selected_text, edit_view->GetText()); 953 ASSERT_FALSE(edit_view->IsSelectAll()); 954 955 // Delete the item. 956 popup_model->TryDeletingCurrentItem(); 957 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); 958 // The selected line shouldn't be changed, because we have more than two 959 // items. 960 ASSERT_EQ(default_line + 1, popup_model->selected_line()); 961 // Make sure the item is really deleted. 962 ASSERT_NE(selected_text, 963 popup_model->result().match_at(default_line + 1).fill_into_edit); 964 selected_text = 965 popup_model->result().match_at(default_line + 1).fill_into_edit; 966 // New temporary text is shown. 967 ASSERT_EQ(selected_text, edit_view->GetText()); 968 969 // Revert to the default match. 970 ASSERT_TRUE(edit_view->model()->OnEscapeKeyPressed()); 971 ASSERT_EQ(default_line, popup_model->selected_line()); 972 ASSERT_EQ(user_text, edit_view->GetText()); 973 ASSERT_TRUE(edit_view->IsSelectAll()); 974 975 // Move down and up to select the default match as temporary text. 976 edit_view->model()->OnUpOrDownKeyPressed(1); 977 ASSERT_EQ(default_line + 1, popup_model->selected_line()); 978 edit_view->model()->OnUpOrDownKeyPressed(-1); 979 ASSERT_EQ(default_line, popup_model->selected_line()); 980 981 selected_text = popup_model->result().match_at(default_line).fill_into_edit; 982 // New temporary text is shown. 983 ASSERT_EQ(selected_text, edit_view->GetText()); 984 ASSERT_FALSE(edit_view->IsSelectAll()); 985 986 // Delete the default item. 987 popup_model->TryDeletingCurrentItem(); 988 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); 989 // The selected line shouldn't be changed, but the default item should have 990 // been changed. 991 ASSERT_EQ(default_line, popup_model->selected_line()); 992 // Make sure the item is really deleted. 993 ASSERT_NE(selected_text, 994 popup_model->result().match_at(default_line).fill_into_edit); 995 selected_text = 996 popup_model->result().match_at(default_line).fill_into_edit; 997 // New temporary text is shown. 998 ASSERT_EQ(selected_text, edit_view->GetText()); 999 1000 // As the current selected item is the new default item, pressing Escape key 1001 // should revert all directly. 1002 ASSERT_TRUE(edit_view->model()->OnEscapeKeyPressed()); 1003 ASSERT_EQ(old_text, edit_view->GetText()); 1004 ASSERT_TRUE(edit_view->IsSelectAll()); 1005 } 1006 1007 void TabMoveCursorToEndTest() { 1008 AutocompleteEditView* edit_view = NULL; 1009 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 1010 1011 edit_view->SetUserText(ASCIIToUTF16("Hello world")); 1012 1013 // Move cursor to the beginning. 1014 #if defined(OS_MACOSX) 1015 // Home doesn't work on Mac trybot. 1016 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, ui::EF_CONTROL_DOWN)); 1017 #else 1018 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_HOME, 0)); 1019 #endif 1020 1021 string16::size_type start, end; 1022 edit_view->GetSelectionBounds(&start, &end); 1023 EXPECT_EQ(0U, start); 1024 EXPECT_EQ(0U, end); 1025 1026 // Pressing tab should move cursor to the end. 1027 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); 1028 1029 edit_view->GetSelectionBounds(&start, &end); 1030 EXPECT_EQ(edit_view->GetText().size(), start); 1031 EXPECT_EQ(edit_view->GetText().size(), end); 1032 1033 // The location bar should still have focus. 1034 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_LOCATION_BAR)); 1035 1036 // Select all text. 1037 edit_view->SelectAll(true); 1038 EXPECT_TRUE(edit_view->IsSelectAll()); 1039 edit_view->GetSelectionBounds(&start, &end); 1040 EXPECT_EQ(0U, start); 1041 EXPECT_EQ(edit_view->GetText().size(), end); 1042 1043 // Pressing tab should move cursor to the end. 1044 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); 1045 1046 edit_view->GetSelectionBounds(&start, &end); 1047 EXPECT_EQ(edit_view->GetText().size(), start); 1048 EXPECT_EQ(edit_view->GetText().size(), end); 1049 1050 // The location bar should still have focus. 1051 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_LOCATION_BAR)); 1052 1053 // Pressing tab when cursor is at the end should change focus. 1054 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); 1055 1056 ASSERT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_LOCATION_BAR)); 1057 } 1058 1059 void PersistKeywordModeOnTabSwitch() { 1060 AutocompleteEditView* edit_view = NULL; 1061 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 1062 1063 // Trigger keyword hint mode. 1064 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys)); 1065 ASSERT_TRUE(edit_view->model()->is_keyword_hint()); 1066 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword())); 1067 1068 // Trigger keyword mode. 1069 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0)); 1070 ASSERT_FALSE(edit_view->model()->is_keyword_hint()); 1071 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword())); 1072 1073 // Input something as search text. 1074 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys)); 1075 1076 // Create a new tab. 1077 browser()->NewTab(); 1078 1079 // Switch back to the first tab. 1080 browser()->ActivateTabAt(0, true); 1081 1082 // Make sure we're still in keyword mode. 1083 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(edit_view->model()->keyword())); 1084 } 1085 1086 void CtrlKeyPressedWithInlineAutocompleteTest() { 1087 AutocompleteEditView* edit_view = NULL; 1088 ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); 1089 AutocompletePopupModel* popup_model = edit_view->model()->popup_model(); 1090 ASSERT_TRUE(popup_model); 1091 1092 // Input something to trigger inline autocomplete. 1093 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys)); 1094 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone()); 1095 ASSERT_TRUE(popup_model->IsOpen()); 1096 1097 string16 old_text = edit_view->GetText(); 1098 1099 // Make sure inline autocomplete is triggerred. 1100 EXPECT_GT(old_text.length(), arraysize(kInlineAutocompleteText) - 1); 1101 1102 // Press ctrl key. 1103 edit_view->model()->OnControlKeyChanged(true); 1104 1105 // Inline autocomplete should still be there. 1106 EXPECT_EQ(old_text, edit_view->GetText()); 1107 } 1108 1109 }; 1110 1111 // Test if ctrl-* accelerators are workable in omnibox. 1112 // See http://crbug.com/19193: omnibox blocks ctrl-* commands 1113 // 1114 // Flaky on interactive tests (dbg), http://crbug.com/69433 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 1126 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, MAYBE_PopupAccelerators) { 1127 PopupAcceleratorsTest(); 1128 } 1129 1130 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, BackspaceInKeywordMode) { 1131 BackspaceInKeywordModeTest(); 1132 } 1133 1134 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, Escape) { 1135 EscapeTest(); 1136 } 1137 1138 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, DesiredTLD) { 1139 DesiredTLDTest(); 1140 } 1141 1142 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, AltEnter) { 1143 AltEnterTest(); 1144 } 1145 1146 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, EnterToSearch) { 1147 EnterToSearchTest(); 1148 } 1149 1150 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, EscapeToDefaultMatch) { 1151 EscapeToDefaultMatchTest(); 1152 } 1153 1154 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, BasicTextOperations) { 1155 BasicTextOperationsTest(); 1156 } 1157 1158 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, AcceptKeywordBySpace) { 1159 AcceptKeywordBySpaceTest(); 1160 } 1161 1162 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, NonSubstitutingKeywordTest) { 1163 NonSubstitutingKeywordTest(); 1164 } 1165 1166 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, DeleteItem) { 1167 DeleteItemTest(); 1168 } 1169 1170 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, TabMoveCursorToEnd) { 1171 TabMoveCursorToEndTest(); 1172 } 1173 1174 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, 1175 PersistKeywordModeOnTabSwitch) { 1176 PersistKeywordModeOnTabSwitch(); 1177 } 1178 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 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 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 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 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: 1316 AutocompleteEditViewViewsTest() { 1317 views::NativeTextfieldViews::SetEnableTextfieldViews(true); 1318 } 1319 }; 1320 1321 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, 1322 FLAKY_BrowserAccelerators) { 1323 BrowserAcceleratorsTest(); 1324 } 1325 1326 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, MAYBE_PopupAccelerators) { 1327 PopupAcceleratorsTest(); 1328 } 1329 1330 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, BackspaceInKeywordMode) { 1331 BackspaceInKeywordModeTest(); 1332 } 1333 1334 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, Escape) { 1335 EscapeTest(); 1336 } 1337 1338 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, DesiredTLD) { 1339 DesiredTLDTest(); 1340 } 1341 1342 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, AltEnter) { 1343 AltEnterTest(); 1344 } 1345 1346 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, EnterToSearch) { 1347 EnterToSearchTest(); 1348 } 1349 1350 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, EscapeToDefaultMatch) { 1351 EscapeToDefaultMatchTest(); 1352 } 1353 1354 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, BasicTextOperations) { 1355 BasicTextOperationsTest(); 1356 } 1357 1358 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, AcceptKeywordBySpace) { 1359 AcceptKeywordBySpaceTest(); 1360 } 1361 1362 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, 1363 NonSubstitutingKeywordTest) { 1364 NonSubstitutingKeywordTest(); 1365 } 1366 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. 1373 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, 1374 DISABLED_TabMoveCursorToEnd) { 1375 TabMoveCursorToEndTest(); 1376 } 1377 1378 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, 1379 PersistKeywordModeOnTabSwitch) { 1380 PersistKeywordModeOnTabSwitch(); 1381 } 1382 1383 IN_PROC_BROWSER_TEST_F(AutocompleteEditViewViewsTest, 1384 CtrlKeyPressedWithInlineAutocompleteTest) { 1385 CtrlKeyPressedWithInlineAutocompleteTest(); 1386 } 1387 1388 #endif 1389