Chromium Code Reviews| Index: chrome/renderer/page_click_tracker_browsertest.cc |
| diff --git a/chrome/renderer/page_click_tracker_browsertest.cc b/chrome/renderer/page_click_tracker_browsertest.cc |
| index bf034bc951dfbe06e886270a7343dcc5633431f1..1c7af7f95bf489c398b911dde1b66dd46585ae1b 100644 |
| --- a/chrome/renderer/page_click_tracker_browsertest.cc |
| +++ b/chrome/renderer/page_click_tracker_browsertest.cc |
| @@ -7,17 +7,21 @@ |
| #include "chrome/renderer/page_click_listener.h" |
| #include "chrome/renderer/page_click_tracker.h" |
| #include "chrome/test/base/chrome_render_view_test.h" |
| +#include "content/common/view_messages.h" |
| #include "content/public/renderer/render_view.h" |
| +#include "content/renderer/render_view_impl.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
|
Ilya Sherman
2011/11/03 21:32:11
nit: I think you wanted to remove the content/rend
csharp
2011/11/04 13:25:32
Done.
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h" |
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" |
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
| +#include "ui/base/keycodes/keyboard_codes.h" |
| class TestPageClickListener : public PageClickListener { |
| public: |
| TestPageClickListener() |
| - : called_(false), |
| + : input_element_clicked_called_(false), |
| + input_element_lost_focus_called_(false), |
| was_focused_(false), |
| is_focused_(false), |
| notification_response_(false) { |
| @@ -26,99 +30,204 @@ class TestPageClickListener : public PageClickListener { |
| virtual bool InputElementClicked(const WebKit::WebInputElement& element, |
| bool was_focused, |
| bool is_focused) { |
| - called_ = true; |
| + input_element_clicked_called_ = true; |
| element_clicked_ = element; |
| was_focused_ = was_focused; |
| is_focused_ = is_focused; |
| return notification_response_; |
| } |
| + virtual bool InputElementLostFocus() { |
| + input_element_lost_focus_called_ = true; |
| + return notification_response_; |
| + } |
| + |
| void ClearResults() { |
| - called_ = false; |
| + input_element_clicked_called_ = false; |
| + input_element_lost_focus_called_ = false; |
| element_clicked_.reset(); |
| was_focused_ = false; |
| is_focused_ = false; |
| } |
| - bool called_; |
| + bool input_element_clicked_called_; |
| + bool input_element_lost_focus_called_; |
| WebKit::WebInputElement element_clicked_; |
| bool was_focused_; |
| bool is_focused_; |
| bool notification_response_; |
| }; |
| -// Tests that PageClickTracker does notify correctly when a node is clicked. |
| -TEST_F(ChromeRenderViewTest, PageClickTracker) { |
| - // RenderView creates PageClickTracker but it doesn't keep it around. Rather |
| - // than make it do so for the test, we create a new object. |
| - PageClickTracker* page_click_tracker = new PageClickTracker(view_); |
| - |
| - TestPageClickListener test_listener1; |
| - TestPageClickListener test_listener2; |
| - page_click_tracker->AddListener(&test_listener1); |
| - page_click_tracker->AddListener(&test_listener2); |
| - |
| - LoadHTML("<form>" |
| - " <input type='text' id='text'></input><br>" |
| - " <input type='button' id='button'></input><br>" |
| - "</form>"); |
| - GetWebWidget()->resize(WebKit::WebSize(500, 500)); |
| - GetWebWidget()->setFocus(true); |
| - WebKit::WebDocument document = view_->GetWebView()->mainFrame()->document(); |
| - WebKit::WebElement text = document.getElementById("text"); |
| - ASSERT_FALSE(text.isNull()); |
| - WebKit::WebElement button = document.getElementById("button"); |
| - ASSERT_FALSE(button.isNull()); |
| +class PageClickTrackerTest : public ChromeRenderViewTest { |
| + protected: |
| + virtual void SetUp() { |
| + ChromeRenderViewTest::SetUp(); |
| + |
| + // RenderView creates PageClickTracker but it doesn't keep it around. |
| + // Rather than make it do so for the test, we create a new object. |
| + page_click_tracker_.reset(new PageClickTracker(view_)); |
| + page_click_tracker_->AddListener(&test_listener1_); |
| + page_click_tracker_->AddListener(&test_listener2_); |
| + LoadHTML("<form>" |
| + " <input type='text' id='text_1'></input><br>" |
| + " <input type='text' id='text_2'></input><br>" |
| + " <input type='button' id='button'></input><br>" |
| + "</form>"); |
| + GetWebWidget()->resize(WebKit::WebSize(500, 500)); |
| + GetWebWidget()->setFocus(true); |
| + WebKit::WebDocument document = view_->GetWebView()->mainFrame()->document(); |
| + text_ = document.getElementById("text_1"); |
| + ASSERT_FALSE(text_.isNull()); |
| + } |
| + |
| + // Send a raw keyboard event to the renderer. |
| + void SendWebKeyboardEvent(WebKit::WebInputEvent::Type type, int key_code) { |
| + WebKit::WebKeyboardEvent keyboard_event; |
| + keyboard_event.type = type; |
| + keyboard_event.windowsKeyCode = key_code; |
| + keyboard_event.setKeyIdentifierFromWindowsKeyCode(); |
| + |
| + scoped_ptr<IPC::Message> input_message(new ViewMsg_HandleInputEvent(0)); |
| + input_message->WriteData(reinterpret_cast<const char*>(&keyboard_event), |
| + sizeof(WebKit::WebKeyboardEvent)); |
| + RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); |
| + impl->OnMessageReceived(*input_message); |
| + } |
| + |
| + // Send all the messages required for a complete key press. |
| + void SendKeyPress(int key_code) { |
| + SendWebKeyboardEvent(WebKit::WebInputEvent::RawKeyDown, key_code); |
| + SendWebKeyboardEvent(WebKit::WebInputEvent::Char, key_code); |
| + SendWebKeyboardEvent(WebKit::WebInputEvent::KeyUp, key_code); |
| + } |
| + |
| + scoped_ptr<PageClickTracker> page_click_tracker_; |
| + TestPageClickListener test_listener1_; |
| + TestPageClickListener test_listener2_; |
| + WebKit::WebElement text_; |
| +}; |
| + |
| +// Tests that PageClickTracker does notify correctly when a node is clicked. |
| +TEST_F(PageClickTrackerTest, PageClickTrackerInputClicked) { |
| // Click the text field once. |
| - EXPECT_TRUE(SimulateElementClick("text")); |
| - EXPECT_TRUE(test_listener1.called_); |
| - EXPECT_TRUE(test_listener2.called_); |
| - EXPECT_FALSE(test_listener1.was_focused_); |
| - EXPECT_FALSE(test_listener2.was_focused_); |
| - EXPECT_TRUE(test_listener1.is_focused_); |
| - EXPECT_TRUE(test_listener2.is_focused_); |
| - EXPECT_TRUE(text == test_listener1.element_clicked_); |
| - EXPECT_TRUE(text == test_listener2.element_clicked_); |
| - test_listener1.ClearResults(); |
| - test_listener2.ClearResults(); |
| + EXPECT_TRUE(SimulateElementClick("text_1")); |
| + EXPECT_TRUE(test_listener1_.input_element_clicked_called_); |
| + EXPECT_TRUE(test_listener2_.input_element_clicked_called_); |
| + EXPECT_FALSE(test_listener1_.was_focused_); |
| + EXPECT_FALSE(test_listener2_.was_focused_); |
| + EXPECT_TRUE(test_listener1_.is_focused_); |
| + EXPECT_TRUE(test_listener2_.is_focused_); |
| + EXPECT_TRUE(text_ == test_listener1_.element_clicked_); |
| + EXPECT_TRUE(text_ == test_listener2_.element_clicked_); |
| + test_listener1_.ClearResults(); |
| + test_listener2_.ClearResults(); |
| // Click the text field again to test that was_focused_ is set correctly. |
| - EXPECT_TRUE(SimulateElementClick("text")); |
| - EXPECT_TRUE(test_listener1.called_); |
| - EXPECT_TRUE(test_listener2.called_); |
| - EXPECT_TRUE(test_listener1.was_focused_); |
| - EXPECT_TRUE(test_listener2.was_focused_); |
| - EXPECT_TRUE(test_listener1.is_focused_); |
| - EXPECT_TRUE(test_listener2.is_focused_); |
| - EXPECT_TRUE(text == test_listener1.element_clicked_); |
| - EXPECT_TRUE(text == test_listener2.element_clicked_); |
| - test_listener1.ClearResults(); |
| - test_listener2.ClearResults(); |
| + EXPECT_TRUE(SimulateElementClick("text_1")); |
| + EXPECT_TRUE(test_listener1_.input_element_clicked_called_); |
| + EXPECT_TRUE(test_listener2_.input_element_clicked_called_); |
| + EXPECT_TRUE(test_listener1_.was_focused_); |
| + EXPECT_TRUE(test_listener2_.was_focused_); |
| + EXPECT_TRUE(test_listener1_.is_focused_); |
| + EXPECT_TRUE(test_listener2_.is_focused_); |
| + EXPECT_TRUE(text_ == test_listener1_.element_clicked_); |
| + EXPECT_TRUE(text_ == test_listener2_.element_clicked_); |
| + test_listener1_.ClearResults(); |
| + test_listener2_.ClearResults(); |
| // Click the button, no notification should happen (this is not a text-input). |
| EXPECT_TRUE(SimulateElementClick("button")); |
| - EXPECT_FALSE(test_listener1.called_); |
| - EXPECT_FALSE(test_listener2.called_); |
| + EXPECT_FALSE(test_listener1_.input_element_clicked_called_); |
| + EXPECT_FALSE(test_listener2_.input_element_clicked_called_); |
| // Make the first listener stop the event propagation, click the text field |
| // and make sure only the first listener is notified. |
| - test_listener1.notification_response_ = true; |
| - EXPECT_TRUE(SimulateElementClick("text")); |
| - EXPECT_TRUE(test_listener1.called_); |
| - EXPECT_FALSE(test_listener2.called_); |
| - test_listener1.ClearResults(); |
| + test_listener1_.notification_response_ = true; |
| + EXPECT_TRUE(SimulateElementClick("text_1")); |
| + EXPECT_TRUE(test_listener1_.input_element_clicked_called_); |
| + EXPECT_FALSE(test_listener2_.input_element_clicked_called_); |
| + test_listener1_.ClearResults(); |
| // Make sure removing a listener work. |
| - page_click_tracker->RemoveListener(&test_listener1); |
| - EXPECT_TRUE(SimulateElementClick("text")); |
| - EXPECT_FALSE(test_listener1.called_); |
| - EXPECT_TRUE(test_listener2.called_); |
| - test_listener2.ClearResults(); |
| + page_click_tracker_->RemoveListener(&test_listener1_); |
| + EXPECT_TRUE(SimulateElementClick("text_1")); |
| + EXPECT_FALSE(test_listener1_.input_element_clicked_called_); |
| + EXPECT_TRUE(test_listener2_.input_element_clicked_called_); |
| + test_listener2_.ClearResults(); |
| // Make sure we don't choke when no listeners are registered. |
| - page_click_tracker->RemoveListener(&test_listener2); |
| - EXPECT_TRUE(SimulateElementClick("text")); |
| - EXPECT_FALSE(test_listener1.called_); |
| - EXPECT_FALSE(test_listener2.called_); |
| + page_click_tracker_->RemoveListener(&test_listener2_); |
| + EXPECT_TRUE(SimulateElementClick("text_1")); |
| + EXPECT_FALSE(test_listener1_.input_element_clicked_called_); |
| + EXPECT_FALSE(test_listener2_.input_element_clicked_called_); |
| +} |
| + |
| +TEST_F(PageClickTrackerTest, PageClickTrackerInputFocusLost) { |
| + // Gain focus on the text field by using tab. |
| + EXPECT_NE(text_, text_.document().focusedNode()); |
| + SendKeyPress(ui::VKEY_TAB); |
| + EXPECT_EQ(text_, text_.document().focusedNode()); |
| + EXPECT_FALSE(test_listener1_.input_element_lost_focus_called_); |
| + EXPECT_FALSE(test_listener2_.input_element_lost_focus_called_); |
| + |
| + // Click a button and ensure that the lost focus notification was sent, |
| + // even though focus was gained without the mouse. |
| + EXPECT_TRUE(SimulateElementClick("button")); |
| + EXPECT_TRUE(test_listener1_.input_element_lost_focus_called_); |
| + EXPECT_TRUE(test_listener2_.input_element_lost_focus_called_); |
| + test_listener1_.ClearResults(); |
| + test_listener2_.ClearResults(); |
| + |
| + // Click a text field and test that no lost focus notifications are sent. |
| + EXPECT_TRUE(SimulateElementClick("text_1")); |
| + EXPECT_FALSE(test_listener1_.input_element_lost_focus_called_); |
| + EXPECT_FALSE(test_listener2_.input_element_lost_focus_called_); |
| + test_listener1_.ClearResults(); |
| + test_listener2_.ClearResults(); |
| + |
| + // Select another text field to test that the notifcation for the |
| + // first text field losing focus is sent. |
| + EXPECT_TRUE(SimulateElementClick("text_2")); |
| + EXPECT_TRUE(test_listener1_.input_element_lost_focus_called_); |
| + EXPECT_TRUE(test_listener2_.input_element_lost_focus_called_); |
| + test_listener1_.ClearResults(); |
| + test_listener2_.ClearResults(); |
| + |
| + // Click the button, a notification should happen since a text field has |
| + // lost focus. |
| + EXPECT_TRUE(SimulateElementClick("button")); |
| + EXPECT_TRUE(test_listener1_.input_element_lost_focus_called_); |
| + EXPECT_TRUE(test_listener2_.input_element_lost_focus_called_); |
| + test_listener1_.ClearResults(); |
| + test_listener2_.ClearResults(); |
| + |
| + // Click on a text field while the button has focus and ensure no lost focus |
| + // notification is sent. |
| + EXPECT_TRUE(SimulateElementClick("text_1")); |
| + EXPECT_FALSE(test_listener1_.input_element_lost_focus_called_); |
| + EXPECT_FALSE(test_listener2_.input_element_lost_focus_called_); |
| + |
| + // Make the first listener stop the event propagation, then click a button |
| + // and make sure only the first listener is notified. |
| + test_listener1_.notification_response_ = true; |
| + EXPECT_TRUE(SimulateElementClick("button")); |
| + EXPECT_TRUE(test_listener1_.input_element_lost_focus_called_); |
| + EXPECT_FALSE(test_listener2_.input_element_lost_focus_called_); |
| + test_listener1_.ClearResults(); |
| + |
| + // Make sure removing a listener work. |
| + page_click_tracker_->RemoveListener(&test_listener1_); |
| + EXPECT_TRUE(SimulateElementClick("text_1")); |
| + EXPECT_TRUE(SimulateElementClick("button")); |
| + EXPECT_FALSE(test_listener1_.input_element_lost_focus_called_); |
| + EXPECT_TRUE(test_listener2_.input_element_lost_focus_called_); |
| + test_listener2_.ClearResults(); |
| + |
| + // Make sure we don't choke when no listeners are registered. |
| + page_click_tracker_->RemoveListener(&test_listener2_); |
| + EXPECT_TRUE(SimulateElementClick("text_1")); |
| + EXPECT_TRUE(SimulateElementClick("button")); |
| + EXPECT_FALSE(test_listener1_.input_element_lost_focus_called_); |
| + EXPECT_FALSE(test_listener2_.input_element_lost_focus_called_); |
| } |