66f6731e44cad8611b3f5ca29f5c53031243b46b
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / omnibox / omnibox_view_views_browsertest.cc
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 "base/command_line.h"
8 #include "chrome/browser/search_engines/template_url_service_factory.h"
9 #include "chrome/browser/ui/browser.h"
10 #include "chrome/browser/ui/browser_commands.h"
11 #include "chrome/browser/ui/browser_window.h"
12 #include "chrome/browser/ui/browser_window_testing_views.h"
13 #include "chrome/browser/ui/location_bar/location_bar.h"
14 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
15 #include "chrome/browser/ui/view_ids.h"
16 #include "chrome/browser/ui/views/frame/browser_view.h"
17 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
18 #include "chrome/grit/generated_resources.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "chrome/test/base/interactive_test_utils.h"
21 #include "ui/base/clipboard/clipboard.h"
22 #include "ui/base/clipboard/scoped_clipboard_writer.h"
23 #include "ui/base/ime/text_input_focus_manager.h"
24 #include "ui/base/test/ui_controls.h"
25 #include "ui/base/ui_base_switches.h"
26 #include "ui/events/event_processor.h"
27 #include "ui/events/event_utils.h"
28 #include "ui/events/test/event_generator.h"
29 #include "ui/views/controls/textfield/textfield_test_api.h"
30
31 class OmniboxViewViewsTest : public InProcessBrowserTest {
32  protected:
33   OmniboxViewViewsTest() {}
34
35   static void GetOmniboxViewForBrowser(const Browser* browser,
36                                        OmniboxView** omnibox_view) {
37     BrowserWindow* window = browser->window();
38     ASSERT_TRUE(window);
39     LocationBar* location_bar = window->GetLocationBar();
40     ASSERT_TRUE(location_bar);
41     *omnibox_view = location_bar->GetOmniboxView();
42     ASSERT_TRUE(*omnibox_view);
43   }
44
45   // Move the mouse to the center of the browser window and left-click.
46   void ClickBrowserWindowCenter() {
47     ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
48         BrowserView::GetBrowserViewForBrowser(
49             browser())->GetBoundsInScreen().CenterPoint()));
50     ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(ui_controls::LEFT,
51                                                    ui_controls::DOWN));
52     ASSERT_TRUE(
53         ui_test_utils::SendMouseEventsSync(ui_controls::LEFT, ui_controls::UP));
54   }
55
56   // Press and release the mouse at the specified locations.  If
57   // |release_offset| differs from |press_offset|, the mouse will be moved
58   // between the press and release.
59   void Click(ui_controls::MouseButton button,
60              const gfx::Point& press_location,
61              const gfx::Point& release_location) {
62     ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(press_location));
63     ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(button, ui_controls::DOWN));
64
65     if (press_location != release_location)
66       ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(release_location));
67     ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(button, ui_controls::UP));
68   }
69
70   // Tap the center of the browser window.
71   void TapBrowserWindowCenter() {
72     gfx::Point center = BrowserView::GetBrowserViewForBrowser(
73         browser())->GetBoundsInScreen().CenterPoint();
74     ui::test::EventGenerator generator(browser()->window()->GetNativeWindow());
75     generator.GestureTapAt(center);
76   }
77
78   // Touch down and release at the specified locations.
79   void Tap(const gfx::Point& press_location,
80            const gfx::Point& release_location) {
81     ui::test::EventGenerator generator(browser()->window()->GetNativeWindow());
82     if (press_location == release_location) {
83       generator.GestureTapAt(press_location);
84     } else {
85       generator.GestureScrollSequence(press_location,
86                                       release_location,
87                                       base::TimeDelta::FromMilliseconds(10),
88                                       1);
89     }
90   }
91
92  private:
93   // InProcessBrowserTest:
94   virtual void SetUpOnMainThread() OVERRIDE {
95     ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
96     chrome::FocusLocationBar(browser());
97     ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
98   }
99
100   DISALLOW_COPY_AND_ASSIGN(OmniboxViewViewsTest);
101 };
102
103 IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, PasteAndGoDoesNotLeavePopupOpen) {
104   OmniboxView* view = NULL;
105   ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &view));
106   OmniboxViewViews* omnibox_view_views = static_cast<OmniboxViewViews*>(view);
107
108   // Put an URL on the clipboard.
109   {
110     ui::ScopedClipboardWriter clipboard_writer(
111         ui::Clipboard::GetForCurrentThread(), ui::CLIPBOARD_TYPE_COPY_PASTE);
112     clipboard_writer.WriteURL(base::ASCIIToUTF16("http://www.example.com/"));
113   }
114
115   // Paste and go.
116   omnibox_view_views->ExecuteCommand(IDS_PASTE_AND_GO, ui::EF_NONE);
117
118   // The popup should not be open.
119   EXPECT_FALSE(view->model()->popup_model()->IsOpen());
120 }
121
122 IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, SelectAllOnClick) {
123   OmniboxView* omnibox_view = NULL;
124   ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &omnibox_view));
125   omnibox_view->SetUserText(base::ASCIIToUTF16("http://www.google.com/"));
126
127   // Take the focus away from the omnibox.
128   ASSERT_NO_FATAL_FAILURE(ClickBrowserWindowCenter());
129   EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
130   EXPECT_FALSE(omnibox_view->IsSelectAll());
131
132   // Clicking in the omnibox should take focus and select all text.
133   const gfx::Rect omnibox_bounds = BrowserView::GetBrowserViewForBrowser(
134         browser())->GetViewByID(VIEW_ID_OMNIBOX)->GetBoundsInScreen();
135   const gfx::Point click_location = omnibox_bounds.CenterPoint();
136   ASSERT_NO_FATAL_FAILURE(Click(ui_controls::LEFT,
137                                 click_location, click_location));
138   EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
139   EXPECT_TRUE(omnibox_view->IsSelectAll());
140
141   // Clicking in another view should clear focus and the selection.
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 again should take focus and select all text again.
147   ASSERT_NO_FATAL_FAILURE(Click(ui_controls::LEFT,
148                                 click_location, click_location));
149   EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
150   EXPECT_TRUE(omnibox_view->IsSelectAll());
151
152   // Clicking another omnibox spot should keep focus but clear the selection.
153   omnibox_view->SelectAll(false);
154   const gfx::Point click2_location = omnibox_bounds.origin() +
155       gfx::Vector2d(omnibox_bounds.width() / 4, omnibox_bounds.height() / 4);
156   ASSERT_NO_FATAL_FAILURE(Click(ui_controls::LEFT,
157                                 click2_location, click2_location));
158   EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
159   EXPECT_FALSE(omnibox_view->IsSelectAll());
160
161   // Take the focus away and click in the omnibox again, but drag a bit before
162   // releasing.  We should focus the omnibox but not select all of its text.
163   ASSERT_NO_FATAL_FAILURE(ClickBrowserWindowCenter());
164   ASSERT_NO_FATAL_FAILURE(Click(ui_controls::LEFT,
165                                 click_location, click2_location));
166   EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
167   EXPECT_FALSE(omnibox_view->IsSelectAll());
168
169   // Middle-clicking should not be handled by the omnibox.
170   ASSERT_NO_FATAL_FAILURE(ClickBrowserWindowCenter());
171   ASSERT_NO_FATAL_FAILURE(Click(ui_controls::MIDDLE,
172                                 click_location, click_location));
173   EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
174   EXPECT_FALSE(omnibox_view->IsSelectAll());
175 }
176
177 IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, SelectAllOnTap) {
178   OmniboxView* omnibox_view = NULL;
179   ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &omnibox_view));
180   omnibox_view->SetUserText(base::ASCIIToUTF16("http://www.google.com/"));
181
182   // Take the focus away from the omnibox.
183   ASSERT_NO_FATAL_FAILURE(TapBrowserWindowCenter());
184   EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
185   EXPECT_FALSE(omnibox_view->IsSelectAll());
186
187   // Tapping in the omnibox should take focus and select all text.
188   const gfx::Rect omnibox_bounds = BrowserView::GetBrowserViewForBrowser(
189       browser())->GetViewByID(VIEW_ID_OMNIBOX)->GetBoundsInScreen();
190   const gfx::Point tap_location = omnibox_bounds.CenterPoint();
191   ASSERT_NO_FATAL_FAILURE(Tap(tap_location, tap_location));
192   EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
193   EXPECT_TRUE(omnibox_view->IsSelectAll());
194
195   // Tapping in another view should clear focus and the selection.
196   ASSERT_NO_FATAL_FAILURE(TapBrowserWindowCenter());
197   EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
198   EXPECT_FALSE(omnibox_view->IsSelectAll());
199
200   // Tapping in the omnibox again should take focus and select all text again.
201   ASSERT_NO_FATAL_FAILURE(Tap(tap_location, tap_location));
202   EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
203   EXPECT_TRUE(omnibox_view->IsSelectAll());
204
205   // Tapping another omnibox spot should keep focus and selection.
206   omnibox_view->SelectAll(false);
207   const gfx::Point tap2_location = omnibox_bounds.origin() +
208       gfx::Vector2d(omnibox_bounds.width() / 4, omnibox_bounds.height() / 4);
209   ASSERT_NO_FATAL_FAILURE(Tap(tap2_location, tap2_location));
210   EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
211   // We don't test if the all text is selected because it depends on whether or
212   // not there was text under the tap, which appears to be flaky.
213
214   // Take the focus away and tap in the omnibox again, but drag a bit before
215   // releasing.  We should focus the omnibox but not select all of its text.
216   ASSERT_NO_FATAL_FAILURE(TapBrowserWindowCenter());
217   ASSERT_NO_FATAL_FAILURE(Tap(tap_location, tap2_location));
218   EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
219   EXPECT_FALSE(omnibox_view->IsSelectAll());
220 }
221
222 IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, SelectAllOnTabToFocus) {
223   OmniboxView* omnibox_view = NULL;
224   ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &omnibox_view));
225   ui_test_utils::NavigateToURL(browser(), GURL("http://www.google.com/"));
226   // RevertAll after navigation to invalidate the selection range saved on blur.
227   omnibox_view->RevertAll();
228   EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
229   EXPECT_FALSE(omnibox_view->IsSelectAll());
230
231   // Pressing tab to focus the omnibox should select all text.
232   while (!ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)) {
233     ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_TAB,
234                                                 false, false, false, false));
235   }
236   EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
237   EXPECT_TRUE(omnibox_view->IsSelectAll());
238 }
239
240 IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, CloseOmniboxPopupOnTextDrag) {
241   OmniboxView* omnibox_view = NULL;
242   ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &omnibox_view));
243   OmniboxViewViews* omnibox_view_views =
244       static_cast<OmniboxViewViews*>(omnibox_view);
245
246   // Populate suggestions for the omnibox popup.
247   AutocompleteController* autocomplete_controller =
248       omnibox_view->model()->popup_model()->autocomplete_controller();
249   AutocompleteResult& results = autocomplete_controller->result_;
250   ACMatches matches;
251   AutocompleteMatch match;
252   match.destination_url = GURL("http://autocomplete-result/");
253   match.allowed_to_be_default_match = true;
254   match.type = AutocompleteMatchType::HISTORY_TITLE;
255   match.relevance = 500;
256   matches.push_back(match);
257   match.destination_url = GURL("http://autocomplete-result2/");
258   matches.push_back(match);
259   results.AppendMatches(matches);
260   results.SortAndCull(
261       AutocompleteInput(),
262       TemplateURLServiceFactory::GetForProfile(browser()->profile()));
263
264   // The omnibox popup should open with suggestions displayed.
265   omnibox_view->model()->popup_model()->OnResultChanged();
266   EXPECT_TRUE(omnibox_view->model()->popup_model()->IsOpen());
267
268   // The omnibox text should be selected.
269   EXPECT_TRUE(omnibox_view->IsSelectAll());
270
271   // Simulate a mouse click before dragging the mouse.
272   gfx::Point point(omnibox_view_views->x(), omnibox_view_views->y());
273   ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, point, point,
274                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
275   omnibox_view_views->OnMousePressed(pressed);
276   EXPECT_TRUE(omnibox_view->model()->popup_model()->IsOpen());
277
278   // Simulate a mouse drag of the omnibox text, and the omnibox should close.
279   ui::MouseEvent dragged(ui::ET_MOUSE_DRAGGED, point, point,
280                          ui::EF_LEFT_MOUSE_BUTTON, 0);
281   omnibox_view_views->OnMouseDragged(dragged);
282
283   EXPECT_FALSE(omnibox_view->model()->popup_model()->IsOpen());
284 }
285
286 IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, BackgroundIsOpaque) {
287   // The omnibox text should be rendered on an opaque background. Otherwise, we
288   // can't use subpixel rendering.
289   BrowserWindowTesting* window = browser()->window()->GetBrowserWindowTesting();
290   ASSERT_TRUE(window);
291   OmniboxViewViews* view = window->GetLocationBarView()->omnibox_view();
292   ASSERT_TRUE(view);
293   EXPECT_FALSE(view->GetRenderText()->background_is_transparent());
294 }
295
296 // Tests if executing a command hides touch editing handles.
297 IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest,
298                        DeactivateTouchEditingOnExecuteCommand) {
299   CommandLine::ForCurrentProcess()->AppendSwitch(switches::kEnableTouchEditing);
300
301   OmniboxView* view = NULL;
302   ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &view));
303   OmniboxViewViews* omnibox_view_views = static_cast<OmniboxViewViews*>(view);
304   views::TextfieldTestApi textfield_test_api(omnibox_view_views);
305
306   // Put a URL on the clipboard. It is written to the clipboard upon destruction
307   // of the writer.
308   {
309     ui::ScopedClipboardWriter clipboard_writer(
310         ui::Clipboard::GetForCurrentThread(),
311         ui::CLIPBOARD_TYPE_COPY_PASTE);
312     clipboard_writer.WriteURL(base::ASCIIToUTF16("http://www.example.com/"));
313   }
314
315   // Tap to activate touch editing.
316   gfx::Point omnibox_center =
317       omnibox_view_views->GetBoundsInScreen().CenterPoint();
318   Tap(omnibox_center, omnibox_center);
319   EXPECT_TRUE(textfield_test_api.touch_selection_controller());
320
321   // Execute a command and check if it deactivate touch editing. Paste & Go is
322   // chosen since it is specific to Omnibox and its execution wouldn't be
323   // delgated to the base Textfield class.
324   omnibox_view_views->ExecuteCommand(IDS_PASTE_AND_GO, ui::EF_NONE);
325   EXPECT_FALSE(textfield_test_api.touch_selection_controller());
326 }
327
328 IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, FocusedTextInputClient) {
329   base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
330   cmd_line->AppendSwitch(switches::kEnableTextInputFocusManager);
331
332   // TODO(yukishiino): The following call to FocusLocationBar is not necessary
333   // if the flag is enabled by default.  Remove the call once the transition to
334   // TextInputFocusManager completes.
335   chrome::FocusLocationBar(browser());
336   OmniboxView* view = NULL;
337   ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &view));
338   OmniboxViewViews* omnibox_view_views = static_cast<OmniboxViewViews*>(view);
339   ui::TextInputFocusManager* text_input_focus_manager =
340       ui::TextInputFocusManager::GetInstance();
341   EXPECT_EQ(omnibox_view_views->GetTextInputClient(),
342             text_input_focus_manager->GetFocusedTextInputClient());
343 }