Java 硒:点击烤面包机问题

Java 硒:点击烤面包机问题,java,selenium-webdriver,Java,Selenium Webdriver,我试图点击页面上的一个元素;该元素在屏幕上清晰可见。有一个烤面包机可能会弹出,所以我试图写一个防御:如果烤面包机在屏幕上,首先关闭烤面包机,然后继续点击下一页。我使用的是PageFactory,所以我有一个元素包含烤面包机,还有一个元素用于烤面包机的关闭按钮。我的“处理烤面包机”方法如下: if (driver.findElements(By.cssSelector("#toaster")).size() > 0 && toaster.isDisplayed())

我试图点击页面上的一个元素;该元素在屏幕上清晰可见。有一个烤面包机可能会弹出,所以我试图写一个防御:如果烤面包机在屏幕上,首先关闭烤面包机,然后继续点击下一页。我使用的是PageFactory,所以我有一个元素包含烤面包机,还有一个元素用于烤面包机的关闭按钮。我的“处理烤面包机”方法如下:

if (driver.findElements(By.cssSelector("#toaster")).size() > 0 
    && toaster.isDisplayed()) {
    toasterClose.click();
}
然而,当我在chrome中执行此操作时,我得到了
org.openqa.selenium.WebDriverException:未知错误:元素在点(994758)处不可单击

暂停测试执行时,我无法在屏幕上看到烤面包机。我想开发者一定是把它隐藏起来了,让它呈现在一个很远的、不可滚动的位置。因此,作为权宜之计,我添加了一个条件,即如果x坐标大于800,则不要单击。有了这些,我得到:

org.openqa.selenium.WebDriverException: unknown error: Element is not clickable at point (547, 725). Other element would receive the click: <div id="toaster">...</div>
org.openqa.selenium.WebDriverException:未知错误:元素在点(547725)处不可单击。其他元素将收到单击:。。。
发生什么事了?烤面包机怎么可能不可点击,但无论如何都会收到点击?Firefox可以很好地处理测试,不管有没有800像素的解决方案;只有Chrome有这个问题

澄清:测试的目标不是点击烤面包机。目标是单击页面上的另一个元素。测试报告说有一个烤面包机挡道,所以我试图写一个步骤,如果显示烤面包机,就关闭它。我还没有看到这个烤面包机,所以我不确定它到底是什么,但chrome一直报告说它挡道了。我们所有的烤面包机网站都使用一个基本模板,其中包括一个关闭按钮,这样用户就可以关闭烤面包机,这正是我试图单击的。Firefox从未出现过这个问题,也没有报告任何烤面包机的存在

我之所以称它为烤面包机,是因为我们的网站就是这样称呼它的,因为无论我们从哪个框架(jQuery UI?主干网?)获得它,它都是这样称呼的。如果我暂停执行,在测试的这一点上我看不到任何烤面包机,但是jQuery告诉我它存在并且是可见的。但是,jQuery中的元素只有我们的烤面包机设置的默认部分:一个div、消息应该在的空div和close按钮。很明显,这并不意味着要在这个时候渲染,但Chrome认为这是一个障碍

我假设“toaster”是指某种带有关闭按钮的javascript模式弹出窗口

确定正确的问题
您正在测试
#toaster
元素的存在性和可见性,而不是正在单击的
toasterClose
元素。不能保证一个元素存在并显示,另一个元素也存在。从错误中可以看出,
#toaster
元素与
toasterClose
元素重叠,使其不可拾取

故障排除可点击性
一旦正确选择了
烤面包机关闭
,请手动使用devtools并进行检查,查看其不可关闭的原因。它是否可见且无障碍?
toasterClose
元素的高度/宽度是否为零?是否存在修改页面后期加载的动态JavaScript?它是否实际位于页面视图中?(我曾让元素在窗口边缘清晰呈现,但却被浏览器的滚动条挡住了。1)

备选方案
您还应该看看是否真的需要使用这个
toasterClose
元素。人类如何关闭此弹出窗口?他们会按退出键吗?他们会在弹出窗口外的覆盖元素上单击吗?他们是否做了其他一些事情来触发某种
closeModal()
javascript函数?您也可以使用Selenium来执行这些操作

最后一招
要删除这样的弹出窗口,您可以随时运行自己的javascript来修改DOM,并删除所有有问题的元素:

driver.execute_script(<<-javascript)
  var toaster = document.getElementById("toaster");
  toaster.parentNode.removeChild(toaster);

  var overlay = document.getElementById("modal_overlay");
  overlay.parentNode.removeChild(overlay);
javascript

driver.execute_脚本(尝试以下代码。应该可以工作:

if (driver.findElements(By.cssSelector("#toaster")).size() > 0 
    && toaster.isDisplayed()) {

    Actions builder = new Actions(driver);
    builder.moveToElement(toasterClose).moveByOffset(2,2).click().build().perform();

}

你们能用键盘上的退出键手动关闭烤面包机吗。 如果可以,请使用以下选项:

Actions动作=新动作(驱动程序);

action.sendKeys(Keys.ESCAPE).build().perform()

看起来烤面包机部分渲染并固定在屏幕下边缘下方的DOM上,使用position:fixed可以阻止它显示,直到它准备好填充数据并在屏幕上设置动画。当chrome尝试单击屏幕下边缘下方的链接时,它预测它将被删除点击烤面包机,实际上并不需要滚动

在谷歌搜索之后,我添加了以下实用功能:

public static void ScrollElementIntoView(WebDriver driver, WebElement element) {
    ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
}

然后我在点击该页面上的任何链接之前调用此方法,瞧,没有更多的烤面包机问题!

很有趣。
toasterClose.isDisplayed()
说什么?烤面包机是以某种方式滑入屏幕,还是(dis)滑入屏幕立即出现?我们在inframe中吗?一些老的Web驱动程序在计算iframe中的正确点击坐标时遇到问题。有什么更新吗?我下面的建议有帮助吗?@Kache抱歉,我病了,我明天一到系统前面,我就会回到这个问题上。AsterClose包含在#toaster元素中。当我用我的眼球检查屏幕,我在任何地方都看不到烤面包机。烤面包机关闭是一个大[X]按钮,在烤面包机的角落里,他们会点击关闭它。但是,我给你奖金,因为你提到了滚动条,因为这正是我发现真正问题的原因。哦,很好。那么,实际问题是什么?你最终不得不滚动/调整浏览器窗口的大小吗?是的,我不得不滚动。我添加了一个自我回答,解释了为什么hy?这对烤面包机关闭有什么作用?click()没有?这个解决方案背后的想法是什么?I fac
public static void ScrollElementIntoView(WebDriver driver, WebElement element) {
    ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
}