是否可以通过编程确定是否使用W3C动作命令?

时间:2018-08-22 20:27:34

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

Actions.moveToElement的{​​{3}}表示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();
    }
}

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

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

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

2 个答案:

答案 0 :(得分:1)

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

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/moveto规范中的JsonWireProtocol,提到:

    /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偏移量。

视野内中心点

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

  • 让矩形成为通过调用元素上的getClientRects返回的DOMRect序列的第一个元素。
  • 让左为(max(0,min(x坐标,x坐标+宽度尺寸)))。
  • 让我们成为(min(innerWidth,max(x坐标,x坐标+宽度尺寸)))。
  • 让top成为(max(0,min(y坐标,y坐标+高度尺寸)))。
  • 让底部成为(min(innerHeight,max(y坐标,y坐标+高度尺寸)))。
  • 让x为(0.5×(左+右))。
  • 让我们成为(0.5×(顶部+底部))。
  • 将x和y成对返回。

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

答案 1 :(得分: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();