Home | History | Annotate | Download | only in omnibox
      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