【问题标题】:Selenium: Clicking on toaster issuesSelenium:点击烤面包机问题
【发布时间】:2014-05-05 19:46:48
【问题描述】:

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

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

但是,当我在 chrome 中执行此操作时,我收到了 org.openqa.selenium.WebDriverException: unknown error: Element is not clickable at point (994, 758)

暂停测试执行,我在屏幕上看不到烤面包机。我认为开发人员必须通过使其呈现在一个遥远的、不可滚动的位置来隐藏它。所以作为权宜之计,我加了一个条件,如果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>

发生了什么事?烤面包机怎么可能无法点击,但无论如何都会收到点击? Firefox 可以很好地处理测试,不管有没有 800 像素的解决方法;只有 Chrome 有这个问题。

澄清:测试的目的不是点击烤面包机。目标是单击页面上的另一个元素。测试报告说烤面包机挡住了路,所以我尝试编写一个步骤来关闭烤面包机(如果显示)。我还没有看到这个烤面包机,所以我不确定它是什么,但是 chrome 一直报告它在路上。我们站点范围内的所有烤面包机都使用包含关闭按钮的基本模板,以便用户可以关闭烤面包机,这就是我要单击的内容。 Firefox 从来没有这个问题,也没有报告任何烤面包机的存在。

我之所以称它为烤面包机,是因为我们的网站就是这样称呼它的,因为无论我们从哪个框架(jQuery UI?Backbone?)中获取它,它都是这样称呼的。如果我暂停执行,此时在测试中我看不到任何烤面包机,但 jQuery 告诉我它存在并且可见。但是,使用 jQuery 找到的元素只有我们的烤面包机设置的默认部分:一个 div、一个空的 div,其中应该是消息,以及关闭按钮。显然,此时它不应该被渲染,但 Chrome 认为它会妨碍它。

【问题讨论】:

  • 有趣。 toasterClose.isDisplayed() 说什么?烤面包机是否以某种方式滑入屏幕,还是立即(消失)出现?我们在一个框架内吗?一些较旧的 Webdriver 在计算 iframe 中的正确点击坐标时遇到问题。
  • 有什么更新吗?我的以下任何建议有帮助吗?
  • @Kache 对不起,我病了,等我明天再回到系统前面再说

标签: java selenium-webdriver


【解决方案1】:

我假设“烤面包机”是指某种带有关闭按钮的 javascript 模态弹出窗口。

找出正确的问题
您正在测试 #toaster 元素的存在和可见性,而不是您正在单击的 toasterClose 元素。不能保证仅仅因为一个元素存在并显示,另一个元素也存在。从错误来看,#toaster 元素似乎与toasterClose 元素重叠,使其无法点击。

可点击性问题排查
正确选择 toasterClose 后,手动使用 devtools 并检查它为什么无法点击。是否可见且通畅? toasterClose 元素的高度/宽度是否为零?是否有动态 JavaScript 修改页面后加载?它实际上是否位于页面视图中? (我让元素在窗口边缘明显呈现,但被浏览器的滚动条挡住了。1

替代方案
你还应该看看你是否真的需要使用这个toasterClose 元素。人类将如何关闭此弹出窗口?他们会按Escape 吗?他们会在弹出窗口外点击覆盖元素吗?他们是否做了其他事情来触发某种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

未来/附加
如果这是您经常遇到的问题,我建议将此代码包装在 try/catch 和重试机制中,以使其对 javascript 动态加载的元素具有弹性。

1更新
只是为了详细说明我遇到的滚动条问题,因为事实证明它与您的问题非常相似。


在这里,“我感觉很幸运”按钮不在视线范围内。如果 Selenium 尝试点击它,首先它会尝试将其滚动到视图中。


这是 Selenium 尝试做的一个例子。注意按钮现在是如何“显示”的。


但是,OSX 上的 Chrome 的样式是滚动条通常是隐藏的。 Selenium 发出滚动命令的那一刻,滚动条出现并且以下单击命令无法到达按钮。

解决方案是使用javascript手动滚动窗口:

page.execute_script(<<-javascript)
  document.getElementById("gbqfsb").scrollIntoView(true);
  // or if that doesn't work:
  window.scrollTo(0, document.getElementById("gbqfsb").getBoundingClientRect().top);
javascript

【讨论】:

  • ToasterClose 包含在#toaster 元素中。当我暂停执行并用我的眼球检查屏幕时,我在任何地方都看不到烤面包机。 toasterClose 是烤面包机一角的一个大 [X] 按钮,他们可以点击此处将其关闭。
  • 我给你赏金,但是,提到滚动条,因为这是让我找出真正问题的原因
  • 哦,很好。那么真正的问题是什么?您最终是否不得不滚动/调整浏览器窗口的大小?
  • 是的,我必须滚动。我添加了一个解释原因的自我回答
【解决方案2】:

试试下面的代码。应该工作:

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

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

}

【讨论】:

  • 为什么? toasterClose.click() 没有这样做有什么作用?这个解决方案背后的想法是什么?
  • 几天前我遇到了一个类似的问题,十字图标的某些部分不可点击,必须在该元素周围移动才能到达十字图标可点击的位置以使点击事件起作用。在这里想到了类似的东西。
  • 一个问题@Yamikuronue:建议的解决方案对你有用吗?
  • 不会,烤面包机没有显示在屏幕上,所以这与您遇到的问题不同。我很感激这些信息
【解决方案3】:

您可以使用键盘上的退出键手动关闭烤面包机吗? 如果可以,请使用以下内容:

Actions action = new Actions(driver); action.sendKeys(Keys.ESCAPE).build().perform();

【讨论】:

  • 烤面包机没有明显打开,所以我不确定?
【解决方案4】:

似乎烤面包机被部分渲染并固定在屏幕底部边缘下方的 DOM 上,使用 position:fixed 阻止它显示,直到它准备好填充数据并在屏幕上设置动画。当 chrome 尝试单击屏幕底部边缘下方的链接时,它预测它会撞到烤面包机并且实际上并没有打扰滚动。

经过一番谷歌搜索,我添加了以下实用功能:

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

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

【讨论】:

  • 哦,哈!这几乎就是我提到一半的滚动条问题。我正在争论是否要详细说明它。我想如果我有,它可能是你问题的答案。不过,无论如何,我都会用一些细节来更新我的答案。
猜你喜欢
  • 1970-01-01
  • 2018-02-26
  • 2022-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-24
  • 2018-05-12
相关资源
最近更新 更多