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.
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"
20 class TestPageClickListener
: public PageClickListener
{
22 TestPageClickListener()
23 : form_control_element_clicked_called_(false),
24 form_control_element_lost_focus_called_(false),
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
;
36 virtual void FormControlElementLostFocus() OVERRIDE
{
37 form_control_element_lost_focus_called_
= true;
41 form_control_element_clicked_called_
= false;
42 form_control_element_lost_focus_called_
= false;
43 form_control_element_clicked_
.reset();
47 bool form_control_element_clicked_called_
;
48 bool form_control_element_lost_focus_called_
;
49 blink::WebFormControlElement form_control_element_clicked_
;
53 class PageClickTrackerTest
: public content::RenderViewTest
{
55 virtual void SetUp() OVERRIDE
{
56 content::RenderViewTest::SetUp();
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_
));
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>"
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());
78 virtual void TearDown() OVERRIDE
{
81 test_listener_
.ClearResults();
82 page_click_tracker_
.reset();
83 content::RenderViewTest::TearDown();
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();
92 keyboard_event
.type
= blink::WebInputEvent::RawKeyDown
;
93 SendWebKeyboardEvent(keyboard_event
);
95 keyboard_event
.type
= blink::WebInputEvent::Char
;
96 SendWebKeyboardEvent(keyboard_event
);
98 keyboard_event
.type
= blink::WebInputEvent::KeyUp
;
99 SendWebKeyboardEvent(keyboard_event
);
102 scoped_ptr
<PageClickTracker
> page_click_tracker_
;
103 TestPageClickListener test_listener_
;
104 blink::WebElement text_
;
105 blink::WebElement textarea_
;
108 // Tests that PageClickTracker does notify correctly when an input
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();
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();
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_
);
130 // Tests that PageClickTracker does notify correctly when a textarea
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();
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();
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_
);
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_
);
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();
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();
170 // Select another text field to test that the notifcation 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();
176 // Click the button, a notification should happen since a text field has
178 EXPECT_TRUE(SimulateElementClick("button"));
179 EXPECT_TRUE(test_listener_
.form_control_element_lost_focus_called_
);
180 test_listener_
.ClearResults();
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_
);
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_
);
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();
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();
208 // Select another textarea field to test that the notifcation 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();
214 // Click the button, a notification should happen since a textarea field has
216 EXPECT_TRUE(SimulateElementClick("button"));
217 EXPECT_TRUE(test_listener_
.form_control_element_lost_focus_called_
);
218 test_listener_
.ClearResults();
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_
);
226 } // namespace autofill