当动画发生时,Selenium FirefoxDriver点击了错误的链接
Selenium FirefoxDriver clicks on wrong link when animations occur
我正在使用Selenium 2.35,在尝试点击firefox中的一个元素时出现了一个不可预测的错误,如下所示:
new Actions(driver).moveToElement(element).click().perform();
我所定位的元素是<span>元素与一个点击事件相关联。我遇到的问题是,当Firefox尝试点击该元素时,偶尔会错过并点击一个完全不同的元素。如果我使用调试器浏览代码,问题永远不会发生,这让我相信FirefoxDriver只是在浏览器上点击了错误的位置,这与时间问题有关。存在动态加载的<div>在我的页面上,使我想要点击的元素在我找到它并发送.click()命令之前下移。我相信这就是我问题的根源。我可以放一个Thread.sleep(500)来确保它有足够的时间来完成动画和插入动态div,但这对我来说似乎很草率。有没有办法告诉我的FirefoxDriver,等到屏幕上的元素移动完成后,它才能尝试发送.click()事件?
此外,我尝试只发送元素.click(),但似乎失败的次数更多。
更新(9/15/13):
在@MrTi评论的帮助下,我得出的解决方案如下:
private void jsClickOnElementById(String id)
{
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.id(id)));
JavascriptExecutor js = (JavascriptExecutor)driver;
StringBuilder sb = new StringBuilder();
sb.append("var x = $('#" + id + "');");
sb.append("x.click();");
js.executeScript(sb.toString());
}
为了确保元素确实在页面上,我添加了最初的"等待"调用,然后使用JavascriptExecutor运行一些jquery并单击页面上的元素。这似乎对我的案子很有效。如果有人能帮助解决这个解决方案的一些缺点,他们将不胜感激,因为我对JavascriptExecutor类还很陌生。
除了确保页面使用ExpectedConditions实际可见外,还可以通过处理页面上的动画(转换)来解决这种情况。
可以禁用页面上的所有动画,直到页面刷新,方法是执行:
(JavascriptExecutor)driver.executeScript("$('body').append('<style> * {transition: none!important;}</style>')")
此外,如果你知道获得动画的特定元素,你可以检查它是否已设置动画(JQuery动画选择器):
(Boolean)((JavascriptExecutor)driver).executeScript("return $("#ELEMENT_ID").is(":animated")")
如果特定元素未知,您可以确定是否所有动画都已完成:
(Boolean)((JavascriptExecutor)driver).executeScript("return $(":animated").length == 0 ")
遗憾的是,在2018年(五年后),我可以确认selenium中的element.click()并不总是点击正确的元素。我仍然需要使用JavascriptExecutor来执行jquery,以便通过jquery $(selector).click()
按ID点击元素,从而自信地点击该元素。
不仅仅是因为滚动、动画或屏幕外的原因找不到元素,Selenium对Marionette内部DOM树的包装似乎与firefox的geckodriver不同步,因为动态加载的元素(在本例中是表行)
我相信发生的事情是动态加载使选择器选择了其他东西。如果您发布HTML(尤其是在动态加载之前/之后),这将对编写更好的选择器非常有帮助。
但是,有几种方法可以等待加载完成。
第一个等待直到(Boolean)((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")
返回true。这将等待页面上的所有JQuery完成(这可能是导致动态加载的原因)。这是有用的,但我建议等待其他东西。
第二种选择是等待,直到出现动态加载的元素:
wait.until(ExpectedConditions.presenceOfElementSelectedBy(...selector...));
我喜欢这种方法,因为它会等你需要的时间,而且不会再等了。
最后一个选择是编写一个选择器,它将始终选择元素,即使其他事情正在进行。这可能是你的最佳选择,但你也可能遇到StaleElementReferenceExceptions
。
- $q.reject和处理AngularJS链接承诺中的错误
- jquery备用链接错误
- 如果URL's链接返回错误
- 如何从 MVC4 链接调用 Javascript 方法(错误 JavaScript 运行时错误:对象不支持此操作)
- 第二个引导程序导航栏链接打开第一个(错误的)导航栏;jquery
- fs extra:错误:EPERM:不允许操作,取消链接
- CasperJS:如何点击框架中的链接,关闭页面,没有错误
- 链接程序时出现WebGL错误
- 单击链接时出现函数未定义错误
- 如何链接javascript承诺和错误
- 创建到电子表格创建错误中的文件的链接的脚本“;无法转换“”;
- JavaScript链接错误
- 内部链接返回空错误,我在 Javascript 中找不到错误.外部链接工作得很好
- HTML 内容中的 CSS 链接在加载 HTML 时会引发错误
- Gulp 在 gulp.src() 中的符号链接上给出错误
- 页面加载时出现浏览器链接 JS 错误
- 延迟链接 - 然后在上一个调用完成但出现错误时调用成功回调
- j查询 长按链接时的移动错误
- 从timeline2.6.1的例子不工作-错误链接是未定义的时间线代码0
- Grails资源标签生成错误链接