Title: [226044] releases/WebKitGTK/webkit-2.18/Source/WebKit
Revision
226044
Author
carlo...@webkit.org
Date
2017-12-18 08:56:24 -0800 (Mon, 18 Dec 2017)

Log Message

Merge r225367 - Web Automation: computeElementLayout does not correctly translate iframe client coordinates to main frame coordinates
https://bugs.webkit.org/show_bug.cgi?id=180213
<rdar://problem/30260141>

Reviewed by Simon Fraser.

The current implementation computes points in terms of the frame in which the element is located.
However, WebDriver expects coordinates to be relative to the top-level document since
these coordinates are used for generating click events, among other things.

To convert from frame client coordinates to main frame client coordinates, round-trip
both inViewCenterPoint and elementBounds to root view coordinates and back
to the main frame's contents/client coordinates. Then convert this to page coordinates if needed.

This progresses several tests in the Selenium Python test suite:

 - event_firing_webdriver_tests.py::test_should_fire_navigation_events
 - frame_switching_tests.py::testShouldBeAbleToClickInAFrameThatRewritesTopWindowLocation
 - frame_switching_tests.py::testShouldBeAbleToSwitchToTheTopIfTheFrameIsDeletedFromUnderUs
 - frame_switching_tests.py::testShouldBeAbleToSwitchToTheTopIfTheFrameIsDeletedFromUnderUsWithFrameIndex
 - frame_switching_tests.py::testShouldBeAbleToSwitchToTheTopIfTheFrameIsDeletedFromUnderUsWithWebelement
 - frame_switching_tests.py::testShouldNotBeAbleToDoAnythingTheFrameIsDeletedFromUnderUs
 - position_and_size_tests.py::testShouldGetCoordinatesOfAnInvisibleElement

* WebProcess/Automation/WebAutomationSessionProxy.cpp:
(WebKit::WebAutomationSessionProxy::computeElementLayout):
Get both the frame and main frame FrameViews and convert coordinates to the root view.
This is somewhat lossy as clientToDocument* deals with FloatPoints but contentsToRootView
deals with IntPoints. For the purposes of WebDriver, lossiness is not a problem since
integer values are expected anyway.

The imperative nature of the coordinate calculations is difficult to debug, so I converted
this function to only assign to each variable once.

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.18/Source/WebKit/ChangeLog (226043 => 226044)


--- releases/WebKitGTK/webkit-2.18/Source/WebKit/ChangeLog	2017-12-18 16:56:18 UTC (rev 226043)
+++ releases/WebKitGTK/webkit-2.18/Source/WebKit/ChangeLog	2017-12-18 16:56:24 UTC (rev 226044)
@@ -1,3 +1,39 @@
+2017-11-30  Brian Burg  <bb...@apple.com>
+
+        Web Automation: computeElementLayout does not correctly translate iframe client coordinates to main frame coordinates
+        https://bugs.webkit.org/show_bug.cgi?id=180213
+        <rdar://problem/30260141>
+
+        Reviewed by Simon Fraser.
+
+        The current implementation computes points in terms of the frame in which the element is located.
+        However, WebDriver expects coordinates to be relative to the top-level document since
+        these coordinates are used for generating click events, among other things.
+
+        To convert from frame client coordinates to main frame client coordinates, round-trip
+        both inViewCenterPoint and elementBounds to root view coordinates and back
+        to the main frame's contents/client coordinates. Then convert this to page coordinates if needed.
+
+        This progresses several tests in the Selenium Python test suite:
+
+         - event_firing_webdriver_tests.py::test_should_fire_navigation_events
+         - frame_switching_tests.py::testShouldBeAbleToClickInAFrameThatRewritesTopWindowLocation
+         - frame_switching_tests.py::testShouldBeAbleToSwitchToTheTopIfTheFrameIsDeletedFromUnderUs
+         - frame_switching_tests.py::testShouldBeAbleToSwitchToTheTopIfTheFrameIsDeletedFromUnderUsWithFrameIndex
+         - frame_switching_tests.py::testShouldBeAbleToSwitchToTheTopIfTheFrameIsDeletedFromUnderUsWithWebelement
+         - frame_switching_tests.py::testShouldNotBeAbleToDoAnythingTheFrameIsDeletedFromUnderUs
+         - position_and_size_tests.py::testShouldGetCoordinatesOfAnInvisibleElement
+
+        * WebProcess/Automation/WebAutomationSessionProxy.cpp:
+        (WebKit::WebAutomationSessionProxy::computeElementLayout):
+        Get both the frame and main frame FrameViews and convert coordinates to the root view.
+        This is somewhat lossy as clientToDocument* deals with FloatPoints but contentsToRootView
+        deals with IntPoints. For the purposes of WebDriver, lossiness is not a problem since
+        integer values are expected anyway.
+
+        The imperative nature of the coordinate calculations is difficult to debug, so I converted
+        this function to only assign to each variable once.
+
 2017-11-14  Carlos Garcia Campos  <cgar...@igalia.com>
 
         Move JSONValues to WTF and convert uses of InspectorValues.h to JSONValues.h

