先决条件:
Selenium 3.141
火狐浏览器
要求:获取WebElement的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 坐标是从桌面窗口或视口(viewport)的左上角计算的吗?
更新
状态:
根据您的建议,我尝试了下面的代码行,是的,它会自动滚动到所需的元素。
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 坐标为 700,但元素可能为 900 像素。
当我执行 mousemove 时,它会移动到返回的 700 像素,这不是要拖动的元素。我的 webelement(源)仍然是 900 像素。 X 坐标完全没问题。
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。
最佳答案
获取位置()
getLocation()
返回页面上渲染元素的左上角所在的点,即包含元素左上角位置的点。
作为提取 Google Home Page 上搜索框的X和Y坐标的示例您可以使用以下解决方案:
代码块:
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
坐标。然而,为了获得最佳结果,您需要:
在尝试调用
scrollIntoView()
之前,为visibilityOfElementLocated()
引入 WebDriverWait举个例子:
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("element"))));
您可以在How to scroll UP to an element and click in selenium?中找到相关讨论
在尝试交互之前,为
elementToBeClickable()
引入 WebDriverWait,即调用click()
举个例子:
new Actions(driver).moveToElement(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOf(ParentElement)))).perform(); new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath(subElement))).click();
结论
正如您提到的...执行垂直滚动并单击它...,scrollIntoView()
看起来纯粹是开销如:
以下方法:
将自动滚动视口(viewport)内的元素。
更新2
根据您解决有关...超出视口(viewport)范围...的错误的评论,您可以引用讨论 org.openqa.selenium.interactions.MoveTargetOutOfBoundsException: (x, y) is out of bounds while MouseHover with GeckoDriver Firefox Selenium
更新3
根据您的评论...返回时它移动到 700 像素,这不是要拖动的元素...值得一提的是,正如我在答案中已经提到的那样 < strong>getLocation()
返回页面上渲染元素左上角的点。为了执行成功的拖放操作,大概需要将可拖动元素在可放置元素内拖动到一定百分比。
此外,如果要拖动的html5元素具有属性draggable
,则需要进行不同的处理,这完全是一个不同的主题,我们可以单独讨论它线程。
相关的 HTML 会对我们有很大帮助。
引用文献
您可以在以下位置找到一些相关的详细讨论:
关于java - 如何从 selenium java 中的 getLocation 获取精确的 y 坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58538692/