Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / ui / omnibox / omnibox_view_browsertest.cc
blobfa609f9d8faa2776ed7d0e8ecd7d91fc179f7685
1 // Copyright (c) 2012 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.
5 #include <stdio.h>
7 #include "base/command_line.h"
8 #include "base/strings/string16.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/time/time.h"
12 #include "chrome/app/chrome_command_ids.h"
13 #include "chrome/browser/autocomplete/history_quick_provider.h"
14 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/history/history_service.h"
17 #include "chrome/browser/history/history_service_factory.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/search_engines/template_url_service_factory.h"
20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/browser_commands.h"
22 #include "chrome/browser/ui/browser_window.h"
23 #include "chrome/browser/ui/location_bar/location_bar.h"
24 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
25 #include "chrome/browser/ui/omnibox/omnibox_view.h"
26 #include "chrome/browser/ui/tabs/tab_strip_model.h"
27 #include "chrome/browser/ui/toolbar/test_toolbar_model.h"
28 #include "chrome/common/chrome_paths.h"
29 #include "chrome/common/chrome_switches.h"
30 #include "chrome/common/url_constants.h"
31 #include "chrome/test/base/in_process_browser_test.h"
32 #include "chrome/test/base/interactive_test_utils.h"
33 #include "chrome/test/base/ui_test_utils.h"
34 #include "components/bookmarks/browser/bookmark_model.h"
35 #include "components/bookmarks/browser/bookmark_utils.h"
36 #include "components/bookmarks/test/bookmark_test_helpers.h"
37 #include "components/omnibox/autocomplete_input.h"
38 #include "components/omnibox/autocomplete_match.h"
39 #include "components/search_engines/template_url.h"
40 #include "components/search_engines/template_url_service.h"
41 #include "content/public/browser/notification_service.h"
42 #include "content/public/browser/web_contents.h"
43 #include "net/dns/mock_host_resolver.h"
44 #include "ui/base/clipboard/clipboard.h"
45 #include "ui/base/clipboard/scoped_clipboard_writer.h"
46 #include "ui/events/event_constants.h"
47 #include "ui/events/keycodes/keyboard_codes.h"
48 #include "ui/gfx/point.h"
50 using base::ASCIIToUTF16;
51 using base::UTF16ToUTF8;
52 using base::Time;
53 using base::TimeDelta;
55 namespace {
57 const char kSearchKeyword[] = "foo";
58 const char kSearchKeyword2[] = "footest.com";
59 const ui::KeyboardCode kSearchKeywordKeys[] = {
60 ui::VKEY_F, ui::VKEY_O, ui::VKEY_O, ui::VKEY_UNKNOWN
62 const ui::KeyboardCode kSearchKeywordPrefixKeys[] = {
63 ui::VKEY_F, ui::VKEY_O, ui::VKEY_UNKNOWN
65 const ui::KeyboardCode kSearchKeywordCompletionKeys[] = {
66 ui::VKEY_O, ui::VKEY_UNKNOWN
68 const char kSearchURL[] = "http://www.foo.com/search?q={searchTerms}";
69 const char kSearchShortName[] = "foo";
70 const char kSearchText[] = "abc";
71 const ui::KeyboardCode kSearchTextKeys[] = {
72 ui::VKEY_A, ui::VKEY_B, ui::VKEY_C, ui::VKEY_UNKNOWN
74 const char kSearchTextURL[] = "http://www.foo.com/search?q=abc";
76 const char kInlineAutocompleteText[] = "def";
77 const ui::KeyboardCode kInlineAutocompleteTextKeys[] = {
78 ui::VKEY_D, ui::VKEY_E, ui::VKEY_F, ui::VKEY_UNKNOWN
81 // Hostnames that shall be blocked by host resolver.
82 const char *kBlockedHostnames[] = {
83 "foo",
84 "*.foo.com",
85 "bar",
86 "*.bar.com",
87 "abc",
88 "*.abc.com",
89 "def",
90 "*.def.com",
91 "*.site.com",
92 "history",
93 "z"
96 const struct TestHistoryEntry {
97 const char* url;
98 const char* title;
99 int visit_count;
100 int typed_count;
101 bool starred;
102 } kHistoryEntries[] = {
103 {"http://www.bar.com/1", "Page 1", 10, 10, false },
104 {"http://www.bar.com/2", "Page 2", 9, 9, false },
105 {"http://www.bar.com/3", "Page 3", 8, 8, false },
106 {"http://www.bar.com/4", "Page 4", 7, 7, false },
107 {"http://www.bar.com/5", "Page 5", 6, 6, false },
108 {"http://www.bar.com/6", "Page 6", 5, 5, false },
109 {"http://www.bar.com/7", "Page 7", 4, 4, false },
110 {"http://www.bar.com/8", "Page 8", 3, 3, false },
111 {"http://www.bar.com/9", "Page 9", 2, 2, false },
112 {"http://www.site.com/path/1", "Site 1", 4, 4, false },
113 {"http://www.site.com/path/2", "Site 2", 3, 3, false },
114 {"http://www.site.com/path/3", "Site 3", 2, 2, false },
116 // To trigger inline autocomplete.
117 {"http://www.def.com", "Page def", 10000, 10000, true },
119 // Used in particular for the desired TLD test. This makes it test
120 // the interesting case when there's an intranet host with the same
121 // name as the .com.
122 {"http://bar/", "Bar", 1, 0, false },
125 // Stores the given text to clipboard.
126 void SetClipboardText(const base::string16& text) {
127 ui::ScopedClipboardWriter writer(ui::CLIPBOARD_TYPE_COPY_PASTE);
128 writer.WriteText(text);
131 #if defined(OS_MACOSX)
132 const int kCtrlOrCmdMask = ui::EF_COMMAND_DOWN;
133 #else
134 const int kCtrlOrCmdMask = ui::EF_CONTROL_DOWN;
135 #endif
137 } // namespace
139 class OmniboxViewTest : public InProcessBrowserTest,
140 public content::NotificationObserver {
141 protected:
142 virtual void SetUpOnMainThread() override {
143 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
144 ASSERT_NO_FATAL_FAILURE(SetupComponents());
145 chrome::FocusLocationBar(browser());
146 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
149 static void GetOmniboxViewForBrowser(
150 const Browser* browser,
151 OmniboxView** omnibox_view) {
152 BrowserWindow* window = browser->window();
153 ASSERT_TRUE(window);
154 LocationBar* location_bar = window->GetLocationBar();
155 ASSERT_TRUE(location_bar);
156 *omnibox_view = location_bar->GetOmniboxView();
157 ASSERT_TRUE(*omnibox_view);
160 void GetOmniboxView(OmniboxView** omnibox_view) {
161 GetOmniboxViewForBrowser(browser(), omnibox_view);
164 static void SendKeyForBrowser(const Browser* browser,
165 ui::KeyboardCode key,
166 int modifiers) {
167 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
168 browser, key,
169 (modifiers & ui::EF_CONTROL_DOWN) != 0,
170 (modifiers & ui::EF_SHIFT_DOWN) != 0,
171 (modifiers & ui::EF_ALT_DOWN) != 0,
172 (modifiers & ui::EF_COMMAND_DOWN) != 0));
175 void SendKey(ui::KeyboardCode key, int modifiers) {
176 SendKeyForBrowser(browser(), key, modifiers);
179 void SendKeySequence(const ui::KeyboardCode* keys) {
180 for (; *keys != ui::VKEY_UNKNOWN; ++keys)
181 ASSERT_NO_FATAL_FAILURE(SendKey(*keys, 0));
184 bool SendKeyAndWait(const Browser* browser,
185 ui::KeyboardCode key,
186 int modifiers,
187 int type,
188 const content::NotificationSource& source)
189 WARN_UNUSED_RESULT {
190 return ui_test_utils::SendKeyPressAndWait(
191 browser, key,
192 (modifiers & ui::EF_CONTROL_DOWN) != 0,
193 (modifiers & ui::EF_SHIFT_DOWN) != 0,
194 (modifiers & ui::EF_ALT_DOWN) != 0,
195 (modifiers & ui::EF_COMMAND_DOWN) != 0,
196 type, source);
199 void WaitForTabOpenOrCloseForBrowser(const Browser* browser,
200 int expected_tab_count) {
201 int tab_count = browser->tab_strip_model()->count();
202 if (tab_count == expected_tab_count)
203 return;
205 content::NotificationRegistrar registrar;
206 registrar.Add(this,
207 (tab_count < expected_tab_count) ?
208 static_cast<int>(chrome::NOTIFICATION_TAB_PARENTED) :
209 static_cast<int>(content::NOTIFICATION_WEB_CONTENTS_DESTROYED),
210 content::NotificationService::AllSources());
212 while (!HasFailure() &&
213 browser->tab_strip_model()->count() != expected_tab_count) {
214 content::RunMessageLoop();
217 ASSERT_EQ(expected_tab_count, browser->tab_strip_model()->count());
220 void WaitForTabOpenOrClose(int expected_tab_count) {
221 WaitForTabOpenOrCloseForBrowser(browser(), expected_tab_count);
224 void WaitForAutocompleteControllerDone() {
225 OmniboxView* omnibox_view = NULL;
226 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
228 AutocompleteController* controller =
229 omnibox_view->model()->autocomplete_controller();
230 ASSERT_TRUE(controller);
232 if (controller->done())
233 return;
235 content::NotificationRegistrar registrar;
236 registrar.Add(this,
237 chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
238 content::Source<AutocompleteController>(controller));
240 while (!HasFailure() && !controller->done())
241 content::RunMessageLoop();
243 ASSERT_TRUE(controller->done());
246 void SetupSearchEngine() {
247 Profile* profile = browser()->profile();
248 TemplateURLService* model =
249 TemplateURLServiceFactory::GetForProfile(profile);
250 ASSERT_TRUE(model);
252 ui_test_utils::WaitForTemplateURLServiceToLoad(model);
254 ASSERT_TRUE(model->loaded());
256 TemplateURLData data;
257 data.short_name = ASCIIToUTF16(kSearchShortName);
258 data.SetKeyword(ASCIIToUTF16(kSearchKeyword));
259 data.SetURL(kSearchURL);
260 TemplateURL* template_url = new TemplateURL(data);
261 model->Add(template_url);
262 model->SetUserSelectedDefaultSearchProvider(template_url);
264 data.SetKeyword(ASCIIToUTF16(kSearchKeyword2));
265 model->Add(new TemplateURL(data));
267 // Remove built-in template urls, like google.com, bing.com etc., as they
268 // may appear as autocomplete suggests and interfere with our tests.
269 TemplateURLService::TemplateURLVector urls = model->GetTemplateURLs();
270 for (TemplateURLService::TemplateURLVector::const_iterator i = urls.begin();
271 i != urls.end();
272 ++i) {
273 if ((*i)->prepopulate_id() != 0)
274 model->Remove(*i);
278 void AddHistoryEntry(const TestHistoryEntry& entry, const Time& time) {
279 Profile* profile = browser()->profile();
280 HistoryService* history_service = HistoryServiceFactory::GetForProfile(
281 profile, Profile::EXPLICIT_ACCESS);
282 ASSERT_TRUE(history_service);
284 if (!history_service->BackendLoaded()) {
285 content::NotificationRegistrar registrar;
286 registrar.Add(this, chrome::NOTIFICATION_HISTORY_LOADED,
287 content::Source<Profile>(profile));
288 content::RunMessageLoop();
291 BookmarkModel* bookmark_model =
292 BookmarkModelFactory::GetForProfile(profile);
293 ASSERT_TRUE(bookmark_model);
294 test::WaitForBookmarkModelToLoad(bookmark_model);
296 GURL url(entry.url);
297 // Add everything in order of time. We don't want to have a time that
298 // is "right now" or it will nondeterministically appear in the results.
299 history_service->AddPageWithDetails(url, base::UTF8ToUTF16(entry.title),
300 entry.visit_count,
301 entry.typed_count, time, false,
302 history::SOURCE_BROWSED);
303 if (entry.starred)
304 bookmarks::AddIfNotBookmarked(bookmark_model, url, base::string16());
305 // Wait at least for the AddPageWithDetails() call to finish.
307 content::NotificationRegistrar registrar;
308 registrar.Add(this, chrome::NOTIFICATION_HISTORY_URLS_MODIFIED,
309 content::Source<Profile>(profile));
310 content::RunMessageLoop();
311 // We don't want to return until all observers have processed this
312 // notification, because some (e.g. the in-memory history database) may do
313 // something important. Since we don't know where in the observer list we
314 // stand, just spin the message loop once more to allow the current
315 // callstack to complete.
316 content::RunAllPendingInMessageLoop();
320 void SetupHistory() {
321 // Add enough history pages containing |kSearchText| to trigger
322 // open history page url in autocomplete result.
323 for (size_t i = 0; i < arraysize(kHistoryEntries); i++) {
324 // Add everything in order of time. We don't want to have a time that
325 // is "right now" or it will nondeterministically appear in the results.
326 Time t = Time::Now() - TimeDelta::FromHours(i + 1);
327 ASSERT_NO_FATAL_FAILURE(AddHistoryEntry(kHistoryEntries[i], t));
331 void SetupHostResolver() {
332 for (size_t i = 0; i < arraysize(kBlockedHostnames); ++i)
333 host_resolver()->AddSimulatedFailure(kBlockedHostnames[i]);
336 void SetupComponents() {
337 ASSERT_NO_FATAL_FAILURE(SetupHostResolver());
338 ASSERT_NO_FATAL_FAILURE(SetupSearchEngine());
339 ASSERT_NO_FATAL_FAILURE(SetupHistory());
342 virtual void Observe(int type,
343 const content::NotificationSource& source,
344 const content::NotificationDetails& details) override {
345 switch (type) {
346 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED:
347 case chrome::NOTIFICATION_TAB_PARENTED:
348 case chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY:
349 case chrome::NOTIFICATION_HISTORY_LOADED:
350 case chrome::NOTIFICATION_HISTORY_URLS_MODIFIED:
351 break;
352 default:
353 FAIL() << "Unexpected notification type";
355 base::MessageLoop::current()->Quit();
359 // Test if ctrl-* accelerators are workable in omnibox.
360 // See http://crbug.com/19193: omnibox blocks ctrl-* commands
362 // Flaky on interactive tests (dbg), http://crbug.com/69433
363 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, DISABLED_BrowserAccelerators) {
364 OmniboxView* omnibox_view = NULL;
365 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
367 int tab_count = browser()->tab_strip_model()->count();
369 // Create a new Tab.
370 chrome::NewTab(browser());
371 ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count + 1));
373 // Select the first Tab.
374 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_1, kCtrlOrCmdMask));
375 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
377 chrome::FocusLocationBar(browser());
379 // Select the second Tab.
380 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_2, kCtrlOrCmdMask));
381 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
383 chrome::FocusLocationBar(browser());
385 // Try ctrl-w to close a Tab.
386 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_W, kCtrlOrCmdMask));
387 ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count));
389 // Try ctrl-l to focus location bar.
390 omnibox_view->SetUserText(ASCIIToUTF16("Hello world"));
391 EXPECT_FALSE(omnibox_view->IsSelectAll());
392 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_L, kCtrlOrCmdMask));
393 EXPECT_TRUE(omnibox_view->IsSelectAll());
395 // Try editing the location bar text.
396 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RIGHT, 0));
397 EXPECT_FALSE(omnibox_view->IsSelectAll());
398 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_S, 0));
399 EXPECT_EQ(ASCIIToUTF16("Hello worlds"), omnibox_view->GetText());
401 // Try ctrl-x to cut text.
402 #if defined(OS_MACOSX)
403 // Mac uses alt-left/right to select a word.
404 ASSERT_NO_FATAL_FAILURE(
405 SendKey(ui::VKEY_LEFT, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN));
406 #else
407 ASSERT_NO_FATAL_FAILURE(
408 SendKey(ui::VKEY_LEFT, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN));
409 #endif
410 EXPECT_FALSE(omnibox_view->IsSelectAll());
411 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_X, kCtrlOrCmdMask));
412 EXPECT_EQ(ASCIIToUTF16("Hello "), omnibox_view->GetText());
414 #if !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
415 // Try alt-f4 to close the browser.
416 ASSERT_TRUE(SendKeyAndWait(
417 browser(), ui::VKEY_F4, ui::EF_ALT_DOWN,
418 chrome::NOTIFICATION_BROWSER_CLOSED,
419 content::Source<Browser>(browser())));
420 #endif
423 // Flakily fails and times out on Win only. http://crbug.com/69941
424 // Fails on Linux. http://crbug.com/408634
425 #if defined(OS_WIN) || defined(OS_LINUX)
426 #define MAYBE_PopupAccelerators DISABLED_PopupAccelerators
427 #else
428 #define MAYBE_PopupAccelerators PopupAccelerators
429 #endif
431 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, MAYBE_PopupAccelerators) {
432 // Create a popup.
433 Browser* popup = CreateBrowserForPopup(browser()->profile());
434 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(popup));
435 OmniboxView* omnibox_view = NULL;
436 ASSERT_NO_FATAL_FAILURE(
437 GetOmniboxViewForBrowser(popup, &omnibox_view));
438 chrome::FocusLocationBar(popup);
439 EXPECT_TRUE(omnibox_view->IsSelectAll());
441 #if !defined(OS_MACOSX)
442 // Try ctrl-w to close the popup.
443 // This piece of code doesn't work on Mac, because the Browser object won't
444 // be destroyed before finishing the current message loop iteration, thus
445 // No BROWSER_CLOSED notification will be sent.
446 ASSERT_TRUE(SendKeyAndWait(
447 popup, ui::VKEY_W, ui::EF_CONTROL_DOWN,
448 chrome::NOTIFICATION_BROWSER_CLOSED, content::Source<Browser>(popup)));
450 // Create another popup.
451 popup = CreateBrowserForPopup(browser()->profile());
452 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(popup));
453 ASSERT_NO_FATAL_FAILURE(
454 GetOmniboxViewForBrowser(popup, &omnibox_view));
455 #endif
457 // Set the edit text to "Hello world".
458 omnibox_view->SetUserText(ASCIIToUTF16("Hello world"));
459 chrome::FocusLocationBar(popup);
460 EXPECT_TRUE(omnibox_view->IsSelectAll());
462 // Try editing the location bar text -- should be disallowed.
463 ASSERT_NO_FATAL_FAILURE(SendKeyForBrowser(popup, ui::VKEY_S, 0));
464 EXPECT_EQ(ASCIIToUTF16("Hello world"), omnibox_view->GetText());
465 EXPECT_TRUE(omnibox_view->IsSelectAll());
467 ASSERT_NO_FATAL_FAILURE(
468 SendKeyForBrowser(popup, ui::VKEY_X, kCtrlOrCmdMask));
469 EXPECT_EQ(ASCIIToUTF16("Hello world"), omnibox_view->GetText());
470 EXPECT_TRUE(omnibox_view->IsSelectAll());
472 #if !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
473 // Try alt-f4 to close the popup.
474 ASSERT_TRUE(SendKeyAndWait(
475 popup, ui::VKEY_F4, ui::EF_ALT_DOWN,
476 chrome::NOTIFICATION_BROWSER_CLOSED, content::Source<Browser>(popup)));
477 #endif
480 // http://crbug.com/133341
481 #if defined(OS_LINUX)
482 #define MAYBE_BackspaceInKeywordMode DISABLED_BackspaceInKeywordMode
483 #else
484 #define MAYBE_BackspaceInKeywordMode BackspaceInKeywordMode
485 #endif
487 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, MAYBE_BackspaceInKeywordMode) {
488 OmniboxView* omnibox_view = NULL;
489 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
491 // Trigger keyword hint mode.
492 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
493 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
494 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(omnibox_view->model()->keyword()));
496 // Trigger keyword mode.
497 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
498 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
499 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(omnibox_view->model()->keyword()));
501 // Backspace without search text should bring back keyword hint mode.
502 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
503 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
504 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(omnibox_view->model()->keyword()));
506 // Trigger keyword mode again.
507 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
508 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
509 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(omnibox_view->model()->keyword()));
511 // Input something as search text.
512 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
514 // Should stay in keyword mode while deleting search text by pressing
515 // backspace.
516 for (size_t i = 0; i < arraysize(kSearchText) - 1; ++i) {
517 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
518 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
519 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(omnibox_view->model()->keyword()));
522 // Input something as search text.
523 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
525 // Move cursor to the beginning of the search text.
526 #if defined(OS_MACOSX)
527 // Home doesn't work on Mac trybot.
528 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, ui::EF_CONTROL_DOWN));
529 #else
530 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_HOME, 0));
531 #endif
532 // Backspace at the beginning of the search text shall turn off
533 // the keyword mode.
534 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
535 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
536 ASSERT_EQ(base::string16(), omnibox_view->model()->keyword());
537 ASSERT_EQ(std::string(kSearchKeyword) + kSearchText,
538 UTF16ToUTF8(omnibox_view->GetText()));
541 // http://crbug.com/158913
542 #if defined(USE_AURA)
543 #define MAYBE_Escape DISABLED_Escape
544 #else
545 #define MAYBE_Escape Escape
546 #endif
548 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, MAYBE_Escape) {
549 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIHistoryURL));
550 chrome::FocusLocationBar(browser());
552 OmniboxView* omnibox_view = NULL;
553 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
555 base::string16 old_text = omnibox_view->GetText();
556 EXPECT_FALSE(old_text.empty());
557 EXPECT_TRUE(omnibox_view->IsSelectAll());
559 // Delete all text in omnibox.
560 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
561 EXPECT_TRUE(omnibox_view->GetText().empty());
563 // Escape shall revert the text in omnibox.
564 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_ESCAPE, 0));
565 EXPECT_EQ(old_text, omnibox_view->GetText());
566 EXPECT_TRUE(omnibox_view->IsSelectAll());
568 #undef MAYBE_ESCAPE
570 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, DesiredTLD) {
571 OmniboxView* omnibox_view = NULL;
572 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
573 OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
574 ASSERT_TRUE(popup_model);
576 // Test ctrl-Enter.
577 const ui::KeyboardCode kKeys[] = {
578 ui::VKEY_B, ui::VKEY_A, ui::VKEY_R, ui::VKEY_UNKNOWN
580 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kKeys));
581 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
582 ASSERT_TRUE(popup_model->IsOpen());
583 // ctrl-Enter triggers desired_tld feature, thus www.bar.com shall be
584 // opened.
585 ASSERT_TRUE(SendKeyAndWait(browser(), ui::VKEY_RETURN, ui::EF_CONTROL_DOWN,
586 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
587 content::Source<content::NavigationController>(
588 &browser()->tab_strip_model()->GetActiveWebContents()->
589 GetController())));
591 GURL url = browser()->tab_strip_model()->GetActiveWebContents()->GetURL();
592 EXPECT_EQ("www.bar.com", url.host());
593 EXPECT_EQ("/", url.path());
596 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, DesiredTLDWithTemporaryText) {
597 OmniboxView* omnibox_view = NULL;
598 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
599 OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
600 ASSERT_TRUE(popup_model);
602 Profile* profile = browser()->profile();
603 TemplateURLService* template_url_service =
604 TemplateURLServiceFactory::GetForProfile(profile);
606 // Add a non-substituting keyword. This ensures the popup will have a
607 // non-verbatim entry with "ab" as a prefix. This way, by arrowing down, we
608 // can set "abc" as temporary text in the omnibox.
609 TemplateURLData data;
610 data.short_name = ASCIIToUTF16("abc");
611 data.SetKeyword(ASCIIToUTF16(kSearchText));
612 data.SetURL("http://abc.com/");
613 template_url_service->Add(new TemplateURL(data));
615 // Send "ab", so that an "abc" entry appears in the popup.
616 const ui::KeyboardCode kSearchTextPrefixKeys[] = {
617 ui::VKEY_A, ui::VKEY_B, ui::VKEY_UNKNOWN
619 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextPrefixKeys));
620 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
621 ASSERT_TRUE(popup_model->IsOpen());
623 // Arrow down to the "abc" entry in the popup.
624 size_t size = popup_model->result().size();
625 while (popup_model->selected_line() < size - 1) {
626 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DOWN, 0));
627 if (omnibox_view->GetText() == ASCIIToUTF16("abc"))
628 break;
630 ASSERT_EQ(ASCIIToUTF16("abc"), omnibox_view->GetText());
632 // Hitting ctrl-enter should navigate based on the current text rather than
633 // the original input, i.e. to www.abc.com instead of www.ab.com.
634 ASSERT_TRUE(SendKeyAndWait(
635 browser(), ui::VKEY_RETURN, ui::EF_CONTROL_DOWN,
636 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
637 content::Source<content::NavigationController>(
638 &browser()->tab_strip_model()->GetActiveWebContents()->
639 GetController())));
641 GURL url(browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
642 EXPECT_EQ("www.abc.com", url.host());
643 EXPECT_EQ("/", url.path());
646 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, AltEnter) {
647 OmniboxView* omnibox_view = NULL;
648 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
650 omnibox_view->SetUserText(ASCIIToUTF16(chrome::kChromeUIHistoryURL));
651 int tab_count = browser()->tab_strip_model()->count();
652 // alt-Enter opens a new tab.
653 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN, ui::EF_ALT_DOWN));
654 ASSERT_NO_FATAL_FAILURE(WaitForTabOpenOrClose(tab_count + 1));
657 // http://crbug.com/133354, http://crbug.com/146953
658 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, DISABLED_EnterToSearch) {
659 OmniboxView* omnibox_view = NULL;
660 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
661 OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
662 ASSERT_TRUE(popup_model);
664 // Test Enter to search.
665 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
666 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
667 ASSERT_TRUE(popup_model->IsOpen());
669 // Check if the default match result is Search Primary Provider.
670 ASSERT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
671 popup_model->result().default_match()->type);
673 // Open the default match.
674 ASSERT_TRUE(SendKeyAndWait(browser(), ui::VKEY_RETURN, 0,
675 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
676 content::Source<content::NavigationController>(
677 &browser()->tab_strip_model()->GetActiveWebContents()->
678 GetController())));
679 GURL url = browser()->tab_strip_model()->GetActiveWebContents()->GetURL();
680 EXPECT_EQ(kSearchTextURL, url.spec());
682 // Test that entering a single character then Enter performs a search.
683 const ui::KeyboardCode kSearchSingleCharKeys[] = {
684 ui::VKEY_Z, ui::VKEY_UNKNOWN
686 chrome::FocusLocationBar(browser());
687 EXPECT_TRUE(omnibox_view->IsSelectAll());
688 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchSingleCharKeys));
689 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
690 ASSERT_TRUE(popup_model->IsOpen());
691 EXPECT_EQ("z", UTF16ToUTF8(omnibox_view->GetText()));
693 // Check if the default match result is Search Primary Provider.
694 ASSERT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
695 popup_model->result().default_match()->type);
697 // Open the default match.
698 ASSERT_TRUE(SendKeyAndWait(browser(), ui::VKEY_RETURN, 0,
699 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
700 content::Source<content::NavigationController>(
701 &browser()->tab_strip_model()->GetActiveWebContents()->
702 GetController())));
703 url = browser()->tab_strip_model()->GetActiveWebContents()->GetURL();
704 EXPECT_EQ("http://www.foo.com/search?q=z", url.spec());
707 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, EscapeToDefaultMatch) {
708 OmniboxView* omnibox_view = NULL;
709 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
710 OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
711 ASSERT_TRUE(popup_model);
713 // Input something to trigger inline autocomplete.
714 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys));
715 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
716 ASSERT_TRUE(popup_model->IsOpen());
718 base::string16 old_text = omnibox_view->GetText();
720 // Make sure inline autocomplete is triggerred.
721 EXPECT_GT(old_text.length(), arraysize(kInlineAutocompleteText) - 1);
723 size_t old_selected_line = popup_model->selected_line();
724 EXPECT_EQ(0U, old_selected_line);
726 // Move to another line with different text.
727 size_t size = popup_model->result().size();
728 while (popup_model->selected_line() < size - 1) {
729 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DOWN, 0));
730 ASSERT_NE(old_selected_line, popup_model->selected_line());
731 if (old_text != omnibox_view->GetText())
732 break;
735 EXPECT_NE(old_text, omnibox_view->GetText());
737 // Escape shall revert back to the default match item.
738 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_ESCAPE, 0));
739 EXPECT_EQ(old_text, omnibox_view->GetText());
740 EXPECT_EQ(old_selected_line, popup_model->selected_line());
743 // Flaky on Windows: http://crbug.com/146619
744 #if defined(OS_WIN)
745 #define MAYBE_BasicTextOperations DISABLED_BasicTextOperations
746 #else
747 #define MAYBE_BasicTextOperations BasicTextOperations
748 #endif
750 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, MAYBE_BasicTextOperations) {
751 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
752 chrome::FocusLocationBar(browser());
754 OmniboxView* omnibox_view = NULL;
755 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
757 base::string16 old_text = omnibox_view->GetText();
758 EXPECT_EQ(base::UTF8ToUTF16(url::kAboutBlankURL), old_text);
759 EXPECT_TRUE(omnibox_view->IsSelectAll());
761 size_t start, end;
762 omnibox_view->GetSelectionBounds(&start, &end);
763 #if defined(OS_WIN) || defined(OS_LINUX)
764 // Views textfields select-all in reverse to show the leading text.
765 std::swap(start, end);
766 #endif
767 EXPECT_EQ(0U, start);
768 EXPECT_EQ(old_text.size(), end);
770 // Move the cursor to the end.
771 #if defined(OS_MACOSX)
772 // End doesn't work on Mac trybot.
773 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_E, ui::EF_CONTROL_DOWN));
774 #else
775 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_END, 0));
776 #endif
777 EXPECT_FALSE(omnibox_view->IsSelectAll());
779 // Make sure the cursor is placed correctly.
780 omnibox_view->GetSelectionBounds(&start, &end);
781 EXPECT_EQ(old_text.size(), start);
782 EXPECT_EQ(old_text.size(), end);
784 // Insert one character at the end. Make sure we won't insert
785 // anything after the special ZWS mark used in gtk implementation.
786 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, 0));
787 EXPECT_EQ(old_text + base::char16('a'), omnibox_view->GetText());
789 // Delete one character from the end. Make sure we won't delete the special
790 // ZWS mark used in gtk implementation.
791 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
792 EXPECT_EQ(old_text, omnibox_view->GetText());
794 omnibox_view->SelectAll(true);
795 EXPECT_TRUE(omnibox_view->IsSelectAll());
796 omnibox_view->GetSelectionBounds(&start, &end);
797 #if defined(OS_WIN) || defined(OS_LINUX)
798 // Views textfields select-all in reverse to show the leading text.
799 std::swap(start, end);
800 #endif
801 EXPECT_EQ(0U, start);
802 EXPECT_EQ(old_text.size(), end);
804 // Delete the content
805 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DELETE, 0));
806 EXPECT_TRUE(omnibox_view->IsSelectAll());
807 omnibox_view->GetSelectionBounds(&start, &end);
808 EXPECT_EQ(0U, start);
809 EXPECT_EQ(0U, end);
810 EXPECT_TRUE(omnibox_view->GetText().empty());
812 // Check if RevertAll() can set text and cursor correctly.
813 omnibox_view->RevertAll();
814 EXPECT_FALSE(omnibox_view->IsSelectAll());
815 EXPECT_EQ(old_text, omnibox_view->GetText());
816 omnibox_view->GetSelectionBounds(&start, &end);
817 EXPECT_EQ(old_text.size(), start);
818 EXPECT_EQ(old_text.size(), end);
821 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, AcceptKeywordBySpace) {
822 OmniboxView* omnibox_view = NULL;
823 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
825 base::string16 search_keyword(ASCIIToUTF16(kSearchKeyword));
827 // Trigger keyword hint mode.
828 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
829 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
830 ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
831 ASSERT_EQ(search_keyword, omnibox_view->GetText());
833 // Trigger keyword mode by space.
834 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
835 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
836 ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
837 ASSERT_TRUE(omnibox_view->GetText().empty());
839 // Revert to keyword hint mode.
840 omnibox_view->model()->ClearKeyword(base::string16());
841 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
842 ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
843 ASSERT_EQ(search_keyword, omnibox_view->GetText());
845 // Keyword should also be accepted by typing an ideographic space.
846 omnibox_view->OnBeforePossibleChange();
847 omnibox_view->SetWindowTextAndCaretPos(search_keyword +
848 base::WideToUTF16(L"\x3000"), search_keyword.length() + 1, false, false);
849 omnibox_view->OnAfterPossibleChange();
850 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
851 ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
852 ASSERT_TRUE(omnibox_view->GetText().empty());
854 // Revert to keyword hint mode.
855 omnibox_view->model()->ClearKeyword(base::string16());
856 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
857 ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
858 ASSERT_EQ(search_keyword, omnibox_view->GetText());
860 // Keyword shouldn't be accepted by pressing space with a trailing
861 // whitespace.
862 omnibox_view->SetWindowTextAndCaretPos(search_keyword + base::char16(' '),
863 search_keyword.length() + 1, false, false);
864 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
865 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
866 ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
867 ASSERT_EQ(search_keyword + ASCIIToUTF16(" "), omnibox_view->GetText());
869 // Keyword shouldn't be accepted by deleting the trailing space.
870 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
871 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
872 ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
873 ASSERT_EQ(search_keyword + base::char16(' '), omnibox_view->GetText());
875 // Keyword shouldn't be accepted by pressing space before a trailing space.
876 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
877 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
878 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
879 ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
880 ASSERT_EQ(search_keyword + ASCIIToUTF16(" "), omnibox_view->GetText());
882 // Keyword should be accepted by pressing space in the middle of context and
883 // just after the keyword.
884 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
885 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, 0));
886 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
887 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
888 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
889 ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
890 ASSERT_EQ(ASCIIToUTF16("a "), omnibox_view->GetText());
891 size_t start, end;
892 omnibox_view->GetSelectionBounds(&start, &end);
893 EXPECT_EQ(0U, start);
894 EXPECT_EQ(0U, end);
896 // Keyword shouldn't be accepted by pasting "foo bar".
897 omnibox_view->SetUserText(base::string16());
898 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
899 ASSERT_TRUE(omnibox_view->model()->keyword().empty());
901 omnibox_view->OnBeforePossibleChange();
902 omnibox_view->model()->OnPaste();
903 omnibox_view->SetWindowTextAndCaretPos(search_keyword +
904 ASCIIToUTF16(" bar"), search_keyword.length() + 4, false, false);
905 omnibox_view->OnAfterPossibleChange();
906 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
907 ASSERT_TRUE(omnibox_view->model()->keyword().empty());
908 ASSERT_EQ(search_keyword + ASCIIToUTF16(" bar"), omnibox_view->GetText());
910 // Keyword shouldn't be accepted for case like: "foo b|ar" -> "foo b |ar".
911 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
912 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
913 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
914 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
915 ASSERT_TRUE(omnibox_view->model()->keyword().empty());
916 ASSERT_EQ(search_keyword + ASCIIToUTF16(" b ar"), omnibox_view->GetText());
918 // Keyword could be accepted by pressing space with a selected range at the
919 // end of text.
920 omnibox_view->OnBeforePossibleChange();
921 omnibox_view->OnInlineAutocompleteTextMaybeChanged(
922 search_keyword + ASCIIToUTF16(" "), search_keyword.length());
923 omnibox_view->OnAfterPossibleChange();
924 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
925 ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
926 ASSERT_EQ(search_keyword + ASCIIToUTF16(" "), omnibox_view->GetText());
928 omnibox_view->GetSelectionBounds(&start, &end);
929 ASSERT_NE(start, end);
930 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
931 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
932 ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
933 ASSERT_EQ(base::string16(), omnibox_view->GetText());
935 // Space should accept keyword even when inline autocomplete is available.
936 omnibox_view->SetUserText(base::string16());
937 const TestHistoryEntry kHistoryFoobar = {
938 "http://www.foobar.com", "Page foobar", 100, 100, true
941 // Add a history entry to trigger inline autocomplete when typing "foo".
942 ASSERT_NO_FATAL_FAILURE(
943 AddHistoryEntry(kHistoryFoobar, Time::Now() - TimeDelta::FromHours(1)));
945 // Type "fo" to trigger inline autocomplete.
946 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordPrefixKeys));
947 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
948 ASSERT_TRUE(omnibox_view->model()->popup_model()->IsOpen());
949 ASSERT_NE(search_keyword, omnibox_view->GetText());
951 // Keyword hint shouldn't be visible.
952 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
953 ASSERT_TRUE(omnibox_view->model()->keyword().empty());
955 // Add the "o". Inline autocompletion should still happen, but now we
956 // should also get a keyword hint because we've typed a keyword exactly.
957 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordCompletionKeys));
958 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
959 ASSERT_TRUE(omnibox_view->model()->popup_model()->IsOpen());
960 ASSERT_NE(search_keyword, omnibox_view->GetText());
961 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
962 ASSERT_FALSE(omnibox_view->model()->keyword().empty());
964 // Trigger keyword mode by space.
965 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
966 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
967 ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
968 ASSERT_TRUE(omnibox_view->GetText().empty());
970 // Space in the middle of a temporary text, which separates the text into
971 // keyword and replacement portions, should trigger keyword mode.
972 omnibox_view->SetUserText(base::string16());
973 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
974 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
975 OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
976 ASSERT_TRUE(popup_model->IsOpen());
977 ASSERT_EQ(ASCIIToUTF16("foobar.com"), omnibox_view->GetText());
978 omnibox_view->model()->OnUpOrDownKeyPressed(1);
979 omnibox_view->model()->OnUpOrDownKeyPressed(-1);
980 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
981 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
982 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
983 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
984 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
985 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
986 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, 0));
987 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
988 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
989 ASSERT_EQ(search_keyword, omnibox_view->model()->keyword());
990 ASSERT_EQ(ASCIIToUTF16("bar.com"), omnibox_view->GetText());
992 // Space after temporary text that looks like a keyword, when the original
993 // input does not look like a keyword, should trigger keyword mode.
994 omnibox_view->SetUserText(base::string16());
995 const TestHistoryEntry kHistoryFoo = {
996 "http://footest.com", "Page footest", 1000, 1000, true
999 // Add a history entry to trigger HQP matching with text == keyword when
1000 // typing "fo te".
1001 ASSERT_NO_FATAL_FAILURE(
1002 AddHistoryEntry(kHistoryFoo, Time::Now() - TimeDelta::FromMinutes(10)));
1004 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_F, 0));
1005 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_O, 0));
1006 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
1007 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_T, 0));
1008 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_E, 0));
1009 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1010 ASSERT_TRUE(popup_model->IsOpen());
1011 base::string16 search_keyword2(ASCIIToUTF16(kSearchKeyword2));
1012 while ((omnibox_view->GetText() != search_keyword2) &&
1013 (popup_model->selected_line() < popup_model->result().size() - 1))
1014 omnibox_view->model()->OnUpOrDownKeyPressed(1);
1015 ASSERT_EQ(search_keyword2, omnibox_view->GetText());
1016 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_SPACE, 0));
1017 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
1018 ASSERT_EQ(search_keyword2, omnibox_view->model()->keyword());
1019 ASSERT_TRUE(omnibox_view->GetText().empty());
1022 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, NonSubstitutingKeywordTest) {
1023 OmniboxView* omnibox_view = NULL;
1024 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1025 OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
1026 ASSERT_TRUE(popup_model);
1028 Profile* profile = browser()->profile();
1029 TemplateURLService* template_url_service =
1030 TemplateURLServiceFactory::GetForProfile(profile);
1032 // Add a non-default substituting keyword.
1033 TemplateURLData data;
1034 data.short_name = ASCIIToUTF16("Search abc");
1035 data.SetKeyword(ASCIIToUTF16(kSearchText));
1036 data.SetURL("http://abc.com/{searchTerms}");
1037 TemplateURL* template_url = new TemplateURL(data);
1038 template_url_service->Add(template_url);
1040 omnibox_view->SetUserText(base::string16());
1042 // Non-default substituting keyword shouldn't be matched by default.
1043 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
1044 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1045 ASSERT_TRUE(popup_model->IsOpen());
1047 // Check if the default match result is Search Primary Provider.
1048 ASSERT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
1049 popup_model->result().default_match()->type);
1050 ASSERT_EQ(kSearchTextURL,
1051 popup_model->result().default_match()->destination_url.spec());
1053 omnibox_view->SetUserText(base::string16());
1054 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1055 ASSERT_FALSE(popup_model->IsOpen());
1057 // Try a non-substituting keyword.
1058 template_url_service->Remove(template_url);
1059 data.short_name = ASCIIToUTF16("abc");
1060 data.SetURL("http://abc.com/");
1061 template_url_service->Add(new TemplateURL(data));
1063 // We always allow exact matches for non-substituting keywords.
1064 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
1065 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1066 ASSERT_TRUE(popup_model->IsOpen());
1067 ASSERT_EQ(AutocompleteMatchType::HISTORY_KEYWORD,
1068 popup_model->result().default_match()->type);
1069 ASSERT_EQ("http://abc.com/",
1070 popup_model->result().default_match()->destination_url.spec());
1073 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, DeleteItem) {
1074 // Disable the search provider, to make sure the popup contains only history
1075 // items.
1076 TemplateURLService* model =
1077 TemplateURLServiceFactory::GetForProfile(browser()->profile());
1078 model->SetUserSelectedDefaultSearchProvider(NULL);
1080 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
1081 chrome::FocusLocationBar(browser());
1083 OmniboxView* omnibox_view = NULL;
1084 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1086 OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
1087 ASSERT_TRUE(popup_model);
1089 base::string16 old_text = omnibox_view->GetText();
1091 // Input something that can match history items.
1092 omnibox_view->SetUserText(ASCIIToUTF16("site.com/p"));
1093 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1094 ASSERT_TRUE(popup_model->IsOpen());
1096 // Delete the inline autocomplete part.
1097 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DELETE, 0));
1098 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1099 ASSERT_TRUE(popup_model->IsOpen());
1100 ASSERT_GE(popup_model->result().size(), 3U);
1102 base::string16 user_text = omnibox_view->GetText();
1103 ASSERT_EQ(ASCIIToUTF16("site.com/p"), user_text);
1104 omnibox_view->SelectAll(true);
1105 ASSERT_TRUE(omnibox_view->IsSelectAll());
1107 // Move down.
1108 size_t default_line = popup_model->selected_line();
1109 omnibox_view->model()->OnUpOrDownKeyPressed(1);
1110 ASSERT_EQ(default_line + 1, popup_model->selected_line());
1111 base::string16 selected_text =
1112 popup_model->result().match_at(default_line + 1).fill_into_edit;
1113 // Temporary text is shown.
1114 ASSERT_EQ(selected_text, omnibox_view->GetText());
1115 ASSERT_FALSE(omnibox_view->IsSelectAll());
1117 // Delete the item.
1118 popup_model->TryDeletingCurrentItem();
1119 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1120 // The selected line shouldn't be changed, because we have more than two
1121 // items.
1122 ASSERT_EQ(default_line + 1, popup_model->selected_line());
1123 // Make sure the item is really deleted.
1124 ASSERT_NE(selected_text,
1125 popup_model->result().match_at(default_line + 1).fill_into_edit);
1126 selected_text =
1127 popup_model->result().match_at(default_line + 1).fill_into_edit;
1128 // New temporary text is shown.
1129 ASSERT_EQ(selected_text, omnibox_view->GetText());
1131 // Revert to the default match.
1132 ASSERT_TRUE(omnibox_view->model()->OnEscapeKeyPressed());
1133 ASSERT_EQ(default_line, popup_model->selected_line());
1134 ASSERT_EQ(user_text, omnibox_view->GetText());
1135 ASSERT_TRUE(omnibox_view->IsSelectAll());
1137 // Move down and up to select the default match as temporary text.
1138 omnibox_view->model()->OnUpOrDownKeyPressed(1);
1139 ASSERT_EQ(default_line + 1, popup_model->selected_line());
1140 omnibox_view->model()->OnUpOrDownKeyPressed(-1);
1141 ASSERT_EQ(default_line, popup_model->selected_line());
1143 selected_text = popup_model->result().match_at(default_line).fill_into_edit;
1144 // New temporary text is shown.
1145 ASSERT_EQ(selected_text, omnibox_view->GetText());
1146 ASSERT_FALSE(omnibox_view->IsSelectAll());
1148 #if 0
1149 // TODO(mrossetti): http://crbug.com/82335
1150 // Delete the default item.
1151 popup_model->TryDeletingCurrentItem();
1152 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1153 // The selected line shouldn't be changed, but the default item should have
1154 // been changed.
1155 ASSERT_EQ(default_line, popup_model->selected_line());
1156 // Make sure the item is really deleted.
1157 EXPECT_NE(selected_text,
1158 popup_model->result().match_at(default_line).fill_into_edit);
1159 selected_text =
1160 popup_model->result().match_at(default_line).fill_into_edit;
1161 // New temporary text is shown.
1162 ASSERT_EQ(selected_text, omnibox_view->GetText());
1163 #endif
1165 // As the current selected item is the new default item, pressing Escape key
1166 // should revert all directly.
1167 ASSERT_TRUE(omnibox_view->model()->OnEscapeKeyPressed());
1168 ASSERT_EQ(old_text, omnibox_view->GetText());
1169 ASSERT_TRUE(omnibox_view->IsSelectAll());
1172 // http://crbug.com/133344
1173 #if defined(OS_LINUX)
1174 #define MAYBE_TabAcceptKeyword DISABLED_TabAcceptKeyword
1175 #else
1176 #define MAYBE_TabAcceptKeyword TabAcceptKeyword
1177 #endif
1179 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, MAYBE_TabAcceptKeyword) {
1180 OmniboxView* omnibox_view = NULL;
1181 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1183 base::string16 text = ASCIIToUTF16(kSearchKeyword);
1185 // Trigger keyword hint mode.
1186 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
1187 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
1188 ASSERT_EQ(text, omnibox_view->model()->keyword());
1189 ASSERT_EQ(text, omnibox_view->GetText());
1191 // Trigger keyword mode by tab.
1192 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
1193 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
1194 ASSERT_EQ(text, omnibox_view->model()->keyword());
1195 ASSERT_TRUE(omnibox_view->GetText().empty());
1197 // Revert to keyword hint mode.
1198 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
1199 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
1200 ASSERT_EQ(text, omnibox_view->model()->keyword());
1201 ASSERT_EQ(text, omnibox_view->GetText());
1203 // The location bar should still have focus.
1204 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
1206 // Trigger keyword mode by tab.
1207 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
1208 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
1209 ASSERT_EQ(text, omnibox_view->model()->keyword());
1210 ASSERT_TRUE(omnibox_view->GetText().empty());
1212 // Revert to keyword hint mode with SHIFT+TAB.
1213 #if defined(OS_MACOSX)
1214 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACKTAB, 0));
1215 #else
1216 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN));
1217 #endif
1218 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
1219 ASSERT_EQ(text, omnibox_view->model()->keyword());
1220 ASSERT_EQ(text, omnibox_view->GetText());
1221 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
1224 #if !defined(OS_MACOSX)
1225 // Mac intentionally does not support this behavior.
1227 // http://crbug.com/133360
1228 #if defined(OS_LINUX)
1229 #define MAYBE_TabTraverseResultsTest DISABLED_TabTraverseResultsTest
1230 #else
1231 #define MAYBE_TabTraverseResultsTest TabTraverseResultsTest
1232 #endif
1234 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, MAYBE_TabTraverseResultsTest) {
1235 OmniboxView* omnibox_view = NULL;
1236 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1237 OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
1238 ASSERT_TRUE(popup_model);
1240 // Input something to trigger results.
1241 const ui::KeyboardCode kKeys[] = {
1242 ui::VKEY_B, ui::VKEY_A, ui::VKEY_R, ui::VKEY_UNKNOWN
1244 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kKeys));
1245 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1246 ASSERT_TRUE(popup_model->IsOpen());
1248 size_t old_selected_line = popup_model->selected_line();
1249 EXPECT_EQ(0U, old_selected_line);
1251 // Move down the results.
1252 for (size_t size = popup_model->result().size();
1253 popup_model->selected_line() < size - 1;
1254 old_selected_line = popup_model->selected_line()) {
1255 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
1256 ASSERT_LT(old_selected_line, popup_model->selected_line());
1259 // Don't move past the end.
1260 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
1261 ASSERT_EQ(old_selected_line, popup_model->selected_line());
1262 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
1264 // Move back up the results.
1265 for (; popup_model->selected_line() > 0U;
1266 old_selected_line = popup_model->selected_line()) {
1267 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN));
1268 ASSERT_GT(old_selected_line, popup_model->selected_line());
1271 // Don't move past the beginning.
1272 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN));
1273 ASSERT_EQ(0U, popup_model->selected_line());
1274 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
1276 const TestHistoryEntry kHistoryFoo = {
1277 "http://foo/", "Page foo", 1, 1, false
1280 // Add a history entry so "foo" gets multiple matches.
1281 ASSERT_NO_FATAL_FAILURE(
1282 AddHistoryEntry(kHistoryFoo, Time::Now() - TimeDelta::FromHours(1)));
1284 // Load results.
1285 ASSERT_NO_FATAL_FAILURE(omnibox_view->SelectAll(false));
1286 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
1287 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1289 // Trigger keyword mode by tab.
1290 base::string16 text = ASCIIToUTF16(kSearchKeyword);
1291 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
1292 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
1293 ASSERT_EQ(text, omnibox_view->model()->keyword());
1294 ASSERT_TRUE(omnibox_view->GetText().empty());
1296 // The location bar should still have focus.
1297 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
1299 // Pressing tab again should move to the next result and clear keyword
1300 // mode.
1301 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
1302 ASSERT_EQ(1U, omnibox_view->model()->popup_model()->selected_line());
1303 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
1304 ASSERT_NE(text, omnibox_view->model()->keyword());
1306 // The location bar should still have focus.
1307 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
1309 // Moving back up should not show keyword mode.
1310 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN));
1311 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
1312 ASSERT_EQ(text, omnibox_view->model()->keyword());
1314 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
1316 #endif
1319 // http://crbug.com/133347
1320 #if defined(OS_LINUX)
1321 #define MAYBE_PersistKeywordModeOnTabSwitch DISABLED_PersistKeywordModeOnTabSwitch
1322 #else
1323 #define MAYBE_PersistKeywordModeOnTabSwitch PersistKeywordModeOnTabSwitch
1324 #endif
1326 IN_PROC_BROWSER_TEST_F(OmniboxViewTest,
1327 MAYBE_PersistKeywordModeOnTabSwitch) {
1328 OmniboxView* omnibox_view = NULL;
1329 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1331 // Trigger keyword hint mode.
1332 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
1333 ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
1334 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(omnibox_view->model()->keyword()));
1336 // Trigger keyword mode.
1337 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_TAB, 0));
1338 ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
1339 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(omnibox_view->model()->keyword()));
1341 // Input something as search text.
1342 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
1344 // Create a new tab.
1345 chrome::NewTab(browser());
1347 // Switch back to the first tab.
1348 browser()->tab_strip_model()->ActivateTabAt(0, true);
1350 // Make sure we're still in keyword mode.
1351 ASSERT_EQ(kSearchKeyword, UTF16ToUTF8(omnibox_view->model()->keyword()));
1354 // http://crbug.com/133355
1355 #if defined(OS_LINUX)
1356 #define MAYBE_CtrlKeyPressedWithInlineAutocompleteTest DISABLED_CtrlKeyPressedWithInlineAutocompleteTest
1357 #else
1358 #define MAYBE_CtrlKeyPressedWithInlineAutocompleteTest CtrlKeyPressedWithInlineAutocompleteTest
1359 #endif
1361 IN_PROC_BROWSER_TEST_F(OmniboxViewTest,
1362 MAYBE_CtrlKeyPressedWithInlineAutocompleteTest) {
1363 OmniboxView* omnibox_view = NULL;
1364 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1365 OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
1366 ASSERT_TRUE(popup_model);
1368 // Input something to trigger inline autocomplete.
1369 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys));
1370 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1371 ASSERT_TRUE(popup_model->IsOpen());
1373 base::string16 old_text = omnibox_view->GetText();
1375 // Make sure inline autocomplete is triggerred.
1376 EXPECT_GT(old_text.length(), arraysize(kInlineAutocompleteText) - 1);
1378 // Press ctrl key.
1379 omnibox_view->model()->OnControlKeyChanged(true);
1381 // Inline autocomplete should still be there.
1382 EXPECT_EQ(old_text, omnibox_view->GetText());
1385 #if defined(TOOLKIT_VIEWS)
1386 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, UndoRedo) {
1387 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
1388 chrome::FocusLocationBar(browser());
1390 OmniboxView* omnibox_view = NULL;
1391 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1393 base::string16 old_text = omnibox_view->GetText();
1394 EXPECT_EQ(base::UTF8ToUTF16(url::kAboutBlankURL), old_text);
1395 EXPECT_TRUE(omnibox_view->IsSelectAll());
1397 // Delete the text, then undo.
1398 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
1399 EXPECT_TRUE(omnibox_view->GetText().empty());
1400 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN));
1401 EXPECT_EQ(old_text, omnibox_view->GetText());
1403 // Redo should delete the text again.
1404 ASSERT_NO_FATAL_FAILURE(
1405 SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN));
1406 EXPECT_TRUE(omnibox_view->GetText().empty());
1408 // Looks like the undo manager doesn't support restoring selection.
1409 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN));
1410 EXPECT_FALSE(omnibox_view->IsSelectAll());
1412 // The cursor should be at the end.
1413 size_t start, end;
1414 omnibox_view->GetSelectionBounds(&start, &end);
1415 EXPECT_EQ(old_text.size(), start);
1416 EXPECT_EQ(old_text.size(), end);
1418 // Delete three characters; "about:bl" should not trigger inline autocomplete.
1419 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
1420 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
1421 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
1422 EXPECT_EQ(old_text.substr(0, old_text.size() - 3), omnibox_view->GetText());
1424 // Undo delete.
1425 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN));
1426 EXPECT_EQ(old_text, omnibox_view->GetText());
1428 // Redo delete.
1429 ASSERT_NO_FATAL_FAILURE(
1430 SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN));
1431 EXPECT_EQ(old_text.substr(0, old_text.size() - 3), omnibox_view->GetText());
1433 // Delete everything.
1434 omnibox_view->SelectAll(true);
1435 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
1436 EXPECT_TRUE(omnibox_view->GetText().empty());
1438 // Undo delete everything.
1439 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN));
1440 EXPECT_EQ(old_text.substr(0, old_text.size() - 3), omnibox_view->GetText());
1442 // Undo delete two characters.
1443 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_Z, ui::EF_CONTROL_DOWN));
1444 EXPECT_EQ(old_text, omnibox_view->GetText());
1447 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, BackspaceDeleteHalfWidthKatakana) {
1448 OmniboxView* omnibox_view = NULL;
1449 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1450 // Insert text: ダ
1451 omnibox_view->SetUserText(base::UTF8ToUTF16("\357\276\200\357\276\236"));
1453 // Move the cursor to the end.
1454 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_END, 0));
1456 // Backspace should delete one character.
1457 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
1458 EXPECT_EQ(base::UTF8ToUTF16("\357\276\200"), omnibox_view->GetText());
1460 #endif // defined(TOOLKIT_VIEWS)
1462 // Flaky test. crbug.com/356850
1463 IN_PROC_BROWSER_TEST_F(OmniboxViewTest,
1464 DISABLED_DoesNotUpdateAutocompleteOnBlur) {
1465 OmniboxView* omnibox_view = NULL;
1466 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1467 OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
1468 ASSERT_TRUE(popup_model);
1470 // Input something to trigger inline autocomplete.
1471 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys));
1472 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1473 ASSERT_TRUE(popup_model->IsOpen());
1474 size_t start, end;
1475 omnibox_view->GetSelectionBounds(&start, &end);
1476 EXPECT_TRUE(start != end);
1477 base::string16 old_autocomplete_text =
1478 omnibox_view->model()->autocomplete_controller()->input_.text();
1480 // Unfocus the omnibox. This should clear the text field selection and
1481 // close the popup, but should not run autocomplete.
1482 // Note: GTK preserves the selection when the omnibox is unfocused.
1483 ui_test_utils::ClickOnView(browser(), VIEW_ID_TAB_CONTAINER);
1484 ASSERT_FALSE(popup_model->IsOpen());
1485 omnibox_view->GetSelectionBounds(&start, &end);
1486 EXPECT_TRUE(start == end);
1488 EXPECT_EQ(old_autocomplete_text,
1489 omnibox_view->model()->autocomplete_controller()->input_.text());
1492 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, Paste) {
1493 OmniboxView* omnibox_view = NULL;
1494 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1495 OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
1496 ASSERT_TRUE(popup_model);
1497 EXPECT_FALSE(popup_model->IsOpen());
1499 // Paste should yield the expected text and open the popup.
1500 SetClipboardText(ASCIIToUTF16(kSearchText));
1501 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_V, kCtrlOrCmdMask));
1502 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1503 EXPECT_EQ(ASCIIToUTF16(kSearchText), omnibox_view->GetText());
1504 EXPECT_TRUE(popup_model->IsOpen());
1506 // Close the popup and select all.
1507 omnibox_view->CloseOmniboxPopup();
1508 omnibox_view->SelectAll(false);
1509 EXPECT_FALSE(popup_model->IsOpen());
1511 // Pasting the same text again over itself should re-open the popup.
1512 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_V, kCtrlOrCmdMask));
1513 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1514 EXPECT_EQ(ASCIIToUTF16(kSearchText), omnibox_view->GetText());
1515 EXPECT_TRUE(popup_model->IsOpen());
1516 omnibox_view->CloseOmniboxPopup();
1517 EXPECT_FALSE(popup_model->IsOpen());
1519 // Pasting amid text should yield the expected text and re-open the popup.
1520 omnibox_view->SetWindowTextAndCaretPos(ASCIIToUTF16("abcd"), 2, false, false);
1521 SetClipboardText(ASCIIToUTF16("123"));
1522 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_V, kCtrlOrCmdMask));
1523 EXPECT_EQ(ASCIIToUTF16("ab123cd"), omnibox_view->GetText());
1524 EXPECT_TRUE(popup_model->IsOpen());
1526 // Ctrl/Cmd+Alt+V should not paste.
1527 ASSERT_NO_FATAL_FAILURE(
1528 SendKey(ui::VKEY_V, kCtrlOrCmdMask | ui::EF_ALT_DOWN));
1529 EXPECT_EQ(ASCIIToUTF16("ab123cd"), omnibox_view->GetText());
1530 // TODO(msw): Test that AltGr+V does not paste.
1533 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, CopyURLToClipboard) {
1534 // Set permanent text thus making sure that omnibox treats 'google.com'
1535 // as URL (not as ordinary user input).
1536 TestToolbarModel* test_toolbar_model = new TestToolbarModel;
1537 scoped_ptr<ToolbarModel> toolbar_model(test_toolbar_model);
1538 test_toolbar_model->set_text(ASCIIToUTF16("http://www.google.com/"));
1539 browser()->swap_toolbar_models(&toolbar_model);
1540 OmniboxView* omnibox_view = NULL;
1541 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1542 OmniboxEditModel* edit_model = omnibox_view->model();
1543 ASSERT_NE(static_cast<OmniboxEditModel*>(NULL), edit_model);
1544 edit_model->UpdatePermanentText();
1546 const char* target_url = "http://www.google.com/calendar";
1547 omnibox_view->SetUserText(ASCIIToUTF16(target_url));
1549 // Location bar must have focus.
1550 chrome::FocusLocationBar(browser());
1551 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
1553 // Select full URL and copy it to clipboard. General text and html should
1554 // be available.
1555 omnibox_view->SelectAll(true);
1556 EXPECT_TRUE(omnibox_view->IsSelectAll());
1557 ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
1558 clipboard->Clear(ui::CLIPBOARD_TYPE_COPY_PASTE);
1559 EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_COPY));
1560 EXPECT_EQ(ASCIIToUTF16(target_url), omnibox_view->GetText());
1561 EXPECT_TRUE(clipboard->IsFormatAvailable(
1562 ui::Clipboard::GetPlainTextFormatType(), ui::CLIPBOARD_TYPE_COPY_PASTE));
1564 // Make sure HTML format isn't written. See
1565 // BookmarkNodeData::WriteToClipboard() for details.
1566 EXPECT_FALSE(clipboard->IsFormatAvailable(
1567 ui::Clipboard::GetHtmlFormatType(), ui::CLIPBOARD_TYPE_COPY_PASTE));
1569 // These platforms should read bookmark format.
1570 #if defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_MACOSX)
1571 base::string16 title;
1572 std::string url;
1573 clipboard->ReadBookmark(&title, &url);
1574 EXPECT_EQ(target_url, url);
1575 EXPECT_EQ(ASCIIToUTF16(target_url), title);
1576 #endif
1579 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, CutURLToClipboard) {
1580 // Set permanent text thus making sure that omnibox treats 'google.com'
1581 // as URL (not as ordinary user input).
1582 TestToolbarModel* test_toolbar_model = new TestToolbarModel;
1583 scoped_ptr<ToolbarModel> toolbar_model(test_toolbar_model);
1584 test_toolbar_model->set_text(ASCIIToUTF16("http://www.google.com/"));
1585 browser()->swap_toolbar_models(&toolbar_model);
1586 OmniboxView* omnibox_view = NULL;
1587 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1588 OmniboxEditModel* edit_model = omnibox_view->model();
1589 ASSERT_NE(static_cast<OmniboxEditModel*>(NULL), edit_model);
1590 edit_model->UpdatePermanentText();
1592 const char* target_url = "http://www.google.com/calendar";
1593 omnibox_view->SetUserText(ASCIIToUTF16(target_url));
1595 // Location bar must have focus.
1596 chrome::FocusLocationBar(browser());
1597 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
1599 // Select full URL and cut it. General text and html should be available
1600 // in the clipboard.
1601 omnibox_view->SelectAll(true);
1602 EXPECT_TRUE(omnibox_view->IsSelectAll());
1603 ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
1604 clipboard->Clear(ui::CLIPBOARD_TYPE_COPY_PASTE);
1605 EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_CUT));
1606 EXPECT_EQ(base::string16(), omnibox_view->GetText());
1607 EXPECT_TRUE(clipboard->IsFormatAvailable(
1608 ui::Clipboard::GetPlainTextFormatType(), ui::CLIPBOARD_TYPE_COPY_PASTE));
1610 // Make sure HTML format isn't written. See
1611 // BookmarkNodeData::WriteToClipboard() for details.
1612 EXPECT_FALSE(clipboard->IsFormatAvailable(
1613 ui::Clipboard::GetHtmlFormatType(), ui::CLIPBOARD_TYPE_COPY_PASTE));
1615 // These platforms should read bookmark format.
1616 #if defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_MACOSX)
1617 base::string16 title;
1618 std::string url;
1619 clipboard->ReadBookmark(&title, &url);
1620 EXPECT_EQ(target_url, url);
1621 EXPECT_EQ(ASCIIToUTF16(target_url), title);
1622 #endif
1625 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, CopyTextToClipboard) {
1626 OmniboxView* omnibox_view = NULL;
1627 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1628 const char* target_text = "foo";
1629 omnibox_view->SetUserText(ASCIIToUTF16(target_text));
1631 // Location bar must have focus.
1632 chrome::FocusLocationBar(browser());
1633 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
1635 // Select full text and copy it to the clipboard.
1636 omnibox_view->SelectAll(true);
1637 EXPECT_TRUE(omnibox_view->IsSelectAll());
1638 ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
1639 clipboard->Clear(ui::CLIPBOARD_TYPE_COPY_PASTE);
1640 EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_COPY));
1641 EXPECT_TRUE(clipboard->IsFormatAvailable(
1642 ui::Clipboard::GetPlainTextFormatType(), ui::CLIPBOARD_TYPE_COPY_PASTE));
1643 EXPECT_FALSE(clipboard->IsFormatAvailable(
1644 ui::Clipboard::GetHtmlFormatType(), ui::CLIPBOARD_TYPE_COPY_PASTE));
1645 EXPECT_EQ(ASCIIToUTF16(target_text), omnibox_view->GetText());
1648 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, CutTextToClipboard) {
1649 OmniboxView* omnibox_view = NULL;
1650 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1651 const char* target_text = "foo";
1652 omnibox_view->SetUserText(ASCIIToUTF16(target_text));
1654 // Location bar must have focus.
1655 chrome::FocusLocationBar(browser());
1656 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
1658 // Select full text and cut it to the clipboard.
1659 omnibox_view->SelectAll(true);
1660 EXPECT_TRUE(omnibox_view->IsSelectAll());
1661 ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
1662 clipboard->Clear(ui::CLIPBOARD_TYPE_COPY_PASTE);
1663 EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_CUT));
1664 EXPECT_TRUE(clipboard->IsFormatAvailable(
1665 ui::Clipboard::GetPlainTextFormatType(), ui::CLIPBOARD_TYPE_COPY_PASTE));
1666 EXPECT_FALSE(clipboard->IsFormatAvailable(
1667 ui::Clipboard::GetHtmlFormatType(), ui::CLIPBOARD_TYPE_COPY_PASTE));
1668 EXPECT_EQ(base::string16(), omnibox_view->GetText());
1671 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, EditSearchEngines) {
1672 // Disable settings-in-a-window to simplify test.
1673 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1674 ::switches::kDisableSettingsWindow);
1675 OmniboxView* omnibox_view = NULL;
1676 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1677 EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_EDIT_SEARCH_ENGINES));
1678 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1679 const std::string target_url =
1680 std::string(chrome::kChromeUISettingsURL) + chrome::kSearchEnginesSubPage;
1681 EXPECT_EQ(ASCIIToUTF16(target_url), omnibox_view->GetText());
1682 EXPECT_FALSE(omnibox_view->model()->popup_model()->IsOpen());
1685 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, BeginningShownAfterBlur) {
1686 OmniboxView* omnibox_view = NULL;
1687 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1689 omnibox_view->OnBeforePossibleChange();
1690 omnibox_view->SetWindowTextAndCaretPos(ASCIIToUTF16("data:text/plain,test"),
1691 5U, false, false);
1692 omnibox_view->OnAfterPossibleChange();
1693 EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
1694 size_t start, end;
1695 omnibox_view->GetSelectionBounds(&start, &end);
1696 EXPECT_EQ(5U, start);
1697 EXPECT_EQ(5U, end);
1699 ui_test_utils::FocusView(browser(), VIEW_ID_TAB_CONTAINER);
1700 EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
1702 omnibox_view->GetSelectionBounds(&start, &end);
1703 EXPECT_EQ(0U, start);
1704 EXPECT_EQ(0U, end);
1707 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, CtrlArrowAfterArrowSuggestions) {
1708 OmniboxView* omnibox_view = NULL;
1709 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1710 OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
1711 ASSERT_TRUE(popup_model);
1713 // Input something to trigger results.
1714 const ui::KeyboardCode kKeys[] = {
1715 ui::VKEY_B, ui::VKEY_A, ui::VKEY_R, ui::VKEY_UNKNOWN
1717 ASSERT_NO_FATAL_FAILURE(SendKeySequence(kKeys));
1718 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1719 ASSERT_TRUE(popup_model->IsOpen());
1721 ASSERT_EQ(ASCIIToUTF16("bar.com/1"), omnibox_view->GetText());
1723 // Arrow down on a suggestion, and omnibox text should be the suggestion.
1724 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DOWN, 0));
1725 ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
1726 ASSERT_EQ(ASCIIToUTF16("www.bar.com/2"), omnibox_view->GetText());
1728 // Highlight the last 2 words and the omnibox text should not change.
1729 // Simulating Ctrl-shift-left only once does not seem to highlight anything
1730 // on Linux.
1731 #if defined(OS_MACOSX)
1732 // Mac uses alt-left/right to select a word.
1733 const int modifiers = ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN;
1734 #else
1735 const int modifiers = ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN;
1736 #endif
1737 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, modifiers));
1738 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_LEFT, modifiers));
1739 ASSERT_EQ(ASCIIToUTF16("www.bar.com/2"), omnibox_view->GetText());
1742 IN_PROC_BROWSER_TEST_F(OmniboxViewTest,
1743 PersistSearchReplacementAcrossTabSwitch) {
1744 EXPECT_TRUE(browser()->toolbar_model()->url_replacement_enabled());
1745 browser()->toolbar_model()->set_url_replacement_enabled(false);
1747 // Create a new tab.
1748 chrome::NewTab(browser());
1749 EXPECT_TRUE(browser()->toolbar_model()->url_replacement_enabled());
1751 // Switch back to the first tab.
1752 browser()->tab_strip_model()->ActivateTabAt(0, true);
1753 EXPECT_FALSE(browser()->toolbar_model()->url_replacement_enabled());
1756 IN_PROC_BROWSER_TEST_F(OmniboxViewTest,
1757 DontUpdateURLWhileSearchTermReplacementIsDisabled) {
1758 OmniboxView* omnibox_view = NULL;
1759 ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
1760 TestToolbarModel* test_toolbar_model = new TestToolbarModel;
1761 scoped_ptr<ToolbarModel> toolbar_model(test_toolbar_model);
1762 browser()->swap_toolbar_models(&toolbar_model);
1764 base::string16 url_a(ASCIIToUTF16("http://www.a.com/"));
1765 base::string16 url_b(ASCIIToUTF16("http://www.b.com/"));
1766 base::string16 url_c(ASCIIToUTF16("http://www.c.com/"));
1767 chrome::FocusLocationBar(browser());
1768 test_toolbar_model->set_text(url_a);
1769 omnibox_view->Update();
1770 EXPECT_EQ(url_a, omnibox_view->GetText());
1772 // Disable URL replacement and update. Because the omnibox has focus, the
1773 // visible text shouldn't change; see comments in
1774 // OmniboxEditModel::UpdatePermanentText().
1775 browser()->toolbar_model()->set_url_replacement_enabled(false);
1776 test_toolbar_model->set_text(url_b);
1777 omnibox_view->Update();
1778 EXPECT_EQ(url_a, omnibox_view->GetText());
1780 // Re-enable URL replacement and ensure updating changes the text.
1781 browser()->toolbar_model()->set_url_replacement_enabled(true);
1782 // We have to change the toolbar model text here, or Update() will do nothing.
1783 // This is because the previous update already updated the permanent text.
1784 test_toolbar_model->set_text(url_c);
1785 omnibox_view->Update();
1786 EXPECT_EQ(url_c, omnibox_view->GetText());
1788 // The same test, but using RevertAll() to reset search term replacement.
1789 test_toolbar_model->set_text(url_a);
1790 omnibox_view->Update();
1791 EXPECT_EQ(url_a, omnibox_view->GetText());
1792 browser()->toolbar_model()->set_url_replacement_enabled(false);
1793 test_toolbar_model->set_text(url_b);
1794 omnibox_view->Update();
1795 EXPECT_EQ(url_a, omnibox_view->GetText());
1796 omnibox_view->RevertAll();
1797 EXPECT_EQ(url_b, omnibox_view->GetText());
1798 test_toolbar_model->set_text(url_c);
1799 omnibox_view->Update();
1800 EXPECT_EQ(url_c, omnibox_view->GetText());
1803 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, EscDisablesSearchTermReplacement) {
1804 browser()->toolbar_model()->set_url_replacement_enabled(true);
1805 chrome::FocusLocationBar(browser());
1806 ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_ESCAPE, 0));
1807 EXPECT_FALSE(browser()->toolbar_model()->url_replacement_enabled());