Modified: releases/WebKitGTK/webkit-2.18/Source/WebKit/WebProcess/Automation/WebAutomationSessionProxy.cpp (226043 => 226044)


--- releases/WebKitGTK/webkit-2.18/Source/WebKit/WebProcess/Automation/WebAutomationSessionProxy.cpp	2017-12-18 16:56:18 UTC (rev 226043)
+++ releases/WebKitGTK/webkit-2.18/Source/WebKit/WebProcess/Automation/WebAutomationSessionProxy.cpp	2017-12-18 16:56:24 UTC (rev 226044)
@@ -572,15 +572,18 @@
         return;
     }
 
-    WebCore::FloatRect elementBounds = coreElement->boundingClientRect();
-
-    auto* coreFrameView = frame->coreFrame()->view();
+    WebCore::FrameView* frameView = frame->coreFrame()->view();
+    WebCore::FrameView* mainView = frame->coreFrame()->mainFrame().view();
+    WebCore::IntRect frameElementBounds = roundedIntRect(coreElement->boundingClientRect());
+    WebCore::IntRect rootElementBounds = mainView->rootViewToContents(frameView->contentsToRootView(frameElementBounds));
+    WebCore::IntRect resultElementBounds;
     switch (coordinateSystem) {
     case CoordinateSystem::Page:
-        elementBounds = coreFrameView->clientToDocumentRect(elementBounds);
+        resultElementBounds = WebCore::IntRect(mainView->clientToDocumentRect(WebCore::FloatRect(rootElementBounds)));
         break;
     case CoordinateSystem::LayoutViewport:
         // The element bounds are already in client coordinates.
+        resultElementBounds = rootElementBounds;
         break;
     case CoordinateSystem::VisualViewport:
         ASSERT_NOT_REACHED();
@@ -587,17 +590,19 @@
         break;
     }
 
-    std::optional<WebCore::FloatPoint> inViewCenterPoint;
+    std::optional<WebCore::IntPoint> resultInViewCenterPoint;
     bool isObscured = false;
     if (containerElement) {
-        inViewCenterPoint = elementInViewClientCenterPoint(*containerElement, isObscured);
-        if (inViewCenterPoint.has_value()) {
+        std::optional<WebCore::FloatPoint> frameInViewCenterPoint = elementInViewClientCenterPoint(*containerElement, isObscured);
+        if (frameInViewCenterPoint.has_value()) {
+            WebCore::IntPoint rootInViewCenterPoint = mainView->rootViewToContents(frameView->contentsToRootView(WebCore::IntPoint(frameInViewCenterPoint.value())));
             switch (coordinateSystem) {
             case CoordinateSystem::Page:
-                inViewCenterPoint = coreFrameView->clientToDocumentPoint(inViewCenterPoint.value());
+                resultInViewCenterPoint = WebCore::IntPoint(mainView->clientToDocumentPoint(rootInViewCenterPoint));
                 break;
             case CoordinateSystem::LayoutViewport:
                 // The point is already in client coordinates.
+                resultInViewCenterPoint = rootInViewCenterPoint;
                 break;
             case CoordinateSystem::VisualViewport:
                 ASSERT_NOT_REACHED();
@@ -606,7 +611,7 @@
         }
     }
 
-    WebProcess::singleton().parentProcessConnection()->send(Messages::WebAutomationSession::DidComputeElementLayout(callbackID, enclosingIntRect(elementBounds), WebCore::IntPoint(inViewCenterPoint.value()), isObscured, String()), 0);
+    WebProcess::singleton().parentProcessConnection()->send(Messages::WebAutomationSession::DidComputeElementLayout(callbackID, resultElementBounds, resultInViewCenterPoint.value(), isObscured, String()), 0);
 }
 
 void WebAutomationSessionProxy::selectOptionElement(uint64_t pageID, uint64_t frameID, String nodeHandle, uint64_t callbackID)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to