1 // Copyright (c) 2013 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 "chrome/browser/ui/views/omnibox/omnibox_view_views.h" 6 7 #include "chrome/browser/ui/browser.h" 8 #include "chrome/browser/ui/browser_commands.h" 9 #include "chrome/browser/ui/browser_window.h" 10 #include "chrome/browser/ui/omnibox/location_bar.h" 11 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h" 12 #include "chrome/browser/ui/view_ids.h" 13 #include "chrome/browser/ui/views/frame/browser_view.h" 14 #include "chrome/test/base/in_process_browser_test.h" 15 #include "chrome/test/base/interactive_test_utils.h" 16 #include "grit/generated_resources.h" 17 #include "ui/base/clipboard/clipboard.h" 18 #include "ui/base/clipboard/scoped_clipboard_writer.h" 19 #include "ui/base/test/ui_controls.h" 20 #include "ui/views/controls/textfield/native_textfield_wrapper.h" 21 22 #if defined(USE_AURA) 23 #include "ui/aura/root_window.h" 24 #include "ui/aura/window.h" 25 #include "ui/aura/window_tree_host_delegate.h" 26 #endif // defined(USE_AURA) 27 28 class OmniboxViewViewsTest : public InProcessBrowserTest { 29 protected: 30 OmniboxViewViewsTest() {} 31 32 static void GetOmniboxViewForBrowser(const Browser* browser, 33 OmniboxView** omnibox_view) { 34 BrowserWindow* window = browser->window(); 35 ASSERT_TRUE(window); 36 LocationBar* location_bar = window->GetLocationBar(); 37 ASSERT_TRUE(location_bar); 38 *omnibox_view = location_bar->GetOmniboxView(); 39 ASSERT_TRUE(*omnibox_view); 40 } 41 42 // Move the mouse to the center of the browser window and left-click. 43 void ClickBrowserWindowCenter() { 44 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync( 45 BrowserView::GetBrowserViewForBrowser( 46 browser())->GetBoundsInScreen().CenterPoint())); 47 ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(ui_controls::LEFT, 48 ui_controls::DOWN)); 49 ASSERT_TRUE( 50 ui_test_utils::SendMouseEventsSync(ui_controls::LEFT, ui_controls::UP)); 51 } 52 53 // Press and release the mouse at the specified locations. If 54 // |release_offset| differs from |press_offset|, the mouse will be moved 55 // between the press and release. 56 void Click(ui_controls::MouseButton button, 57 const gfx::Point& press_location, 58 const gfx::Point& release_location) { 59 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(press_location)); 60 ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(button, ui_controls::DOWN)); 61 62 if (press_location != release_location) 63 ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(release_location)); 64 ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(button, ui_controls::UP)); 65 } 66 67 #if defined(USE_AURA) 68 // Tap the center of the browser window. 69 void TapBrowserWindowCenter() { 70 aura::RootWindowHostDelegate* rwhd = 71 browser()->window()->GetNativeWindow()->GetRootWindow()-> 72 GetDispatcher()->AsRootWindowHostDelegate(); 73 74 gfx::Point center = BrowserView::GetBrowserViewForBrowser( 75 browser())->GetBoundsInScreen().CenterPoint(); 76 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, center, 77 5, base::TimeDelta::FromMilliseconds(0)); 78 rwhd->OnHostTouchEvent(&press); 79 80 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, center, 81 5, base::TimeDelta::FromMilliseconds(50)); 82 rwhd->OnHostTouchEvent(&release); 83 } 84 85 // Touch down and release at the specified locations. 86 void Tap(const gfx::Point& press_location, 87 const gfx::Point& release_location) { 88 aura::RootWindowHostDelegate* rwhd = 89 browser()->window()->GetNativeWindow()->GetRootWindow()-> 90 GetDispatcher()->AsRootWindowHostDelegate(); 91 92 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, press_location, 93 5, base::TimeDelta::FromMilliseconds(0)); 94 rwhd->OnHostTouchEvent(&press); 95 96 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, release_location, 97 5, base::TimeDelta::FromMilliseconds(50)); 98 rwhd->OnHostTouchEvent(&release); 99 } 100 #endif // defined(USE_AURA) 101 102 private: 103 // InProcessBrowserTest: 104 virtual void SetUpOnMainThread() OVERRIDE { 105 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 106 chrome::FocusLocationBar(browser()); 107 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 108 } 109 110 DISALLOW_COPY_AND_ASSIGN(OmniboxViewViewsTest); 111 }; 112 113 IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, PasteAndGoDoesNotLeavePopupOpen) { 114 OmniboxView* view = browser()->window()->GetLocationBar()->GetOmniboxView(); 115 OmniboxViewViews* omnibox_view_views = static_cast<OmniboxViewViews*>(view); 116 views::NativeTextfieldWrapper* native_textfield_wrapper = 117 static_cast<views::NativeTextfieldWrapper*>( 118 omnibox_view_views->GetNativeWrapperForTesting()); 119 if (!native_textfield_wrapper) 120 return; 121 122 // Put an URL on the clipboard. 123 { 124 ui::ScopedClipboardWriter clipboard_writer( 125 ui::Clipboard::GetForCurrentThread(), ui::CLIPBOARD_TYPE_COPY_PASTE); 126 clipboard_writer.WriteURL(ASCIIToUTF16("http://www.example.com/")); 127 } 128 129 // Paste and go. 130 native_textfield_wrapper->ExecuteTextCommand(IDS_PASTE_AND_GO); 131 132 // The popup should not be open. 133 EXPECT_FALSE(view->model()->popup_model()->IsOpen()); 134 } 135 136 IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, SelectAllOnClick) { 137 OmniboxView* omnibox_view = NULL; 138 ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &omnibox_view)); 139 omnibox_view->SetUserText(ASCIIToUTF16("http://www.google.com/")); 140 141 // Take the focus away from the omnibox. 142 ASSERT_NO_FATAL_FAILURE(ClickBrowserWindowCenter()); 143 EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 144 EXPECT_FALSE(omnibox_view->IsSelectAll()); 145 146 // Clicking in the omnibox should take focus and select all text. 147 const gfx::Rect omnibox_bounds = BrowserView::GetBrowserViewForBrowser( 148 browser())->GetViewByID(VIEW_ID_OMNIBOX)->GetBoundsInScreen(); 149 const gfx::Point click_location = omnibox_bounds.CenterPoint(); 150 ASSERT_NO_FATAL_FAILURE(Click(ui_controls::LEFT, 151 click_location, click_location)); 152 EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 153 EXPECT_TRUE(omnibox_view->IsSelectAll()); 154 155 // Clicking in another view should clear focus and the selection. 156 ASSERT_NO_FATAL_FAILURE(ClickBrowserWindowCenter()); 157 EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 158 EXPECT_FALSE(omnibox_view->IsSelectAll()); 159 160 // Clicking in the omnibox again should take focus and select all text again. 161 ASSERT_NO_FATAL_FAILURE(Click(ui_controls::LEFT, 162 click_location, click_location)); 163 EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 164 EXPECT_TRUE(omnibox_view->IsSelectAll()); 165 166 // Clicking another omnibox spot should keep focus but clear the selection. 167 omnibox_view->SelectAll(false); 168 const gfx::Point click2_location = omnibox_bounds.origin() + 169 gfx::Vector2d(omnibox_bounds.width() / 4, omnibox_bounds.height() / 4); 170 ASSERT_NO_FATAL_FAILURE(Click(ui_controls::LEFT, 171 click2_location, click2_location)); 172 EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 173 EXPECT_FALSE(omnibox_view->IsSelectAll()); 174 175 // Take the focus away and click in the omnibox again, but drag a bit before 176 // releasing. We should focus the omnibox but not select all of its text. 177 ASSERT_NO_FATAL_FAILURE(ClickBrowserWindowCenter()); 178 ASSERT_NO_FATAL_FAILURE(Click(ui_controls::LEFT, 179 click_location, click2_location)); 180 EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 181 EXPECT_FALSE(omnibox_view->IsSelectAll()); 182 183 // Middle-clicking should not be handled by the omnibox. 184 ASSERT_NO_FATAL_FAILURE(ClickBrowserWindowCenter()); 185 ASSERT_NO_FATAL_FAILURE(Click(ui_controls::MIDDLE, 186 click_location, click_location)); 187 EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 188 EXPECT_FALSE(omnibox_view->IsSelectAll()); 189 } 190 191 #if defined(USE_AURA) 192 IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, SelectAllOnTap) { 193 OmniboxView* omnibox_view = NULL; 194 ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &omnibox_view)); 195 omnibox_view->SetUserText(ASCIIToUTF16("http://www.google.com/")); 196 197 // Take the focus away from the omnibox. 198 ASSERT_NO_FATAL_FAILURE(TapBrowserWindowCenter()); 199 EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 200 EXPECT_FALSE(omnibox_view->IsSelectAll()); 201 202 // Tapping in the omnibox should take focus and select all text. 203 const gfx::Rect omnibox_bounds = BrowserView::GetBrowserViewForBrowser( 204 browser())->GetViewByID(VIEW_ID_OMNIBOX)->GetBoundsInScreen(); 205 const gfx::Point tap_location = omnibox_bounds.CenterPoint(); 206 ASSERT_NO_FATAL_FAILURE(Tap(tap_location, tap_location)); 207 EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 208 EXPECT_TRUE(omnibox_view->IsSelectAll()); 209 210 // Tapping in another view should clear focus and the selection. 211 ASSERT_NO_FATAL_FAILURE(TapBrowserWindowCenter()); 212 EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 213 EXPECT_FALSE(omnibox_view->IsSelectAll()); 214 215 // Tapping in the omnibox again should take focus and select all text again. 216 ASSERT_NO_FATAL_FAILURE(Tap(tap_location, tap_location)); 217 EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 218 EXPECT_TRUE(omnibox_view->IsSelectAll()); 219 220 // Tapping another omnibox spot should keep focus and selection. 221 omnibox_view->SelectAll(false); 222 const gfx::Point tap2_location = omnibox_bounds.origin() + 223 gfx::Vector2d(omnibox_bounds.width() / 4, omnibox_bounds.height() / 4); 224 ASSERT_NO_FATAL_FAILURE(Tap(tap2_location, tap2_location)); 225 EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 226 // We don't test if the all text is selected because it depends on whether or 227 // not there was text under the tap, which appears to be flaky. 228 229 // Take the focus away and tap in the omnibox again, but drag a bit before 230 // releasing. We should focus the omnibox but not select all of its text. 231 ASSERT_NO_FATAL_FAILURE(TapBrowserWindowCenter()); 232 ASSERT_NO_FATAL_FAILURE(Tap(tap_location, tap2_location)); 233 EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 234 EXPECT_FALSE(omnibox_view->IsSelectAll()); 235 } 236 #endif // defined(USE_AURA) 237