- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我将 Selenium WebDriver 与 java.awt.Robot 结合使用,以更好地模拟用户与我们的 Web 应用程序的交互。是的,我知道这可能是不必要的,但我服务的客户需要它。
目前一切正常,但我遇到了一个小问题,因为我似乎无法找到一种好的方法来获取 Web 元素在屏幕上的位置。标题栏、菜单栏、导航栏等都将内容向下推到物理屏幕上(机器人从中获取坐标),但对 Selenium 报告元素所在的位置没有影响。
当我在 Selenium WebElement 上调用:element.getLocation();
时,它总是给我它相对于 HTML 内容呈现 Pane 的位置,而不是浏览器窗口本身。
更好的例子是:driver.findElement(By.tagName("body")).getLocation();
总是返回 0,0,无论窗口在屏幕上的实际位置如何。
现在我正在通过在最大化窗口后添加垂直和水平偏移来破解它,但这些在不同的浏览器之间并不相同(例如,IE 的顶部装饰比 Firefox 占用更多空间),并且可能不同对于每个用户,如果他们添加了书签工具栏、搜索栏等。
是的,我知道我可以在全屏模式下运行,但我宁愿不要,如果可能的话。
有没有办法使用 WebDriver 以可靠的方式获取元素在屏幕上的物理位置?
最佳答案
我相信没有办法获得页面上元素的真实屏幕位置。
我也认为全屏模式是最好的选择。
也就是说,我编写了一个 RobotCalibration
类,它可以检测当前浏览器的实际偏移量。它打开一个特制页面并使用 Robot
类点击它。该算法从浏览器的中心开始,然后使用平分法找到浏览器视口(viewport)的左上角。
在 IE8 和 FF18 上测试。适用于最大化和窗口浏览器。已知问题:如果您启用了顶部书签工具栏,它可能会点击某些书签并因此重定向。它可以很容易地处理,但如果你需要的话,我把它留给你了:)。
测试页面:
<!DOCTYPE html>
<html lang="en" onclick="document.getElementById('counter').value++">
<head>
<meta charset="utf-8" />
<title>Calibration Test</title>
</head>
<body>
<img height="1" width="1" style="position: absolute; left: 0; top: 0;"
onclick="document.getElementById('done').value = 'yep'" />
<input type="text" id="counter" value="0" />
<input type="text" id="done" value="nope" />
</body>
</html>
RobotCalibration
类。它有点长,所以我建议您将它复制粘贴到您最喜欢的 IDE 中并在那里进行探索:
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.InputEvent;
import java.nio.file.Paths;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
public class RobotCalibration {
public static Point calibrate(WebDriver driver) {
return new RobotCalibration(driver).calibrate();
}
/** Time for which to wait for the page response. */
private static final long TIMEOUT = 1000;
private final WebDriver driver;
private final Robot r;
private final Point browserCenter;
private int leftX;
private int rightX;
private int midX;
private int topY;
private int bottomY;
private int midY;
private RobotCalibration(WebDriver driver) {
this.driver = driver;
try {
driver.manage().window().getSize();
} catch (UnsupportedOperationException headlessBrowserException) {
throw new IllegalArgumentException("Calibrating a headless browser makes no sense.", headlessBrowserException);
}
try {
this.r = new Robot();
} catch (AWTException headlessEnvironmentException) {
throw new IllegalStateException("Robot won't work on headless environments.", headlessEnvironmentException);
}
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
org.openqa.selenium.Dimension browserSize = driver.manage().window().getSize();
org.openqa.selenium.Point browserPos = driver.manage().window().getPosition();
// a maximized browser returns negative position
// a maximized browser returns size larger than actual screen size
// you can't click outside the screen
leftX = Math.max(0, browserPos.x);
rightX = Math.min(leftX + browserSize.width, screenSize.width - 1);
midX = (leftX + rightX) /2;
topY = Math.max(0, browserPos.y);
bottomY = Math.min(topY + browserSize.height, screenSize.height - 1);
midY = (topY + bottomY) /2;
browserCenter = new Point(midX, midY);
}
private Point calibrate() {
driver.get(Paths.get("files/RobotCalibration.html").toUri().toString());
// find left border
while (leftX < rightX) {
click(midX, midY);
if (clickWasSuccessful()) {
rightX = midX;
} else {
leftX = midX + 1;
// close any menu we could have opened
click(browserCenter.x, browserCenter.y);
}
midX = (leftX + rightX) /2;
}
// find top border
while (topY < bottomY) {
click(midX, midY);
if (clickWasSuccessful()) {
bottomY = midY;
} else {
topY = midY + 1;
// close any menu we could have opened
click(browserCenter.x, browserCenter.y);
}
midY = (topY + bottomY) /2;
}
if (!isCalibrated()) {
throw new IllegalStateException("Couldn't calibrate the Robot.");
}
return new Point(midX, midY);
}
/** clicks on the specified location */
private void click(int x, int y) {
r.mouseMove(x, y);
r.mousePress(InputEvent.BUTTON1_DOWN_MASK);
r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
// for some reason, my IE8 can't properly register clicks that are close
// to each other faster than click every half a second
if (driver instanceof InternetExplorerDriver) {
sleep(500);
}
}
private static void sleep(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException ignored) {
// nothing to do
}
}
private int counter = 0;
/** @return whether the click on a page was successful */
private boolean clickWasSuccessful() {
counter++;
long targetTime = System.currentTimeMillis() + TIMEOUT;
while (System.currentTimeMillis() < targetTime) {
int pageCounter = Integer.parseInt(driver.findElement(By.id("counter")).getAttribute("value"));
if (counter == pageCounter) {
return true;
}
}
return false;
}
/** @return whether the top left corner has already been clicked at */
private boolean isCalibrated() {
long targetTime = System.currentTimeMillis() + TIMEOUT;
while (System.currentTimeMillis() < targetTime) {
if (driver.findElement(By.id("done")).getAttribute("value").equals("yep")) {
return true;
}
}
return false;
}
}
示例用法:
WebDriver driver = new InternetExplorerDriver();
Point p = RobotCalibration.calibrate(driver);
System.out.println("Left offset: " + p.x + ", top offset: " + p.y);
driver.quit();
如有任何不清楚的地方,请随时提问。
关于java - 使用 Java 的 Selenium WebDriver 和 HTML 窗口位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14655581/
我想在 Watir webdriver 中使用 selenium webdriver Actions。这可能吗? 也可以在 watir webdriver 中使用 java 代码。请帮忙。 我浏览了很
我正在使用 watir-webdriver 浏览我的网站并在不同的浏览器中抓取屏幕截图。 有时在 IE 中截取的屏幕截图大小合适,但颜色完全是黑色。同时运行的 Firefox 测试看起来很好。 bro
我已经编写了 driver.findElement(By.id("kfiDocumentLink")).click(); 用于单击“KFI 文档”按钮的代码。 请找到HTML代码。 Download
我有一个包含以下内容的 html 页面: This is Login page. Please click below link
我想获得页面加载异常,但仍然没有结果。 我使用implicitlyWait 设置计时器以抛出异常。 WebDriver driver = new FirefoxDriver(); driver.man
我正在使用具有 IE 特定应用程序的 Selenium Webdriver。我知道我们可以截取执行的截图。同样,是否有任何选项可以将 selenium 执行记录为视频? 最佳答案 WebDriver
Selenium WebDriver 如何克服同源策略? Selenium RC 中存在同源策略问题 最佳答案 First of all “Same Origin Policy” is introdu
我将如何从输入文件中提取文本?我尝试使用 XPath/CSSSelector 但我得到一个空文本,因为它是一个输入字段。 这是我的 html 代码: 结果:195 行中的 1 到 50
如何使用 WebDriver 自动验证码? 是否有其他方法可以使用 Webdriver 自动执行验证码? 最佳答案 您只能使用“alt”属性中的显示验证码值来自动化验证码。 在 WebElement
最近我开始学习 WebDriver,因为我工作的客户计划使用 WebDriver 来自动化 Web 应用程序。 我怀疑 WebDriver 如何在网页上定位其 ID 动态变化的元素(比如每次登录应用程
我发现 watir-webdriver 在一个非常大的页面上通过正则表达式定位元素非常慢,至少在 FF 8.0.1 中对我来说是这样。航类搜索结果页面示例(包含大约 50 个搜索结果,每个都是 htm
我有一个动态更改其文本的字段。我需要一种方法来等待文本被更改。我不知道会出现什么文本,但我知道当前那里有什么文本。所以我想等待它在元素中消失。有办法吗? 最佳答案 你可以试试ExpectedCondi
自从我使用 Firefox 升级到 3.0 beta 后,我就有了这个异常(exception)。 Exception in thread "main" java.lang.IllegalStateE
任何人都可以帮助我使用 Selenium webdriver 截取整页屏幕截图。我正在使用 c#/Nunit。我正在使用的当前方法不是完整的浏览器页面。 我正在使用下面的代码截取屏幕截图。 publi
我通过 WebDriver (Chrome) 从网页下载图像 // STEP 1 $driver->get($link); // STEP 2 $els=$driver->findElements(W
Selenium WebDriver 的默认隐式等待值是什么? selenium 文档说它是“0”,但是当我在一个全新的项目上调用 .findElement 时,DOM 上不存在元素,它似乎在一段时间
我正在使用 Webdriver 测试 Web 应用程序,大致如下所述。当测试通过时,一切都很好。但是,当其中一个测试失败时,我注意到以下 2 个问题。 a) 如果一个测试失败,则套件中的其余测试将超时
我正在使用 Selenium WebDriver 并遇到问题。 在 UI 中,WebDriver 可以看到元素,但无法执行任何操作,例如单击、键入、选择等。元素由 selenium 找到并作为 web
我在 Java 中使用 Web 驱动程序处理 UntrustedSSLcertificates 时陷入困境。 我创建了 Firefox 配置文件,如: FirefoxProfile profile =
选择的编程语言是 Java。我已经用 Java 编写了一个方法,我将 WebDriver 作为参数传递给它... public boolean myMethod(WebDriver webDriver
我是一名优秀的程序员,十分优秀!