• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
TestPageClickListener()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 
InputElementClicked(const blink::WebInputElement & element,bool was_focused,bool is_focused)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 
InputElementLostFocus()37   virtual void InputElementLostFocus() OVERRIDE {
38     input_element_lost_focus_called_ = true;
39   }
40 
ClearResults()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:
SetUp()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 
TearDown()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.
SendKeyPress(int key_code)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.
TEST_F(PageClickTrackerTest,PageClickTrackerInputClicked)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 
TEST_F(PageClickTrackerTest,PageClickTrackerInputFocusLost)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