Index: Source/web/tests/TouchActionTest.cpp |
diff --git a/Source/web/tests/TouchActionTest.cpp b/Source/web/tests/TouchActionTest.cpp |
index 695d18a9193bfeecf8ef69726906bcea94f1905f..4222c5c14014a72f4e25fc5a0a66230d25fd2229 100755 |
--- a/Source/web/tests/TouchActionTest.cpp |
+++ b/Source/web/tests/TouchActionTest.cpp |
@@ -119,9 +119,11 @@ public: |
protected: |
void runTouchActionTest(std::string file); |
void runShadowDOMTest(std::string file); |
+ void runTouchActionHitTest(std::string file); |
void sendTouchEvent(WebView*, WebInputEvent::Type, WebCore::IntPoint clientPoint); |
WebView* setupTest(std::string file, TouchActionTrackingWebViewClient&); |
void runTestOnTree(WebCore::Node* root, WebView*, TouchActionTrackingWebViewClient&); |
+ void runHitTestOnTree(WebCore::Node* root, WebView*, TouchActionTrackingWebViewClient&); |
std::string m_baseURL; |
FrameTestHelpers::WebViewHelper m_webViewHelper; |
@@ -158,6 +160,16 @@ void TouchActionTest::runShadowDOMTest(std::string file) |
runTestOnTree(document.get(), webView, client); |
} |
+void TouchActionTest::runTouchActionHitTest(std::string file) |
+{ |
+ TouchActionTrackingWebViewClient client; |
+ |
+ WebView* webView = setupTest(file, client); |
+ |
+ RefPtr<WebCore::Document> document = static_cast<PassRefPtr<WebCore::Document> >(webView->mainFrame()->document()); |
+ runHitTestOnTree(document.get(), webView, client); |
+} |
+ |
WebView* TouchActionTest::setupTest(std::string file, TouchActionTrackingWebViewClient& client) |
{ |
URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL), WebString::fromUTF8(file)); |
@@ -282,6 +294,87 @@ void TouchActionTest::runTestOnTree(WebCore::Node* root, WebView* webView, Touch |
} |
} |
} |
+ |
+void TouchActionTest::runHitTestOnTree(WebCore::Node* root, WebView* webView, TouchActionTrackingWebViewClient& client) |
Rick Byers
2014/01/17 16:12:46
Is there reason you need to add a new type of test
gnana
2014/01/21 14:00:16
Ok. i understood. i will apply this in next patch.
|
+{ |
+ // Find all elements to test the touch-action of in the document. |
+ WebCore::TrackExceptionState es; |
+ RefPtr<WebCore::NodeList> expectedNodes = root->querySelectorAll("[expected-hittest]", es); |
+ ASSERT_FALSE(es.hadException()); |
+ |
+ RefPtr<WebCore::NodeList> nodes = root->querySelectorAll("[hittest]", es); |
+ ASSERT_FALSE(es.hadException()); |
+ |
+ for (unsigned index = 0; index < nodes->length(); index++) { |
+ WebCore::Element* element = toElement(nodes->item(index)); |
+ element->scrollIntoViewIfNeeded(); |
+ ASSERT_TRUE(nodes->item(index)->isElementNode()); |
+ |
+ std::string failureContext("Test case: "); |
+ if (element->hasID()) { |
+ failureContext.append(element->getIdAttribute().ascii().data()); |
+ } else if (element->firstChild()) { |
+ failureContext.append("\""); |
+ failureContext.append(element->firstChild()->textContent(false).stripWhiteSpace().ascii().data()); |
+ failureContext.append("\""); |
+ } else { |
+ failureContext += "<missing ID>"; |
+ } |
+ |
+ // Run each test three times at different positions in the element. |
+ // Note that we don't want the bounding box because our tests sometimes have elements with |
+ // multiple border boxes with other elements in between. Use the first border box (which |
+ // we can easily visualize in a browser for debugging). |
+ RefPtr<WebCore::ClientRectList> rects = element->getClientRects(); |
+ ASSERT_GE(rects->length(), 0u) << failureContext; |
+ RefPtr<WebCore::ClientRect> r = rects->item(0); |
+ WebCore::FloatRect clientFloatRect = WebCore::FloatRect(r->left(), r->top(), r->width(), r->height()); |
+ WebCore::IntRect clientRect = enclosedIntRect(clientFloatRect); |
+ for (int locIdx = 0; locIdx < 3; locIdx++) { |
+ WebCore::IntPoint clientPoint; |
+ std::stringstream contextStream; |
+ contextStream << failureContext << " ("; |
+ switch (locIdx) { |
+ case 0: |
+ clientPoint = clientRect.center(); |
+ contextStream << "center"; |
+ break; |
+ case 1: |
+ clientPoint = clientRect.location(); |
+ contextStream << "top-left"; |
+ break; |
+ case 2: |
+ clientPoint = clientRect.maxXMaxYCorner(); |
+ clientPoint.move(-1, -1); |
+ contextStream << "bottom-right"; |
+ break; |
+ default: |
+ FAIL() << "Invalid location index."; |
+ } |
+ contextStream << "=" << clientPoint.x() << "," << clientPoint.y() << ")."; |
+ std::string failureContextPos = contextStream.str(); |
+ |
+ WebCore::Frame* frame = root->document().frame(); |
+ WebCore::FrameView* frameView = frame->view(); |
+ WebCore::IntRect visibleRect = frameView->windowClipRect(); |
+ ASSERT_TRUE(visibleRect.contains(clientPoint)) << failureContextPos |
+ << " Test point not contained in visible area: " << visibleRect.x() << "," << visibleRect.y() |
+ << "-" << visibleRect.maxX() << "," << visibleRect.maxY(); |
+ |
+ // First validate that a hit test at this point will really hit the element |
+ // we intended. This is the easiest way for a test to be broken, but has nothing really |
+ // to do with touch action. |
+ // Note that we can't use WebView's hit test API because it doesn't look into shadow DOM. |
+ WebCore::IntPoint docPoint(frameView->windowToContents(clientPoint)); |
+ WebCore::HitTestResult result = frame->eventHandler().hitTestResultAtPoint(docPoint, WebCore::HitTestRequest::ReadOnly | WebCore::HitTestRequest::Active | WebCore::HitTestRequest::TouchAction); |
+ WebCore::Element* expectedElement = toElement(expectedNodes->item(index)); |
+ ASSERT_EQ(expectedElement, result.innerElement()) << "Unexpected hit test result " << failureContextPos |
+ << " Got element: \"" << result.innerElement()->outerHTML().stripWhiteSpace().left(80).ascii().data() << "\"" |
+ << std::endl << "Document render tree:" << std::endl << externalRepresentation(root->document().frame()).utf8().data(); |
+ } |
+ } |
+} |
+ |
void TouchActionTest::sendTouchEvent(WebView* webView, WebInputEvent::Type type, WebCore::IntPoint clientPoint) |
{ |
ASSERT_TRUE(type == WebInputEvent::TouchStart || type == WebInputEvent::TouchCancel); |
@@ -324,4 +417,9 @@ TEST_F(TouchActionTest, Pan) |
runTouchActionTest("touch-action-pan.html"); |
} |
+TEST_F(TouchActionTest, HitTest) |
+{ |
+ runTouchActionHitTest("touch-action-hittest.html"); |
+} |
+ |
} |