java - 是否可以通过编程方式确定是否使用了 W3C 操作命令?

标签 java selenium selenium-webdriver webdriver webdriver-w3c-spec

Selenium Javadoc对于Actions.moveToElement表示xOffsetyOffset参数含义如下。

xOffset - Offset from the top-left corner. A negative value means coordinates left from the element.
yOffset - Offset from the top-left corner. A negative value means coordinates above the element.

考虑以下程序,在 Linux 上针对 Firefox Quantum 运行。

public class FirefoxTest {
    public static void main(String[] args) {
        // Set up driver
        WebDriver driver = new FirefoxDriver();
        JavascriptExecutor js = (JavascriptExecutor) driver;

        driver.get("http://www.google.com");
        WebElement element = new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.name("q")));

        // Perform a move and click action to see where it lands.
        Actions moveAndClick = new Actions(driver).moveToElement(element,0,0).doubleClick();
        moveAndClick.perform();
    }
}

当运行下面的程序时,双击发生在搜索框的中间,而不是左上角(我知道这个是因为我注入(inject)了JS来记录搜索框的位置点击)。此外,在程序运行的终端中输出如下信息。

org.openqa.selenium.interactions.Actions moveToElement
INFO: When using the W3C Action commands, offsets are from the center of element

对于 Actions.moveToElement 是否可以通过编程方式确定偏移量是从元素的中心还是左上角开始?

最佳答案

首先,当调用 GeckoDriver 时,第一组日志确认 dialectW3C,如下所示:

org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C

您作为 moveToElement()Java 文档是正确的仍然提到:

public Actions moveToElement(WebElement target, int xOffset, int yOffset)

Description:
Moves the mouse to an offset from the top-left corner of the element. The element is scrolled into view and its location is calculated using getBoundingClientRect.

Parameters:
    target - element to move to.
    xOffset - Offset from the top-left corner. A negative value means coordinates left from the element.
    yOffset - Offset from the top-left corner. A negative value means coordinates above the element.

Returns:
A self reference.

我可以按如下方式重现您的问题:

  • 代码块:

    new Actions(driver).moveToElement(element,0,0).doubleClick().build().perform();
    
  • 跟踪日志:

    Oct 16, 2018 6:06:13 PM org.openqa.selenium.interactions.Actions moveToElement
    INFO: When using the W3C Action commands, offsets are from the center of element
    1539693373141   webdriver::server   DEBUG   -> POST /session/180ab0f0-21a3-4e38-8c92-d208fac77827/actions {"actions":[{"id":"default mouse","type":"pointer","parameters":{"pointerType":"mouse"},"actions":[{"duration":100,"x":0,"y":0,"type":"pointerMove","origin":{"ELEMENT":"774efad2-7ee0-40a3-bcaa-3a4d5fcff47b","element-6066-11e4-a52e-4f735466cecf":"774efad2-7ee0-40a3-bcaa-3a4d5fcff47b"}},{"button":0,"type":"pointerDown"},{"button":0,"type":"pointerUp"},{"button":0,"type":"pointerDown"},{"button":0,"type":"pointerUp"}]}]}
    1539693373166   Marionette  TRACE   0 -> [0,5,"WebDriver:PerformActions",{"actions":[{"actions":[{"duration":100,"origin":{"element-6066-11e4-a52e-4f735466cecf":"774e ... pointerDown"},{"button":0,"type":"pointerUp"}],"id":"default mouse","parameters":{"pointerType":"mouse"},"type":"pointer"}]}]
    

正如@Andreas 在讨论中指出的那样 offsets are from the center of element instead of from the top-left corner @FlorentB。明确指出:

  • 根据 /session/:sessionId/movetoJsonWireProtocol提到的规范:

    /session/:sessionId/moveto
        POST /session/:sessionId/moveto
        Move the mouse by an offset of the specificed element. If no element is specified, the move is relative to the current mouse cursor. If an element is provided but no offset, the mouse will be moved to the center of the element. If the element is not visible, it will be scrolled into view.
    
        URL Parameters:
        :sessionId - ID of the session to route the command to.
    
        JSON Parameters:
        element - {string} Opaque ID assigned to the element to move to, as described in the WebElement JSON Object. If not specified or is null, the offset is relative to current position of the mouse.
        xoffset - {number} X offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element.
        yoffset - {number} Y offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element.
    
  • 根据 Pointer Actions内节WebDriver W3C Editor's Draft据说:

    代表网络元素的对象

    1. 令元素等于尝试获取具有参数原点的已知连通元素的结果。

    2. 令x元素和y元素为计算元素的视野中心点的结果。

    3. 设 x 等于 x 元素 + x 偏移量,y 等于 y 元素 + y 偏移量。

视野中心点

元素的 View 中心点是矩形的原点位置,该矩形是元素的第一个 DOM 客户端矩形和初始视口(viewport)之间的交点。给定一个已知在 View 中的元素,它被计算为:

  • 令矩形成为通过对元素调用 getClientRects 返回的 DOMRect 序列的第一个元素。
  • 让左边为 (max(0, min(x 坐标, x 坐标 + 宽度尺寸)))。
  • 设右边为 (min(innerWidth, max(x 坐标, x 坐标 + 宽度尺寸)))。
  • 设 top 为 (max(0, min(y 坐标, y 坐标 + 高度尺寸)))。
  • 设 bottom 为 (min(innerHeight, max(y coordinate, y coordinate + height dimension)))。
  • 令 x 为 (0.5 × (left + right))。
  • 设 y 为 (0.5 × (top + bottom))。
  • 返回成对的 x 和 y。

因此可以得出结论,偏移量来自中心,但 Jave Docs 尚未更新。

关于java - 是否可以通过编程方式确定是否使用了 W3C 操作命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51974620/

相关文章:

ruby - 运行 Ruby Selenium 测试用例时出现 "Failed assertion, no message given."错误

java - 如何使用 Selenium 在 Indeed 上单击“立即申请”按钮?

selenium - RemoteWebDriver 和 WebDriver 有什么区别?

node.js - 当它应该返回当前窗口句柄时,为什么我会收到 "NoSuchWindowError"错误和 "getWindowHandle"?

python - Selenium webdriver 链接提取

java - 如何在没有uri的情况下将查询传递给rest模板中的url

java - Undefined Name "Y",以及奇怪的输出问题

java - 使用 volley 时,数据未在微调器中显示 - 真实设备问题

bash - Docker 网络不适用于 bash 入口点

java - 在同一函数内将 var 分配给 String