OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2016 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 "core/dom/Range.h" | |
6 #include "core/frame/FrameView.h" | |
7 #include "core/input/EventHandler.h" | |
8 #include "core/page/ChromeClient.h" | |
9 #include "core/page/ContextMenuController.h" | |
10 #include "core/page/FocusController.h" | |
11 #include "core/page/Page.h" | |
12 #include "platform/Cursor.h" | |
13 #include "platform/testing/URLTestHelpers.h" | |
14 #include "platform/testing/UnitTestHelpers.h" | |
15 #include "public/web/WebSettings.h" | |
16 #include "web/WebLocalFrameImpl.h" | |
17 #include "web/tests/SelectionTestBase.h" | |
18 | |
19 #include <gmock/gmock.h> | |
tkent
2016/03/25 03:33:03
Please include it with "", not <>.
Please specify
| |
20 #include <gtest/gtest.h> | |
21 | |
22 using ::testing::_; | |
23 | |
24 namespace blink { | |
25 | |
26 class TestFrameClient : public FrameTestHelpers::TestWebFrameClient { | |
27 public: | |
28 MOCK_METHOD4(loadURLExternally, | |
29 void(const WebURLRequest&, WebNavigationPolicy, const WebString& downloa dName, bool shouldReplaceCurrentEntry)); | |
30 }; | |
31 | |
32 class LinkSelectionTest : public SelectionTestBase { | |
33 protected: | |
34 void SetUp() override | |
35 { | |
36 const char* const kHTMLString = | |
37 "<a id='link' href='foo.com' style='font-size:20pt'>Text to select f oobar</a>" | |
38 "<div id='page_text'>Lorem ipsum dolor sit amet</div>"; | |
39 | |
40 // We need to set deviceSupportsMouse setting to true and page's focus c ontroller to active | |
41 // so that FrameView can set the mouse cursor. | |
42 m_webView = m_helper.initialize(false, &m_testFrameClient, nullptr, | |
43 [](WebSettings* settings) { settings->setDeviceSupportsMouse(true); }); | |
44 m_mainFrame = m_webView->mainFrameImpl(); | |
45 FrameTestHelpers::loadHTMLString(m_mainFrame, kHTMLString, URLTestHelper s::toKURL("http://foobar.com")); | |
46 m_webView->resize(WebSize(800, 600)); | |
47 m_webView->page()->focusController().setActive(true); | |
48 | |
49 auto* document = m_mainFrame->frame()->document(); | |
50 ASSERT(document); | |
tkent
2016/03/25 03:33:02
Blink's ASSERT() is deprecated. Use glog's DCHECK
| |
51 auto* linkToSelect = document->getElementById("link")->firstChild(); | |
52 ASSERT(linkToSelect); | |
tkent
2016/03/25 03:33:02
ASSERT() is deprecated.
| |
53 // We get larger range that we actually want to select, because we need a slightly larger | |
54 // rect to include the last character to the selection. | |
55 const auto rangeToSelect = Range::create(*document, linkToSelect, 5, lin kToSelect, 16); | |
56 | |
57 const auto& selectionRect = rangeToSelect->boundingBox(); | |
58 const auto& selectionRectCenterY = selectionRect.center().y(); | |
59 m_leftPointInLink = selectionRect.minXMinYCorner(); | |
60 m_leftPointInLink.setY(selectionRectCenterY); | |
61 | |
62 m_rightPointInLink = selectionRect.maxXMinYCorner(); | |
63 m_rightPointInLink.setY(selectionRectCenterY); | |
64 m_rightPointInLink.move(-2, 0); | |
65 } | |
66 | |
67 TestFrameClient m_testFrameClient; | |
68 IntPoint m_leftPointInLink; | |
69 IntPoint m_rightPointInLink; | |
70 }; | |
71 | |
72 TEST_F(LinkSelectionTest, MouseDragWithoutAltAllowNoLinkSelection) | |
73 { | |
74 emulateMouseDrag(m_leftPointInLink, m_rightPointInLink, 0); | |
75 EXPECT_EQ(std::string(), getSelectionText()); | |
76 } | |
77 | |
78 TEST_F(LinkSelectionTest, MouseDragWithAltAllowSelection) | |
79 { | |
80 emulateMouseDrag(m_leftPointInLink, m_rightPointInLink, WebInputEvent::AltKe y); | |
81 EXPECT_EQ("to select", getSelectionText()); | |
82 } | |
83 | |
84 TEST_F(LinkSelectionTest, HandCursorDuringLinkDrag) | |
85 { | |
86 emulateMouseDrag(m_rightPointInLink, m_leftPointInLink, 0, SendDownEvent); | |
87 m_mainFrame->frame()->localFrameRoot()->eventHandler().scheduleCursorUpdate( ); | |
88 testing::runDelayedTasks(50); | |
89 const auto& cursor = m_mainFrame->frame()->chromeClient().lastSetCursorForTe sting(); | |
90 EXPECT_EQ(Cursor::Hand, cursor.getType()); | |
91 } | |
92 | |
93 TEST_F(LinkSelectionTest, CaretCursorOverLinkDuringSelection) | |
94 { | |
95 emulateMouseDrag(m_rightPointInLink, m_leftPointInLink, WebInputEvent::AltKe y, SendDownEvent); | |
96 m_mainFrame->frame()->localFrameRoot()->eventHandler().scheduleCursorUpdate( ); | |
97 testing::runDelayedTasks(50); | |
98 const auto& cursor = m_mainFrame->frame()->chromeClient().lastSetCursorForTe sting(); | |
99 EXPECT_EQ(Cursor::IBeam, cursor.getType()); | |
100 } | |
101 | |
102 TEST_F(LinkSelectionTest, HandCursorOverLinkAfterContextMenu) | |
103 { | |
104 // Move mouse. | |
105 emulateMouseDrag(m_rightPointInLink, m_leftPointInLink, 0, 0); | |
106 | |
107 // Show context menu. We don't send mouseup event here since in browser it d oesn't reach | |
108 // blink because of shown context menu. | |
109 emulateMouseDown(m_leftPointInLink, WebMouseEvent::ButtonRight, 0, 1); | |
110 | |
111 LocalFrame* frame = m_mainFrame->frame(); | |
112 // Hide context menu. | |
113 frame->page()->contextMenuController().clearContextMenu(); | |
114 | |
115 frame->localFrameRoot()->eventHandler().scheduleCursorUpdate(); | |
116 testing::runDelayedTasks(50); | |
117 const auto& cursor = m_mainFrame->frame()->chromeClient().lastSetCursorForTe sting(); | |
118 EXPECT_EQ(Cursor::Hand, cursor.getType()); | |
119 } | |
120 | |
121 TEST_F(LinkSelectionTest, SingleClickWithAltStartsDownload) | |
122 { | |
123 EXPECT_CALL(m_testFrameClient, loadURLExternally(_, WebNavigationPolicy::Web NavigationPolicyDownload, WebString(), _)); | |
124 emulateMouseClick(m_leftPointInLink, WebMouseEvent::ButtonLeft, WebInputEven t::AltKey); | |
125 } | |
126 | |
127 TEST_F(LinkSelectionTest, SingleClickWithAltStartsDownloadWhenTextSelected) | |
128 { | |
129 auto* document = m_mainFrame->frame()->document(); | |
130 auto* textToSelect = document->getElementById("page_text")->firstChild(); | |
131 ASSERT(textToSelect); | |
tkent
2016/03/25 03:33:03
ASSERT() is deprecated.
| |
132 | |
133 // Select some page text outside the link element. | |
134 const RefPtrWillBeRawPtr<Range> rangeToSelect = Range::create(*document, tex tToSelect, 1, textToSelect, 20); | |
135 const auto& selectionRect = rangeToSelect->boundingBox(); | |
136 m_mainFrame->moveRangeSelection(selectionRect.minXMinYCorner(), selectionRec t.maxXMaxYCorner()); | |
137 EXPECT_FALSE(getSelectionText().empty()); | |
138 | |
139 EXPECT_CALL(m_testFrameClient, loadURLExternally(_, WebNavigationPolicy::Web NavigationPolicyDownload, WebString(), _)); | |
140 emulateMouseClick(m_leftPointInLink, WebMouseEvent::ButtonLeft, WebInputEven t::AltKey); | |
141 } | |
142 | |
143 class LinkSelectionClickEvents : public SelectionTestBase { | |
tkent
2016/03/25 03:33:03
Please use "Test" suffix for test fixture class na
| |
144 protected: | |
145 class MockEventListener final : public EventListener { | |
146 public: | |
147 static PassRefPtrWillBeRawPtr<MockEventListener> create() | |
148 { | |
149 return adoptRefWillBeNoop(new MockEventListener()); | |
150 } | |
151 | |
152 bool operator==(const EventListener& other) const final | |
153 { | |
154 return this == &other; | |
155 } | |
156 | |
157 MOCK_METHOD2(handleEvent, void(ExecutionContext* executionContext, Event *)); | |
158 | |
159 private: | |
160 MockEventListener() : EventListener(CPPEventListenerType) | |
161 { | |
162 } | |
163 }; | |
164 | |
165 void SetUp() override | |
166 { | |
167 const char* const kHTMLString = | |
168 "<div id='empty_div' style='width: 100px; height: 100px;'></div>" | |
169 "<span id='text_div'>Sometexttoshow</span>"; | |
170 | |
171 m_webView = m_helper.initialize(false); | |
172 m_mainFrame = m_webView->mainFrameImpl(); | |
173 FrameTestHelpers::loadHTMLString(m_mainFrame, kHTMLString, URLTestHelper s::toKURL("http://foobar.com")); | |
174 m_webView->resize(WebSize(800, 600)); | |
175 m_webView->page()->focusController().setActive(true); | |
176 | |
177 auto* document = m_mainFrame->frame()->document(); | |
178 ASSERT(document); | |
tkent
2016/03/25 03:33:03
ASSERT() is deprecated.
| |
179 | |
180 auto* emptyDiv = document->getElementById("empty_div"); | |
181 auto* textDiv = document->getElementById("text_div"); | |
182 ASSERT_TRUE(emptyDiv); | |
tkent
2016/03/25 03:33:03
ASSERT_NE(nullptr, emptyDiv), or DCHECK_NE(emptyDi
| |
183 ASSERT_TRUE(textDiv); | |
tkent
2016/03/25 03:33:03
Ditto.
| |
184 } | |
185 | |
186 void checkMouseClicks(Element& element, bool doubleClickEvent) | |
187 { | |
188 struct ScopedListenersCleaner { | |
189 ScopedListenersCleaner(Element* element) : m_element(element) {} | |
190 | |
191 ~ScopedListenersCleaner() | |
192 { | |
193 m_element->removeAllEventListeners(); | |
194 } | |
195 | |
196 RawPtrWillBePersistent<Element> m_element; | |
197 } const listenersCleaner(&element); | |
198 | |
199 RefPtrWillBeRawPtr<MockEventListener> eventHandler = MockEventListener:: create(); | |
200 element.addEventListener( | |
201 doubleClickEvent ? EventTypeNames::dblclick : EventTypeNames::click, | |
202 eventHandler); | |
203 | |
204 ::testing::InSequence s; | |
205 EXPECT_CALL(*eventHandler, handleEvent(_, _)).Times(1); | |
206 | |
207 const auto& elemBounds = element.boundsInViewport(); | |
208 const int clickCount = doubleClickEvent ? 2 : 1; | |
209 emulateMouseClick(elemBounds.center(), WebMouseEvent::ButtonLeft, 0, cli ckCount); | |
210 | |
211 if (doubleClickEvent) { | |
212 EXPECT_EQ(element.innerText().isEmpty(), getSelectionText().empty()) ; | |
213 } | |
214 } | |
215 }; | |
216 | |
217 TEST_F(LinkSelectionClickEvents, SingleAndDoubleClickWillBeHandled) | |
218 { | |
219 auto* document = m_mainFrame->frame()->document(); | |
220 auto* element = document->getElementById("empty_div"); | |
221 | |
222 { | |
223 SCOPED_TRACE("Empty div, single click"); | |
224 checkMouseClicks(*element, false); | |
225 } | |
226 | |
227 { | |
228 SCOPED_TRACE("Empty div, double click"); | |
229 checkMouseClicks(*element, true); | |
230 } | |
231 | |
232 element = document->getElementById("text_div"); | |
233 | |
234 { | |
235 SCOPED_TRACE("Text div, single click"); | |
236 checkMouseClicks(*element, false); | |
237 } | |
238 | |
239 { | |
240 SCOPED_TRACE("Text div, double click"); | |
241 checkMouseClicks(*element, true); | |
242 } | |
243 } | |
244 | |
245 } // namespace blink | |
OLD | NEW |