OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 } | 112 } |
113 | 113 |
114 virtual void TearDown() | 114 virtual void TearDown() |
115 { | 115 { |
116 Platform::current()->unitTestSupport()->unregisterAllMockedURLs(); | 116 Platform::current()->unitTestSupport()->unregisterAllMockedURLs(); |
117 } | 117 } |
118 | 118 |
119 protected: | 119 protected: |
120 void runTouchActionTest(std::string file); | 120 void runTouchActionTest(std::string file); |
121 void runShadowDOMTest(std::string file); | 121 void runShadowDOMTest(std::string file); |
122 void sendTouchEvent(WebView*, WebInputEvent::Type, blink::IntPoint clientPoi
nt); | 122 void sendTouchEvent(WebView*, WebInputEvent::Type, IntPoint clientPoint); |
123 WebView* setupTest(std::string file, TouchActionTrackingWebViewClient&); | 123 WebView* setupTest(std::string file, TouchActionTrackingWebViewClient&); |
124 void runTestOnTree(blink::ContainerNode* root, WebView*, TouchActionTracking
WebViewClient&); | 124 void runTestOnTree(ContainerNode* root, WebView*, TouchActionTrackingWebView
Client&); |
125 | 125 |
126 std::string m_baseURL; | 126 std::string m_baseURL; |
127 FrameTestHelpers::WebViewHelper m_webViewHelper; | 127 FrameTestHelpers::WebViewHelper m_webViewHelper; |
128 }; | 128 }; |
129 | 129 |
130 void TouchActionTest::runTouchActionTest(std::string file) | 130 void TouchActionTest::runTouchActionTest(std::string file) |
131 { | 131 { |
132 TouchActionTrackingWebViewClient client; | 132 TouchActionTrackingWebViewClient client; |
133 | 133 |
134 // runTouchActionTest() loads a document in a frame, setting up a | 134 // runTouchActionTest() loads a document in a frame, setting up a |
135 // nested message loop. Should any Oilpan GC happen while it is in | 135 // nested message loop. Should any Oilpan GC happen while it is in |
136 // effect, the implicit assumption that we're outside any event | 136 // effect, the implicit assumption that we're outside any event |
137 // loop (=> there being no pointers on the stack needing scanning) | 137 // loop (=> there being no pointers on the stack needing scanning) |
138 // when that GC strikes will no longer hold. | 138 // when that GC strikes will no longer hold. |
139 // | 139 // |
140 // To ensure that the references on the stack are also traced, we | 140 // To ensure that the references on the stack are also traced, we |
141 // turn them into persistent, stack allocated references. This | 141 // turn them into persistent, stack allocated references. This |
142 // workaround is sufficient to handle this artificial test | 142 // workaround is sufficient to handle this artificial test |
143 // scenario. | 143 // scenario. |
144 WebView* webView = setupTest(file, client); | 144 WebView* webView = setupTest(file, client); |
145 | 145 |
146 RefPtrWillBePersistent<blink::Document> document = static_cast<PassRefPtrWil
lBeRawPtr<blink::Document> >(webView->mainFrame()->document()); | 146 RefPtrWillBePersistent<Document> document = static_cast<PassRefPtrWillBeRawP
tr<Document> >(webView->mainFrame()->document()); |
147 runTestOnTree(document.get(), webView, client); | 147 runTestOnTree(document.get(), webView, client); |
148 | 148 |
149 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally
scoped client. | 149 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally
scoped client. |
150 } | 150 } |
151 | 151 |
152 void TouchActionTest::runShadowDOMTest(std::string file) | 152 void TouchActionTest::runShadowDOMTest(std::string file) |
153 { | 153 { |
154 TouchActionTrackingWebViewClient client; | 154 TouchActionTrackingWebViewClient client; |
155 | 155 |
156 WebView* webView = setupTest(file, client); | 156 WebView* webView = setupTest(file, client); |
157 | 157 |
158 blink::TrackExceptionState es; | 158 TrackExceptionState es; |
159 | 159 |
160 // Oilpan: see runTouchActionTest() comment why these are persistent referen
ces. | 160 // Oilpan: see runTouchActionTest() comment why these are persistent referen
ces. |
161 RefPtrWillBePersistent<blink::Document> document = static_cast<PassRefPtrWil
lBeRawPtr<blink::Document> >(webView->mainFrame()->document()); | 161 RefPtrWillBePersistent<Document> document = static_cast<PassRefPtrWillBeRawP
tr<Document> >(webView->mainFrame()->document()); |
162 RefPtrWillBePersistent<blink::StaticElementList> hostNodes = document->query
SelectorAll("[shadow-host]", es); | 162 RefPtrWillBePersistent<StaticElementList> hostNodes = document->querySelecto
rAll("[shadow-host]", es); |
163 ASSERT_FALSE(es.hadException()); | 163 ASSERT_FALSE(es.hadException()); |
164 ASSERT_GE(hostNodes->length(), 1u); | 164 ASSERT_GE(hostNodes->length(), 1u); |
165 | 165 |
166 for (unsigned index = 0; index < hostNodes->length(); index++) { | 166 for (unsigned index = 0; index < hostNodes->length(); index++) { |
167 blink::ShadowRoot* shadowRoot = hostNodes->item(index)->shadowRoot(); | 167 ShadowRoot* shadowRoot = hostNodes->item(index)->shadowRoot(); |
168 runTestOnTree(shadowRoot, webView, client); | 168 runTestOnTree(shadowRoot, webView, client); |
169 } | 169 } |
170 | 170 |
171 // Projections show up in the main document. | 171 // Projections show up in the main document. |
172 runTestOnTree(document.get(), webView, client); | 172 runTestOnTree(document.get(), webView, client); |
173 | 173 |
174 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally
scoped client. | 174 m_webViewHelper.reset(); // Explicitly reset to break dependency on locally
scoped client. |
175 } | 175 } |
176 | 176 |
177 WebView* TouchActionTest::setupTest(std::string file, TouchActionTrackingWebView
Client& client) | 177 WebView* TouchActionTest::setupTest(std::string file, TouchActionTrackingWebView
Client& client) |
178 { | 178 { |
179 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL),
WebString::fromUTF8(file)); | 179 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL),
WebString::fromUTF8(file)); |
180 // Note that JavaScript must be enabled for shadow DOM tests. | 180 // Note that JavaScript must be enabled for shadow DOM tests. |
181 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + file, true,
0, &client); | 181 WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + file, true,
0, &client); |
182 | 182 |
183 // Lock page scale factor to avoid zooming out to contents size. | 183 // Lock page scale factor to avoid zooming out to contents size. |
184 m_webViewHelper.webView()->setPageScaleFactorLimits(1, 1); | 184 m_webViewHelper.webView()->setPageScaleFactorLimits(1, 1); |
185 | 185 |
186 // Set size to enable hit testing, and avoid line wrapping for consistency w
ith browser. | 186 // Set size to enable hit testing, and avoid line wrapping for consistency w
ith browser. |
187 webView->resize(WebSize(800, 1200)); | 187 webView->resize(WebSize(800, 1200)); |
188 | 188 |
189 // Scroll to verify the code properly transforms windows to client co-ords. | 189 // Scroll to verify the code properly transforms windows to client co-ords. |
190 const int kScrollOffset = 100; | 190 const int kScrollOffset = 100; |
191 RefPtrWillBeRawPtr<blink::Document> document = static_cast<PassRefPtrWillBeR
awPtr<blink::Document> >(webView->mainFrame()->document()); | 191 RefPtrWillBeRawPtr<Document> document = static_cast<PassRefPtrWillBeRawPtr<D
ocument> >(webView->mainFrame()->document()); |
192 document->frame()->view()->setScrollOffset(blink::IntPoint(0, kScrollOffset)
); | 192 document->frame()->view()->setScrollOffset(IntPoint(0, kScrollOffset)); |
193 | 193 |
194 return webView; | 194 return webView; |
195 } | 195 } |
196 | 196 |
197 void TouchActionTest::runTestOnTree(blink::ContainerNode* root, WebView* webView
, TouchActionTrackingWebViewClient& client) | 197 void TouchActionTest::runTestOnTree(ContainerNode* root, WebView* webView, Touch
ActionTrackingWebViewClient& client) |
198 { | 198 { |
199 // Find all elements to test the touch-action of in the document. | 199 // Find all elements to test the touch-action of in the document. |
200 blink::TrackExceptionState es; | 200 TrackExceptionState es; |
201 | 201 |
202 // Oilpan: see runTouchActionTest() comment why these are persistent referen
ces. | 202 // Oilpan: see runTouchActionTest() comment why these are persistent referen
ces. |
203 RefPtrWillBePersistent<blink::StaticElementList> elements = root->querySelec
torAll("[expected-action]", es); | 203 RefPtrWillBePersistent<StaticElementList> elements = root->querySelectorAll(
"[expected-action]", es); |
204 ASSERT_FALSE(es.hadException()); | 204 ASSERT_FALSE(es.hadException()); |
205 | 205 |
206 for (unsigned index = 0; index < elements->length(); index++) { | 206 for (unsigned index = 0; index < elements->length(); index++) { |
207 Element* element = elements->item(index); | 207 Element* element = elements->item(index); |
208 element->scrollIntoViewIfNeeded(); | 208 element->scrollIntoViewIfNeeded(); |
209 | 209 |
210 std::string failureContext("Test case: "); | 210 std::string failureContext("Test case: "); |
211 if (element->hasID()) { | 211 if (element->hasID()) { |
212 failureContext.append(element->getIdAttribute().ascii().data()); | 212 failureContext.append(element->getIdAttribute().ascii().data()); |
213 } else if (element->firstChild()) { | 213 } else if (element->firstChild()) { |
214 failureContext.append("\""); | 214 failureContext.append("\""); |
215 failureContext.append(element->firstChild()->textContent(false).stri
pWhiteSpace().ascii().data()); | 215 failureContext.append(element->firstChild()->textContent(false).stri
pWhiteSpace().ascii().data()); |
216 failureContext.append("\""); | 216 failureContext.append("\""); |
217 } else { | 217 } else { |
218 failureContext += "<missing ID>"; | 218 failureContext += "<missing ID>"; |
219 } | 219 } |
220 | 220 |
221 // Run each test three times at different positions in the element. | 221 // Run each test three times at different positions in the element. |
222 // Note that we don't want the bounding box because our tests sometimes
have elements with | 222 // Note that we don't want the bounding box because our tests sometimes
have elements with |
223 // multiple border boxes with other elements in between. Use the first b
order box (which | 223 // multiple border boxes with other elements in between. Use the first b
order box (which |
224 // we can easily visualize in a browser for debugging). | 224 // we can easily visualize in a browser for debugging). |
225 RefPtrWillBePersistent<blink::ClientRectList> rects = element->getClient
Rects(); | 225 RefPtrWillBePersistent<ClientRectList> rects = element->getClientRects()
; |
226 ASSERT_GE(rects->length(), 0u) << failureContext; | 226 ASSERT_GE(rects->length(), 0u) << failureContext; |
227 RefPtrWillBePersistent<blink::ClientRect> r = rects->item(0); | 227 RefPtrWillBePersistent<ClientRect> r = rects->item(0); |
228 blink::FloatRect clientFloatRect = blink::FloatRect(r->left(), r->top(),
r->width(), r->height()); | 228 FloatRect clientFloatRect = FloatRect(r->left(), r->top(), r->width(), r
->height()); |
229 blink::IntRect clientRect = enclosedIntRect(clientFloatRect); | 229 IntRect clientRect = enclosedIntRect(clientFloatRect); |
230 for (int locIdx = 0; locIdx < 3; locIdx++) { | 230 for (int locIdx = 0; locIdx < 3; locIdx++) { |
231 blink::IntPoint clientPoint; | 231 IntPoint clientPoint; |
232 std::stringstream contextStream; | 232 std::stringstream contextStream; |
233 contextStream << failureContext << " ("; | 233 contextStream << failureContext << " ("; |
234 switch (locIdx) { | 234 switch (locIdx) { |
235 case 0: | 235 case 0: |
236 clientPoint = clientRect.center(); | 236 clientPoint = clientRect.center(); |
237 contextStream << "center"; | 237 contextStream << "center"; |
238 break; | 238 break; |
239 case 1: | 239 case 1: |
240 clientPoint = clientRect.location(); | 240 clientPoint = clientRect.location(); |
241 contextStream << "top-left"; | 241 contextStream << "top-left"; |
242 break; | 242 break; |
243 case 2: | 243 case 2: |
244 clientPoint = clientRect.maxXMaxYCorner(); | 244 clientPoint = clientRect.maxXMaxYCorner(); |
245 clientPoint.move(-1, -1); | 245 clientPoint.move(-1, -1); |
246 contextStream << "bottom-right"; | 246 contextStream << "bottom-right"; |
247 break; | 247 break; |
248 default: | 248 default: |
249 FAIL() << "Invalid location index."; | 249 FAIL() << "Invalid location index."; |
250 } | 250 } |
251 contextStream << "=" << clientPoint.x() << "," << clientPoint.y() <<
")."; | 251 contextStream << "=" << clientPoint.x() << "," << clientPoint.y() <<
")."; |
252 std::string failureContextPos = contextStream.str(); | 252 std::string failureContextPos = contextStream.str(); |
253 | 253 |
254 blink::LocalFrame* frame = root->document().frame(); | 254 LocalFrame* frame = root->document().frame(); |
255 blink::FrameView* frameView = frame->view(); | 255 FrameView* frameView = frame->view(); |
256 blink::IntRect visibleRect = frameView->windowClipRect(); | 256 IntRect visibleRect = frameView->windowClipRect(); |
257 ASSERT_TRUE(visibleRect.contains(clientPoint)) << failureContextPos | 257 ASSERT_TRUE(visibleRect.contains(clientPoint)) << failureContextPos |
258 << " Test point not contained in visible area: " << visibleRect.
x() << "," << visibleRect.y() | 258 << " Test point not contained in visible area: " << visibleRect.
x() << "," << visibleRect.y() |
259 << "-" << visibleRect.maxX() << "," << visibleRect.maxY(); | 259 << "-" << visibleRect.maxX() << "," << visibleRect.maxY(); |
260 | 260 |
261 // First validate that a hit test at this point will really hit the
element | 261 // First validate that a hit test at this point will really hit the
element |
262 // we intended. This is the easiest way for a test to be broken, but
has nothing really | 262 // we intended. This is the easiest way for a test to be broken, but
has nothing really |
263 // to do with touch action. | 263 // to do with touch action. |
264 // Note that we can't use WebView's hit test API because it doesn't
look into shadow DOM. | 264 // Note that we can't use WebView's hit test API because it doesn't
look into shadow DOM. |
265 blink::IntPoint docPoint(frameView->windowToContents(clientPoint)); | 265 IntPoint docPoint(frameView->windowToContents(clientPoint)); |
266 blink::HitTestResult result = frame->eventHandler().hitTestResultAtP
oint(docPoint, blink::HitTestRequest::ReadOnly | blink::HitTestRequest::Active); | 266 HitTestResult result = frame->eventHandler().hitTestResultAtPoint(do
cPoint, HitTestRequest::ReadOnly | HitTestRequest::Active); |
267 ASSERT_EQ(element, result.innerElement()) << "Unexpected hit test re
sult " << failureContextPos | 267 ASSERT_EQ(element, result.innerElement()) << "Unexpected hit test re
sult " << failureContextPos |
268 << " Got element: \"" << result.innerElement()->outerHTML().str
ipWhiteSpace().left(80).ascii().data() << "\"" | 268 << " Got element: \"" << result.innerElement()->outerHTML().str
ipWhiteSpace().left(80).ascii().data() << "\"" |
269 << std::endl << "Document render tree:" << std::endl << external
Representation(root->document().frame()).utf8().data(); | 269 << std::endl << "Document render tree:" << std::endl << external
Representation(root->document().frame()).utf8().data(); |
270 | 270 |
271 // Now send the touch event and check any touch action result. | 271 // Now send the touch event and check any touch action result. |
272 sendTouchEvent(webView, WebInputEvent::TouchStart, clientPoint); | 272 sendTouchEvent(webView, WebInputEvent::TouchStart, clientPoint); |
273 | 273 |
274 AtomicString expectedAction = element->getAttribute("expected-action
"); | 274 AtomicString expectedAction = element->getAttribute("expected-action
"); |
275 if (expectedAction == "auto") { | 275 if (expectedAction == "auto") { |
276 // Auto is the default - no action set. | 276 // Auto is the default - no action set. |
(...skipping 20 matching lines...) Expand all Loading... |
297 } | 297 } |
298 } | 298 } |
299 | 299 |
300 // Reset webview touch state. | 300 // Reset webview touch state. |
301 client.reset(); | 301 client.reset(); |
302 sendTouchEvent(webView, WebInputEvent::TouchCancel, clientPoint); | 302 sendTouchEvent(webView, WebInputEvent::TouchCancel, clientPoint); |
303 EXPECT_EQ(0, client.touchActionSetCount()); | 303 EXPECT_EQ(0, client.touchActionSetCount()); |
304 } | 304 } |
305 } | 305 } |
306 } | 306 } |
307 void TouchActionTest::sendTouchEvent(WebView* webView, WebInputEvent::Type type,
blink::IntPoint clientPoint) | 307 void TouchActionTest::sendTouchEvent(WebView* webView, WebInputEvent::Type type,
IntPoint clientPoint) |
308 { | 308 { |
309 ASSERT_TRUE(type == WebInputEvent::TouchStart || type == WebInputEvent::Touc
hCancel); | 309 ASSERT_TRUE(type == WebInputEvent::TouchStart || type == WebInputEvent::Touc
hCancel); |
310 | 310 |
311 WebTouchEvent webTouchEvent; | 311 WebTouchEvent webTouchEvent; |
312 webTouchEvent.type = type; | 312 webTouchEvent.type = type; |
313 if (type == WebInputEvent::TouchCancel) | 313 if (type == WebInputEvent::TouchCancel) |
314 webTouchEvent.cancelable = false; | 314 webTouchEvent.cancelable = false; |
315 webTouchEvent.touchesLength = 1; | 315 webTouchEvent.touchesLength = 1; |
316 webTouchEvent.touches[0].state = (type == WebInputEvent::TouchStart ? | 316 webTouchEvent.touches[0].state = (type == WebInputEvent::TouchStart ? |
317 WebTouchPoint::StatePressed : | 317 WebTouchPoint::StatePressed : |
(...skipping 24 matching lines...) Expand all Loading... |
342 { | 342 { |
343 runShadowDOMTest("touch-action-shadow-dom.html"); | 343 runShadowDOMTest("touch-action-shadow-dom.html"); |
344 } | 344 } |
345 | 345 |
346 TEST_F(TouchActionTest, Pan) | 346 TEST_F(TouchActionTest, Pan) |
347 { | 347 { |
348 runTouchActionTest("touch-action-pan.html"); | 348 runTouchActionTest("touch-action-pan.html"); |
349 } | 349 } |
350 | 350 |
351 } | 351 } |
OLD | NEW |