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/WebTextAreaElement.h"
     14 #include "third_party/WebKit/public/web/WebView.h"
     15 #include "third_party/WebKit/public/platform/WebSize.h"
     16 #include "ui/events/keycodes/keyboard_codes.h"
     17 
     18 namespace autofill {
     19 
     20 class TestPageClickListener : public PageClickListener {
     21  public:
     22   TestPageClickListener()
     23       : form_control_element_clicked_called_(false),
     24         form_control_element_lost_focus_called_(false),
     25         was_focused_(false) {
     26   }
     27 
     28   virtual void FormControlElementClicked(
     29       const blink::WebFormControlElement& element,
     30       bool was_focused)  OVERRIDE {
     31     form_control_element_clicked_called_ = true;
     32     form_control_element_clicked_ = element;
     33     was_focused_ = was_focused;
     34   }
     35 
     36   virtual void FormControlElementLostFocus() OVERRIDE {
     37     form_control_element_lost_focus_called_ = true;
     38   }
     39 
     40   void ClearResults() {
     41     form_control_element_clicked_called_ = false;
     42     form_control_element_lost_focus_called_ = false;
     43     form_control_element_clicked_.reset();
     44     was_focused_ = false;
     45   }
     46 
     47   bool form_control_element_clicked_called_;
     48   bool form_control_element_lost_focus_called_;
     49   blink::WebFormControlElement form_control_element_clicked_;
     50   bool was_focused_;
     51 };
     52 
     53 class PageClickTrackerTest : public content::RenderViewTest {
     54  protected:
     55   virtual void SetUp() OVERRIDE {
     56     content::RenderViewTest::SetUp();
     57 
     58     // RenderView creates PageClickTracker but it doesn't keep it around.
     59     // Rather than make it do so for the test, we create a new object.
     60     page_click_tracker_.reset(new PageClickTracker(view_, &test_listener_));
     61 
     62     LoadHTML("<form>"
     63              "  <input type='text' id='text_1'></input><br>"
     64              "  <input type='text' id='text_2'></input><br>"
     65              "  <textarea  id='textarea_1'></textarea><br>"
     66              "  <textarea  id='textarea_2'></textarea><br>"
     67              "  <input type='button' id='button'></input><br>"
     68              "</form>");
     69     GetWebWidget()->resize(blink::WebSize(500, 500));
     70     GetWebWidget()->setFocus(true);
     71     blink::WebDocument document = view_->GetWebView()->mainFrame()->document();
     72     text_ = document.getElementById("text_1");
     73     textarea_ = document.getElementById("textarea_1");
     74     ASSERT_FALSE(text_.isNull());
     75     ASSERT_FALSE(textarea_.isNull());
     76   }
     77 
     78   virtual void TearDown() OVERRIDE {
     79     text_.reset();
     80     textarea_.reset();
     81     test_listener_.ClearResults();
     82     page_click_tracker_.reset();
     83     content::RenderViewTest::TearDown();
     84   }
     85 
     86   // Send all the messages required for a complete key press.
     87   void SendKeyPress(int key_code) {
     88     blink::WebKeyboardEvent keyboard_event;
     89     keyboard_event.windowsKeyCode = key_code;
     90     keyboard_event.setKeyIdentifierFromWindowsKeyCode();
     91 
     92     keyboard_event.type = blink::WebInputEvent::RawKeyDown;
     93     SendWebKeyboardEvent(keyboard_event);
     94 
     95     keyboard_event.type = blink::WebInputEvent::Char;
     96     SendWebKeyboardEvent(keyboard_event);
     97 
     98     keyboard_event.type = blink::WebInputEvent::KeyUp;
     99     SendWebKeyboardEvent(keyboard_event);
    100   }
    101 
    102   scoped_ptr<PageClickTracker> page_click_tracker_;
    103   TestPageClickListener test_listener_;
    104   blink::WebElement text_;
    105   blink::WebElement textarea_;
    106 };
    107 
    108 // Tests that PageClickTracker does notify correctly when an input
    109 // node is clicked.
    110 TEST_F(PageClickTrackerTest, PageClickTrackerInputClicked) {
    111   // Click the text field once.
    112   EXPECT_TRUE(SimulateElementClick("text_1"));
    113   EXPECT_TRUE(test_listener_.form_control_element_clicked_called_);
    114   EXPECT_FALSE(test_listener_.was_focused_);
    115   EXPECT_TRUE(text_ == test_listener_.form_control_element_clicked_);
    116   test_listener_.ClearResults();
    117 
    118   // Click the text field again to test that was_focused_ is set correctly.
    119   EXPECT_TRUE(SimulateElementClick("text_1"));
    120   EXPECT_TRUE(test_listener_.form_control_element_clicked_called_);
    121   EXPECT_TRUE(test_listener_.was_focused_);
    122   EXPECT_TRUE(text_ == test_listener_.form_control_element_clicked_);
    123   test_listener_.ClearResults();
    124 
    125   // Click the button, no notification should happen (this is not a text-input).
    126   EXPECT_TRUE(SimulateElementClick("button"));
    127   EXPECT_FALSE(test_listener_.form_control_element_clicked_called_);
    128 }
    129 
    130 // Tests that PageClickTracker does notify correctly when a textarea
    131 // node is clicked.
    132 TEST_F(PageClickTrackerTest, PageClickTrackerTextAreaClicked) {
    133   // Click the textarea field once.
    134   EXPECT_TRUE(SimulateElementClick("textarea_1"));
    135   EXPECT_TRUE(test_listener_.form_control_element_clicked_called_);
    136   EXPECT_FALSE(test_listener_.was_focused_);
    137   EXPECT_TRUE(textarea_ == test_listener_.form_control_element_clicked_);
    138   test_listener_.ClearResults();
    139 
    140   // Click the textarea field again to test that was_focused_ is set correctly.
    141   EXPECT_TRUE(SimulateElementClick("textarea_1"));
    142   EXPECT_TRUE(test_listener_.form_control_element_clicked_called_);
    143   EXPECT_TRUE(test_listener_.was_focused_);
    144   EXPECT_TRUE(textarea_ == test_listener_.form_control_element_clicked_);
    145   test_listener_.ClearResults();
    146 
    147   // Click the button, no notification should happen (this is not a text-input).
    148   EXPECT_TRUE(SimulateElementClick("button"));
    149   EXPECT_FALSE(test_listener_.form_control_element_clicked_called_);
    150 }
    151 
    152 TEST_F(PageClickTrackerTest, PageClickTrackerInputFocusLost) {
    153   // Gain focus on the text field by using tab.
    154   EXPECT_NE(text_, text_.document().focusedElement());
    155   SendKeyPress(ui::VKEY_TAB);
    156   EXPECT_EQ(text_, text_.document().focusedElement());
    157   EXPECT_FALSE(test_listener_.form_control_element_lost_focus_called_);
    158 
    159   // Click a button and ensure that the lost focus notification was sent,
    160   // even though focus was gained without the mouse.
    161   EXPECT_TRUE(SimulateElementClick("button"));
    162   EXPECT_TRUE(test_listener_.form_control_element_lost_focus_called_);
    163   test_listener_.ClearResults();
    164 
    165   // Click a text field and test that no lost focus notifications are sent.
    166   EXPECT_TRUE(SimulateElementClick("text_1"));
    167   EXPECT_FALSE(test_listener_.form_control_element_lost_focus_called_);
    168   test_listener_.ClearResults();
    169 
    170   // Select another text field to test that the notification for the
    171   // first text field losing focus is sent.
    172   EXPECT_TRUE(SimulateElementClick("text_2"));
    173   EXPECT_TRUE(test_listener_.form_control_element_lost_focus_called_);
    174   test_listener_.ClearResults();
    175 
    176   // Click the button, a notification should happen since a text field has
    177   // lost focus.
    178   EXPECT_TRUE(SimulateElementClick("button"));
    179   EXPECT_TRUE(test_listener_.form_control_element_lost_focus_called_);
    180   test_listener_.ClearResults();
    181 
    182   // Click on a text field while the button has focus and ensure no lost focus
    183   // notification is sent.
    184   EXPECT_TRUE(SimulateElementClick("text_1"));
    185   EXPECT_FALSE(test_listener_.form_control_element_lost_focus_called_);
    186 }
    187 
    188 TEST_F(PageClickTrackerTest, PageClickTrackerTextAreaFocusLost) {
    189   // Gain focus on the textare field by using tab.
    190   EXPECT_NE(textarea_, textarea_.document().focusedElement());
    191   SendKeyPress(ui::VKEY_TAB);
    192   SendKeyPress(ui::VKEY_TAB);
    193   SendKeyPress(ui::VKEY_TAB);
    194   EXPECT_EQ(textarea_, textarea_.document().focusedElement());
    195   EXPECT_FALSE(test_listener_.form_control_element_lost_focus_called_);
    196 
    197   // Click a button and ensure that the lost focus notification was sent,
    198   // even though focus was gained without the mouse.
    199   EXPECT_TRUE(SimulateElementClick("button"));
    200   EXPECT_TRUE(test_listener_.form_control_element_lost_focus_called_);
    201   test_listener_.ClearResults();
    202 
    203   // Click a textarea field and test that no lost focus notifications are sent.
    204   EXPECT_TRUE(SimulateElementClick("textarea_1"));
    205   EXPECT_FALSE(test_listener_.form_control_element_lost_focus_called_);
    206   test_listener_.ClearResults();
    207 
    208   // Select another textarea field to test that the notification for the
    209   // first textarea field losing focus is sent.
    210   EXPECT_TRUE(SimulateElementClick("textarea_2"));
    211   EXPECT_TRUE(test_listener_.form_control_element_lost_focus_called_);
    212   test_listener_.ClearResults();
    213 
    214   // Click the button, a notification should happen since a textarea field has
    215   // lost focus.
    216   EXPECT_TRUE(SimulateElementClick("button"));
    217   EXPECT_TRUE(test_listener_.form_control_element_lost_focus_called_);
    218   test_listener_.ClearResults();
    219 
    220   // Click on a textarea field while the button has focus and ensure no lost
    221   // focus notification is sent.
    222   EXPECT_TRUE(SimulateElementClick("textarea_1"));
    223   EXPECT_FALSE(test_listener_.form_control_element_lost_focus_called_);
    224 }
    225 
    226 }  // namespace autofill
    227