ajax Selenium WebDriver - 确定元素是否可点击(即不被 dojo 模态灯箱遮挡)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9878478/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Selenium WebDriver - determine if element is clickable (i.e. not obscured by dojo modal lightbox)
提问by Matthew
I write automated scripts for testing web applications that are very heavy on ajax. For example, a modal dialog is displayed with the text "Saving..." when saving settings, while a lightbox greys out the rest of the page.
我编写自动化脚本来测试对 ajax 非常重要的 Web 应用程序。例如,Saving...保存设置时会显示带有文本“ ”的模式对话框,而灯箱则使页面的其余部分变灰。
My test scripts are trying to click the next link in the test before the message disappears. It almost always works when driving Firefox, but when driving Chrome the following error is displayed:
我的测试脚本试图在消息消失之前单击测试中的下一个链接。它在驱动 Firefox 时几乎总是有效,但在驱动 Chrome 时显示以下错误:
Exception in thread "main" org.openqa.selenium.WebDriverException: Element is not clickable at point (99.5, 118.5). Other element would receive the click: <div class="dijitDialogUnderlay _underlay" dojoattachpoint="node" id="lfn10Dijit_freedom_widget_common_environment_Dialog_8_underlay" style="width: 1034px; height: 1025px; "></div> (WARNING: The server did not provide any stacktrace information)
This happens because the lightbox is obscuring the element I want to click on. I want to wait for the lightbox to disappear before attempting to click the link.
发生这种情况是因为灯箱遮挡了我想要点击的元素。我想在尝试单击链接之前等待灯箱消失。
Checking for the lightbox to no longer exist is not a valid workaround because there are, at times, multiple levels of modal dialogs and lightboxes, and no easy way to distinguish between them.
检查灯箱是否不再存在并不是一个有效的解决方法,因为有时会有多个级别的模式对话框和灯箱,并且没有简单的方法来区分它们。
Is there a way in Selenium to detect if the element is clickable (no other elements obscuring it)? A try/catch would be a workaround, but I'd prefer to do a proper check if that is possible.
Selenium 有没有办法检测元素是否可点击(没有其他元素遮挡它)?try/catch 将是一种解决方法,但如果可能的话,我更愿意进行适当的检查。
回答by Pavel Zorin
Use the WebDriverWait conditions.
使用 WebDriverWait 条件。
WebDriverWait wait = new WebDriverWait(yourWebDriver, 5);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//xpath_to_element")));
Webdriver will wait for 5 seconds for your element to be able to be clicked.
Webdriver 将等待 5 秒钟让您的元素能够被点击。
回答by sreeharimohan
You can use the ExpectedConditions.invisibilityOfElementLocated(By by)method which waits until the element is either invisible or not present on the DOM.
您可以使用ExpectedConditions.invisibilityOfElementLocated(By by)等待元素不可见或不存在于 DOM 上的方法。
WebDriverWait wait = new WebDriverWait(yourWebDriver, 10);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("yourSavingModalDialogDiv")));
So, depending on how much time your modal dialog takes to go invisible or go off the DOM, webdriver will wait. The wait is for a maximum of 10 seconds.
因此,根据您的模态对话框隐藏或脱离 DOM 所需的时间,webdriver 将等待。等待时间最长为 10 秒。
回答by bbbco
You could create a clickUntilfunction/method that does a WebDriver wait until the element is clickable with a timeout. It would attempt to click on the element, and throw away "Element is not clickable" error messages each time until it becomes clicked or times out.
您可以创建一个clickUntil函数/方法,让 WebDriver 等待元素可点击并超时。它会尝试单击元素,并每次都丢弃“元素不可单击”错误消息,直到它被单击或超时。
Not sure how to write that in dojo, but that's an idea.
不知道如何在 dojo 中编写它,但这是一个想法。
回答by nexoma
In Scala:
在斯卡拉:
Standard code for waiting (visibility/invisibility)
(new WebDriverWait(remote, 45)).until( ExpectedConditions.visibilityOf(remote.findElement(locator)) ) Thread.sleep(3000)More visibility in logs :
while (remote.findElement(locator).isDisplayed) { println(s"isDisplayed: $ii $a : " + remote.findElement(locator).isDisplayed) Thread.sleep(100) }If you have asynchronous JavaScript processes use web-elements with timestamp:
val oldtimestamp = remote.findElements(locator).get(0).getAttribute("data-time-stamp") while (oldtimestamp == remote.findElements(locator).get(0).getAttribute("data-time-stamp")) { println("Tstamp2:" + remote.findElements(locator).get(0).getAttribute("data-time-stamp")) Thread.sleep(200) }
等待的标准代码(可见/不可见)
(new WebDriverWait(remote, 45)).until( ExpectedConditions.visibilityOf(remote.findElement(locator)) ) Thread.sleep(3000)日志中的更多可见性:
while (remote.findElement(locator).isDisplayed) { println(s"isDisplayed: $ii $a : " + remote.findElement(locator).isDisplayed) Thread.sleep(100) }如果您有异步 JavaScript 进程,请使用带有时间戳的 web 元素:
val oldtimestamp = remote.findElements(locator).get(0).getAttribute("data-time-stamp") while (oldtimestamp == remote.findElements(locator).get(0).getAttribute("data-time-stamp")) { println("Tstamp2:" + remote.findElements(locator).get(0).getAttribute("data-time-stamp")) Thread.sleep(200) }
回答by Bartosz Gurgul
I also have same problems, but I tested many input in site. One are clickable which I tested and other - not clickable one just skipped. I made it by try() catch() Simply Code :
我也有同样的问题,但我在网站上测试了很多输入。一种是我测试过的可点击的,另一种是可点击的 - 只是跳过的不可点击的。我是通过 try() catch() 简单代码实现的:
for(){ // for all my input
try {
driver.findElement(By.xpath("...."
+ "//input)["+(i+1)+"]")).click();
... tests...
} catch(Exception e) {
if(e.getMessage().contains("is not clickable at point")) {
System.out.println(driver.findElement(By.xpath(locator)).
getAttribute("name")+" are not clicable");
} else {
System.err.println(e.getMessage());
}
}
And more elegant:
更优雅:
@SuppressWarnings("finally")
public boolean tryClick(WebDriver driver,String locator, locatorMethods m) {
boolean result = false;
switch (m) {
case xpath:
try {
driver.findElement(By.xpath(locator)).click();
result= true;
} catch (Exception e) {
if(e.getMessage().contains("is not clickable at point")) {
System.out.println(driver.findElement(By.xpath(locator)).getAttribute("name")+" are not clicable");
} else {
System.err.println(e.getMessage());
}
} finally {
break;
}
case id:
try {
driver.findElement(By.id(locator)).click();
return true;
} catch (Exception e) {
if(e.getMessage().contains("is not clickable at point")) {
System.out.println(driver.findElement(By.id(locator)).getAttribute("name")+" are not clicable");
} else {
System.err.println(e.getMessage());
}
} finally {
break;
}
default:
System.err.println("Unknown locator!");
}
return result;
}

