1

前置要求:

硒 3.141

火狐浏览器

要求:获取网页元素的 x,y 坐标并执行鼠标移动到 xy 坐标。X 计算正确,而y 坐标下降了 100 像素。

注意:Webelement Formfield 是隐藏的,用户将执行垂直滚动并单击它。滚动后获取坐标。

WebElement fromfield = driver.findElement(By.xpath("//*[contains(@data-field-name,'deliverables')]"));
jse.executeScript("arguments[0].scrollIntoView();",fromfield); //scroll to the webelement, a small wait is given after scrolling

org.openqa.selenium.Point fromLocation = fromfield.getLocation();

int fromfield_x = fromLocation.x; 
int fromfield_y = fromLocation.y; //getx/gety returns same values

Actual Output: x = 550, y = 600
Expected Output: x = 550, y = 700. (**Note**: If I pass 700, then mouse moves correctly to required element, but here y is calculated incorrect)

其他试验:尝试以全屏模式打开浏览器,但同样的问题。

查询:

如何获得精确的y坐标?

xy 坐标是从桌面窗口或视口的左上角计算的吗?


更新

地位:

根据您的建议,我尝试了下面的代码行,是的,它会自动滚动到所需的元素。

WebElement source = fromfield.findElement(By.xpath(".//*[contains(@title,'test')]"));
 new Actions(driver).moveToElement(new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(source))).build().perform();

结果1:

System.out.println("Y coordinate is: "+source.getLocation().getY());
int from_x = source.getLocation().getX();
int from_y = source.getLocation().getY();

我得到 y co-ords 为 700,但元素可能为 900 像素。

当我做 mousemove 时,它​​会移动到返回的 700 像素,这不是要拖动的元素。我的 webelement (source) 仍然是 900 像素。X坐标完全OK。

robot.mouseMove(from_x , from_y); //moves to 700 pixels
Actions maction=new Actions(driver);
Action drag = maction.clickAndHold(source).pause(3000).build();
drag.perform(); //tries to drag from 700 pixels

或者

new Actions(driver).moveToElement(new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(source))).clickAndHold(source).build().perform();

y 再次不足。原因是什么?

结果2: 上面的代码片段(movetoelement)适用于chrome,但不适用于firefox。

4

1 回答 1

1

获取位置()

getLocation()返回页面上呈现元素左上角所在的点,即一个点,包含元素左上角的位置。


作为提取Google 主页搜索框的XY坐标的示例,您可以使用以下解决方案:

  • 代码块:

    driver.get("https://www.google.com/");
    WebElement element = new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.name("q")));
    Point elementLocation = element.getLocation();
    System.out.println("X coordinate of the element is: "+elementLocation.getX());
    System.out.println("Y coordinate of the element : "+elementLocation.getY());
    //or
    WebElement elem = new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.name("q")));
    System.out.println("X coordinate is: "+elem.getLocation().getX());
    System.out.println("Y coordinate is: "+elem.getLocation().getY());
    driver.quit();
    
  • 控制台输出:

    X coordinate of the element is: 439
    Y coordinate of the element : 322
    X coordinate is: 439
    Y coordinate is: 322
    

更新 1

从您的问题中不清楚为什么要执行鼠标移动到xy坐标。但是,为了获得最佳结果,您需要:

  • 在尝试调用之前诱导WebDriverWaitvisibilityOfElementLocated()scrollIntoView()

  • 在您尝试交互之前诱导WebDriverWait即调用elementToBeClickable()click()


结论

正如您所提到的...执行垂直滚动并单击它...scrollIntoView()看起来像一个纯粹的开销

以下方法:

将自动滚动Viewport中的元素。


更新 2

根据您的评论以解决有关...超出视口范围的错误...您可以参考讨论org.openqa.selenium.interactions.MoveTargetOutOfBoundsException: (x, y) is out of bounds while MouseHover with GeckoDriver Firefox Selenium


更新 3

根据您的评论...返回时移动到 700 像素,这不是要拖动的元素...值得一提的是,正如我在答案中已经提到的那样,它getLocation()返回页面左上角的点- 渲染元素的手角。而要执行成功的拖放操作,大概需要将可拖动元素拖动到可放置元素内的一定百分比。

此外,如果要拖动的 html5 元素具有draggable需要以不同方式处理的属性,这完全是一个不同的主题,我们可以在单独的线程中讨论它。

相关的 HTML 会在很大程度上帮助我们。


参考

您可以在以下位置找到一些相关的详细讨论:

于 2019-10-24T11:16:09.067 回答