Home | History | Annotate | Download | only in autofill
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/basictypes.h"
      6 #include "components/autofill/content/renderer/page_click_listener.h"
      7 #include "components/autofill/content/renderer/page_click_tracker.h"
      8 #include "content/public/renderer/render_view.h"
      9 #include "content/public/test/render_view_test.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 #include "third_party/WebKit/public/web/WebDocument.h"
     12 #include "third_party/WebKit/public/web/WebInputElement.h"
     13 #include "third_party/WebKit/public/web/WebView.h"
     14 #include "third_party/WebKit/public/platform/WebSize.h"
     15 #include "ui/events/keycodes/keyboard_codes.h"
     16 
     17 namespace autofill {
     18 
     19 class TestPageClickListener : public PageClickListener {
     20  public:
     21   TestPageClickListener()
     22       : input_element_clicked_called_(false),
     23         input_element_lost_focus_called_(false),
     24         was_focused_(false),
     25         is_focused_(false) {
     26   }
     27 
     28   virtual void InputElementClicked(const blink::WebInputElement& element,
     29                                    bool was_focused,
     30                                    bool is_focused) OVERRIDE {
     31     input_element_clicked_called_ = true;
     32     element_clicked_ = element;
     33     was_focused_ = was_focused;
     34     is_focused_ = is_focused;
     35   }
     36 
     37   virtual void InputElementLostFocus() OVERRIDE {
     38     input_element_lost_focus_called_ = true;
     39   }
     40 
     41   void ClearResults() {
     42     input_element_clicked_called_ = false;
     43     input_element_lost_focus_called_ = false;
     44     element_clicked_.reset();
     45     was_focused_ = false;
     46     is_focused_ = false;
     47   }
     48 
     49   bool input_element_clicked_called_;
     50   bool input_element_lost_focus_called_;
     51   blink::WebInputElement element_clicked_;
     52   bool was_focused_;
     53   bool is_focused_;
     54 };
     55 
     56 class PageClickTrackerTest : public content::RenderViewTest {
     57  protected:
     58   virtual void SetUp() OVERRIDE {
     59     content::RenderViewTest::SetUp();
     60 
     61     // RenderView creates PageClickTracker but it doesn't keep it around.
     62     // Rather than make it do so for the test, we create a new object.
     63     page_click_tracker_.reset(new PageClickTracker(view_, &test_listener_));
     64 
     65     LoadHTML("<form>"
     66              "  <input type='text' id='text_1'></input><br>"
     67              "  <input type='text' id='text_2'></input><br>"
     68              "  <input type='button' id='button'></input><br>"
     69              "</form>");
     70     GetWebWidget()->resize(blink::WebSize(500, 500));
     71     GetWebWidget()->setFocus(true);
     72     blink::WebDocument document = view_->GetWebView()->mainFrame()->document();
     73     text_ = document.getElementById("text_1");
     74     ASSERT_FALSE(text_.isNull());
     75   }
     76 
     77   virtual void TearDown() OVERRIDE {
     78     text_.reset();
     79     test_listener_.ClearResults();
     80     page_click_tracker_.reset();
     81     content::RenderViewTest::TearDown();
     82   }
     83 
     84   // Send all the messages required for a complete key press.
     85   void SendKeyPress(int key_code) {
     86     blink::WebKeyboardEvent keyboard_event;
     87     keyboard_event.windowsKeyCode = key_code;
     88     keyboard_event.setKeyIdentifierFromWindowsKeyCode();
     89 
     90     keyboard_event.type = blink::WebInputEvent::RawKeyDown;
     91     SendWebKeyboardEvent(keyboard_event);
     92 
     93     keyboard_event.type = blink::WebInputEvent::Char;
     94     SendWebKeyboardEvent(keyboard_event);
     95 
     96     keyboard_event.type = blink::WebInputEvent::KeyUp;
     97     SendWebKeyboardEvent(keyboard_event);
     98   }
     99 
    100   scoped_ptr<PageClickTracker> page_click_tracker_;
    101   TestPageClickListener test_listener_;
    102   blink::WebElement text_;
    103 };
    104 
    105 // Tests that PageClickTracker does notify correctly when a node is clicked.
    106 TEST_F(PageClickTrackerTest, PageClickTrackerInputClicked) {
    107   // Click the text field once.
    108   EXPECT_TRUE(SimulateElementClick("text_1"));
    109   EXPECT_TRUE(test_listener_.input_element_clicked_called_);
    110   EXPECT_FALSE(test_listener_.was_focused_);
    111   EXPECT_TRUE(test_listener_.is_focused_);
    112   EXPECT_TRUE(text_ == test_listener_.element_clicked_);
    113   test_listener_.ClearResults();
    114 
    115   // Click the text field again to test that was_focused_ is set correctly.
    116   EXPECT_TRUE(SimulateElementClick("text_1"));
    117   EXPECT_TRUE(test_listener_.input_element_clicked_called_);
    118   EXPECT_TRUE(test_listener_.was_focused_);
    119   EXPECT_TRUE(test_listener_.is_focused_);
    120   EXPECT_TRUE(text_ == test_listener_.element_clicked_);
    121   test_listener_.ClearResults();
    122 
    123   // Click the button, no notification should happen (this is not a text-input).
    124   EXPECT_TRUE(SimulateElementClick("button"));
    125   EXPECT_FALSE(test_listener_.input_element_clicked_called_);
    126 }
    127 
    128 TEST_F(PageClickTrackerTest, PageClickTrackerInputFocusLost) {
    129   // Gain focus on the text field by using tab.
    130   EXPECT_NE(text_, text_.document().focusedNode());
    131   SendKeyPress(ui::VKEY_TAB);
    132   EXPECT_EQ(text_, text_.document().focusedNode());
    133   EXPECT_FALSE(test_listener_.input_element_lost_focus_called_);
    134 
    135   // Click a button and ensure that the lost focus notification was sent,
    136   // even though focus was gained without the mouse.
    137   EXPECT_TRUE(SimulateElementClick("button"));
    138   EXPECT_TRUE(test_listener_.input_element_lost_focus_called_);
    139   test_listener_.ClearResults();
    140 
    141   // Click a text field and test that no lost focus notifications are sent.
    142   EXPECT_TRUE(SimulateElementClick("text_1"));
    143   EXPECT_FALSE(test_listener_.input_element_lost_focus_called_);
    144   test_listener_.ClearResults();
    145 
    146   // Select another text field to test that the notifcation for the
    147   // first text field losing focus is sent.
    148   EXPECT_TRUE(SimulateElementClick("text_2"));
    149   EXPECT_TRUE(test_listener_.input_element_lost_focus_called_);
    150   test_listener_.ClearResults();
    151 
    152   // Click the button, a notification should happen since a text field has
    153   // lost focus.
    154   EXPECT_TRUE(SimulateElementClick("button"));
    155   EXPECT_TRUE(test_listener_.input_element_lost_focus_called_);
    156   test_listener_.ClearResults();
    157 
    158   // Click on a text field while the button has focus and ensure no lost focus
    159   // notification is sent.
    160   EXPECT_TRUE(SimulateElementClick("text_1"));
    161   EXPECT_FALSE(test_listener_.input_element_lost_focus_called_);
    162 }
    163 
    164 }  // namespace autofill
    165