// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/test/base/chrome_render_view_test.h" #include "components/autofill/content/renderer/page_click_listener.h" #include "components/autofill/content/renderer/page_click_tracker.h" #include "content/public/renderer/render_view.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/WebFloatPoint.h" #include "third_party/WebKit/public/platform/WebSize.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebInputElement.h" #include "third_party/WebKit/public/web/WebSettings.h" #include "third_party/WebKit/public/web/WebView.h" #include "ui/events/keycodes/keyboard_codes.h" namespace autofill { class TestPageClickListener : public PageClickListener { public: TestPageClickListener() : form_control_element_clicked_called_(false), was_focused_(false) {} void FormControlElementClicked(const blink::WebFormControlElement& element, bool was_focused) override { form_control_element_clicked_called_ = true; form_control_element_clicked_ = element; was_focused_ = was_focused; } void ClearResults() { form_control_element_clicked_called_ = false; form_control_element_clicked_.reset(); was_focused_ = false; } bool form_control_element_clicked_called_; blink::WebFormControlElement form_control_element_clicked_; bool was_focused_; }; class PageClickTrackerTest : public ChromeRenderViewTest { protected: void SetUp() override { 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_->GetMainRenderFrame(), &test_listener_)); // Must be set before loading HTML. view_->GetWebView()->setDefaultPageScaleLimits(1, 4); LoadHTML("<form>" " <input type='text' id='text_1'></input><br>" " <input type='text' id='text_2'></input><br>" " <textarea id='textarea_1'></textarea><br>" " <textarea id='textarea_2'></textarea><br>" " <input type='button' id='button'></input><br>" " <input type='button' id='button_2' disabled></input><br>" "</form>"); GetWebWidget()->resize(blink::WebSize(500, 500)); GetWebWidget()->setFocus(true); blink::WebDocument document = view_->GetWebView()->mainFrame()->document(); text_ = document.getElementById("text_1"); textarea_ = document.getElementById("textarea_1"); ASSERT_FALSE(text_.isNull()); ASSERT_FALSE(textarea_.isNull()); // Enable show-ime event when element is focused by indicating that a user // gesture has been processed since load. EXPECT_TRUE(SimulateElementClick("button")); } void TearDown() override { text_.reset(); textarea_.reset(); test_listener_.ClearResults(); page_click_tracker_.reset(); ChromeRenderViewTest::TearDown(); } scoped_ptr<PageClickTracker> page_click_tracker_; TestPageClickListener test_listener_; blink::WebElement text_; blink::WebElement textarea_; }; // Tests that PageClickTracker does notify correctly when an input // node is clicked. TEST_F(PageClickTrackerTest, PageClickTrackerInputClicked) { EXPECT_NE(text_, text_.document().focusedElement()); // Click the text field once. EXPECT_TRUE(SimulateElementClick("text_1")); EXPECT_TRUE(test_listener_.form_control_element_clicked_called_); EXPECT_FALSE(test_listener_.was_focused_); EXPECT_TRUE(text_ == test_listener_.form_control_element_clicked_); test_listener_.ClearResults(); // Click the text field again to test that was_focused_ is set correctly. EXPECT_TRUE(SimulateElementClick("text_1")); EXPECT_TRUE(test_listener_.form_control_element_clicked_called_); EXPECT_TRUE(test_listener_.was_focused_); EXPECT_TRUE(text_ == test_listener_.form_control_element_clicked_); test_listener_.ClearResults(); // Click the button, no notification should happen (this is not a text-input). EXPECT_TRUE(SimulateElementClick("button")); EXPECT_FALSE(test_listener_.form_control_element_clicked_called_); } // Tests that PageClickTracker does not notify when there is right click. TEST_F(PageClickTrackerTest, PageClickTrackerInputRightClicked) { EXPECT_NE(text_, text_.document().focusedElement()); // Right click the text field once. EXPECT_TRUE(SimulateElementRightClick("text_1")); EXPECT_FALSE(test_listener_.form_control_element_clicked_called_); EXPECT_FALSE(test_listener_.was_focused_); EXPECT_NE(text_, test_listener_.form_control_element_clicked_); } TEST_F(PageClickTrackerTest, PageClickTrackerInputFocusedAndClicked) { // Focus the text field without a click. ExecuteJavaScriptForTests("document.getElementById('text_1').focus();"); EXPECT_FALSE(test_listener_.form_control_element_clicked_called_); test_listener_.ClearResults(); // Click the focused text field to test that was_focused_ is set correctly. EXPECT_TRUE(SimulateElementClick("text_1")); EXPECT_TRUE(test_listener_.form_control_element_clicked_called_); EXPECT_TRUE(test_listener_.was_focused_); EXPECT_TRUE(text_ == test_listener_.form_control_element_clicked_); } // Tests that PageClickTracker does notify correctly when a textarea // node is clicked. TEST_F(PageClickTrackerTest, PageClickTrackerTextAreaClicked) { // Click the textarea field once. EXPECT_TRUE(SimulateElementClick("textarea_1")); EXPECT_TRUE(test_listener_.form_control_element_clicked_called_); EXPECT_FALSE(test_listener_.was_focused_); EXPECT_TRUE(textarea_ == test_listener_.form_control_element_clicked_); test_listener_.ClearResults(); // Click the textarea field again to test that was_focused_ is set correctly. EXPECT_TRUE(SimulateElementClick("textarea_1")); EXPECT_TRUE(test_listener_.form_control_element_clicked_called_); EXPECT_TRUE(test_listener_.was_focused_); EXPECT_TRUE(textarea_ == test_listener_.form_control_element_clicked_); test_listener_.ClearResults(); // Click the button, no notification should happen (this is not a text-input). EXPECT_TRUE(SimulateElementClick("button")); EXPECT_FALSE(test_listener_.form_control_element_clicked_called_); } TEST_F(PageClickTrackerTest, PageClickTrackerTextAreaFocusedAndClicked) { // Focus the textarea without a click. ExecuteJavaScriptForTests("document.getElementById('textarea_1').focus();"); EXPECT_FALSE(test_listener_.form_control_element_clicked_called_); test_listener_.ClearResults(); // Click the focused text field to test that was_focused_ is set correctly. EXPECT_TRUE(SimulateElementClick("textarea_1")); EXPECT_TRUE(test_listener_.form_control_element_clicked_called_); EXPECT_TRUE(test_listener_.was_focused_); EXPECT_TRUE(textarea_ == test_listener_.form_control_element_clicked_); test_listener_.ClearResults(); } TEST_F(PageClickTrackerTest, PageClickTrackerScaledTextareaClicked) { EXPECT_NE(textarea_, textarea_.document().focusedElement()); view_->GetWebView()->setPageScaleFactor(3); view_->GetWebView()->setVisualViewportOffset(blink::WebFloatPoint(50, 50)); // Click textarea_1. SimulatePointClick(gfx::Point(30, 30)); EXPECT_TRUE(test_listener_.form_control_element_clicked_called_); EXPECT_FALSE(test_listener_.was_focused_); EXPECT_TRUE(textarea_ == test_listener_.form_control_element_clicked_); } TEST_F(PageClickTrackerTest, PageClickTrackerScaledTextareaTapped) { EXPECT_NE(textarea_, textarea_.document().focusedElement()); view_->GetWebView()->setPageScaleFactor(3); view_->GetWebView()->setVisualViewportOffset(blink::WebFloatPoint(50, 50)); // Tap textarea_1. SimulateRectTap(gfx::Rect(30, 30, 30, 30)); EXPECT_TRUE(test_listener_.form_control_element_clicked_called_); EXPECT_FALSE(test_listener_.was_focused_); EXPECT_TRUE(textarea_ == test_listener_.form_control_element_clicked_); } TEST_F(PageClickTrackerTest, PageClickTrackerDisabledInputClickedNoEvent) { EXPECT_NE(text_, text_.document().focusedElement()); // Click the text field once. EXPECT_TRUE(SimulateElementClick("text_1")); EXPECT_TRUE(test_listener_.form_control_element_clicked_called_); EXPECT_FALSE(test_listener_.was_focused_); EXPECT_TRUE(text_ == test_listener_.form_control_element_clicked_); test_listener_.ClearResults(); // Click the disabled element. EXPECT_TRUE(SimulateElementClick("button_2")); EXPECT_FALSE(test_listener_.form_control_element_clicked_called_); } TEST_F(PageClickTrackerTest, PageClickTrackerClickDisabledInputDoesNotResetClickCounter) { EXPECT_NE(text_, text_.document().focusedElement()); // Click the text field once. EXPECT_TRUE(SimulateElementClick("text_1")); EXPECT_TRUE(test_listener_.form_control_element_clicked_called_); EXPECT_FALSE(test_listener_.was_focused_); EXPECT_TRUE(text_ == test_listener_.form_control_element_clicked_); test_listener_.ClearResults(); // Click the disabled element. EXPECT_TRUE(SimulateElementClick("button_2")); EXPECT_FALSE(test_listener_.form_control_element_clicked_called_); test_listener_.ClearResults(); // Click the text field second time. Page click tracker should know that this // is the second click. EXPECT_TRUE(SimulateElementClick("text_1")); EXPECT_TRUE(test_listener_.form_control_element_clicked_called_); EXPECT_TRUE(test_listener_.was_focused_); EXPECT_TRUE(text_ == test_listener_.form_control_element_clicked_); } TEST_F(PageClickTrackerTest, PageClickTrackerTapNearEdgeIsPageClick) { EXPECT_NE(text_, text_.document().focusedElement()); // Tap outside of element bounds, but tap width is overlapping the field. gfx::Rect element_bounds = GetElementBounds("text_1"); SimulateRectTap(element_bounds - gfx::Vector2d(element_bounds.width() / 2 + 1, 0)); EXPECT_TRUE(test_listener_.form_control_element_clicked_called_); EXPECT_FALSE(test_listener_.was_focused_); EXPECT_TRUE(text_ == test_listener_.form_control_element_clicked_); } } // namespace autofill