4

Selenium Javadoc forActions.moveToElement表明xOffset和参数的含义yOffset如下。

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();
    }
}

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

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

是否可以以编程方式确定偏移量是来自元素的中心还是左上角Actions.moveToElement

4

2 回答 2

1

首先,在调用GeckoDriver时,第一组日志确认方言W3C如下:

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

您是正确的,因为Java DocsmoveToElement()仍然提到:

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 在讨论中指出的那样,偏移量来自元素的中心,而不是来自@FlorentB 的左上角。明确指出:

  • 根据JsonWireProtocol规范中的/session/:sessionId/moveto,它被提到:

    /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.
    
  • 根据WebDriver W3C Editor's Draft 中的Pointer Actions部分,提到:

    表示 Web 元素的对象

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

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

    3. 让 x 等于 x 元素 + x 偏移,并且 y 等于 y 元素 + y 偏移。

视野中心点

元素的视图中心点是矩形的原点位置,该矩形是元素的第一个 DOM 客户矩形和初始视口之间的交点。给定一个已知可见的元素,它的计算公式为:

  • 让 rectangle 成为通过在 element 上调用 getClientRects 返回的 DOMRect 序列的第一个元素。
  • 让left为(max(0,min(x坐标,x坐标+宽度尺寸)))。
  • 设右为 (min(innerWidth, max(x 坐标, x 坐标 + 宽度尺寸)))。
  • 让顶部为 (max(0, min(y 坐标, y 坐标 + 高度维度)))。
  • 设底部为 (min(innerHeight, max(y 坐标, y 坐标 + 高度尺寸)))。
  • 令 x 为 (0.5 × (left + right))。
  • 设 y 为 (0.5 × (top + bottom))。
  • 将 x 和 y 作为一对返回。

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

于 2018-10-16T13:14:02.263 回答
0

如果要求单击元素的左上角,则以下代码片段将执行

WebElement element = new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.name("q")));
        Actions moveAndClick = new 
int yOffset=element.getRect().height/-2;//top
int xOffset=element.getRect().width/-2;//left
Actions(driver).moveToElement(element,xOffset,yOffset).doubleClick().perform();
于 2020-07-10T07:46:12.637 回答