Selenium Webdriver(JAVA)代码在“上退出”;如果条件是“;关于不存在无接触元素例外的元素。

Selenium Webdriver(JAVA)代码在“上退出”;如果条件是“;关于不存在无接触元素例外的元素。,java,selenium,selenium-webdriver,webdriver,Java,Selenium,Selenium Webdriver,Webdriver,我正在尝试自动化一个脚本。您可以得到如下代码的想法 driver.findElement(By.id("ctl00_body_txtUserID")).sendKeys("Donhere"); driver.findElement(By.id("ctl00_body_txtPassword")).sendKeys("don@123"); driver.findElement(By.id("ctl00_body_btnLogin")).click(); if(driver.findElement(

我正在尝试自动化一个脚本。您可以得到如下代码的想法

driver.findElement(By.id("ctl00_body_txtUserID")).sendKeys("Donhere");
driver.findElement(By.id("ctl00_body_txtPassword")).sendKeys("don@123");
driver.findElement(By.id("ctl00_body_btnLogin")).click();
if(driver.findElement(By.className("tcuarea")).isDisplayed()){
     driver.findElement(By.id("ctl00_Add")).click();
}
driver.findElement(By.id("ctl00_Add_to_Sum")).click();
id为ctl00\u Add的元素很少出现。因此,如果条件结果为TRUE,脚本将继续正常运行。但如果条件为FALSE,则仍进入if条件,此时不显示此类元素。它会导致NoTouchElementException异常

为什么脚本不直接移动到下一步


没有try,catch方法的任何解决方案?

您可以使用try-catch块绑定相同的解决方案,如下所示:

try {
    driver.findElement(By.className("tcuarea")).isDisplayed();
    driver.findElement(By.id("ctl00_Add")).click();
}
catch(Exception e) {
  System.out.println(e.getMessage());
            }  
if(driver.findElement(By.className("tcuarea")).getSize().height != 0){
     driver.findElement(By.id("ctl00_Add")).click();
}

因此,在
driver.findElement(By.className(“tcuarea”)).isDisplayed()的情况下
将抛出NoTouchElement异常,您可以转到catch块并执行某些操作。

如果
findElement
无法找到它抛出的元素
NoTouchElementException
。为了避免它,您可以使用
findElements
查找列表并检查其是否为空,这样您就不需要使用
try-catch

List<WebElement> elements = driver.findElements(By.id("ctl00_Add"));
if (elements.size() > 0) {
    elements.get(0).click();
}
List elements=driver.findElements(By.id(“ctl00_-Add”);
if(elements.size()>0){
元素。获取(0)。单击();
}

这也是推荐的方法。

这是该方法的预期行为isDisplayed()的存在告诉您已定位的元素

NoTouchElement异常: selenium引发异常,声明在DOM中找不到该元素

显示的有以下两种情况:

返回“true”:元素已在DOM中找到,且未隐藏或元素的维度不为零

返回“false”:该元素已在页面上找到;但它是隐藏的或具有属性style=“display: none;“那么isDisplayed()将返回false


在您的场景中,建议使用try catch

由于您的要求是调用
click()
,在.id(“ctl00\u Add”)标识为
的元素上调用
click()
我认为没有必要检查:

driver.findElement(By.className("tcuarea")).isDisplayed())
此外,我不确定您的用例为什么要避免
try/catch{}
块。可能是以下任何一种例外情况:

  • NoTouchElementException
  • TimeoutException
一般来说,最好的解决方法是
try/catch{}
,因为您总是可以捕获异常,而不会停止执行。 同样,
findElements()
是另一个基本解决方案。但就个人而言,我会选择
try/catch{}

你可以马上:

try {
    new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.id("ctl00_Add"))).click();
}
catch(Exception e) {
    System.out.println(e.getMessage());
}  

按如下所示更换if条件:

try {
    driver.findElement(By.className("tcuarea")).isDisplayed();
    driver.findElement(By.id("ctl00_Add")).click();
}
catch(Exception e) {
  System.out.println(e.getMessage());
            }  
if(driver.findElement(By.className("tcuarea")).getSize().height != 0){
     driver.findElement(By.id("ctl00_Add")).click();
}

有时selenium isDisplayed()函数不适用于HTML代码。所以我们需要检查我们正在寻找的元素的高度。如果元素未显示且仍为isDisplayed(),则返回true,元素的高度将为零。这种方法对我有效。

您没有提供足够的信息。html是什么样子的。类名为“tcuarea”的元素上有哪些javascript规则。如何使该元素在前端不可见?
尝试catch
findElements
,在IMO中只有两种方式。但是findElements的问题是,如果未找到元素,它将等待到隐式等待中定义的时间。因此,在我看来,我们应该更喜欢try-catch。这是selenium没有任何预定义方法来解决的重要问题之一。这的确是一个非常重要的问题。这就是WATIR不完全使用隐式等待的原因。如果不使用try-catch块,就无法得到任何好的解决方案,但在执行检查之前,您也需要单独创建一个函数,将隐式等待设置为零,然后需要重置隐式等待。@Rajagopalan:同意。创建一个不同的方法并将隐式等待设置为0或1秒会很好。OP专门编写了没有try,catch方法的任何解决方案?@Guy:不,只有findElements,但findElements的问题是,如果找不到元素,它将等待到隐式等待中定义的时间。@Guy:好,我没有看到这一点,赶紧给出答案。当您使用
findElement
Selenium无法正确处理某些事情时,您将从
隐式等待中得到相同的等待,这就是其中之一,显示的元素必须立即回复用户是否显示,但驱动程序级别的等待将不允许发生这种情况,并且selenium没有任何其他方法来解决此问题。id为ctl00_Add的元素很少显示。对于通常不存在的元素,每次将等待20秒。还有,任何没有尝试的解决方案,捕获方法?他清楚地提到,
任何没有尝试的解决方案,捕获方法?
@Guy will wait 20秒几乎是可配置的,可以根据测试规范进行设置。@Rajagopalan展示OP可能不熟悉的最佳方法的好处有什么不对?@DebanjanB True其可配置,但是使用显式等待一些你知道可能不会发生的事情是一种不好的做法。IsDisplayed一直都非常有效。我从未见过它无法执行此任务。这并不能解决获取
NoTouchElementException
的问题。如果条件返回false,它将不会进入If条件,因此不会单击id为ct100\u add的元素。因此,对于ct100_add.if条件使用find元素,它将永远不会遇到NoSuchElementException。这就是您实际要检查的元素。即使在完成if条件之前,它也可能抛出nosuchelementexist的错误。@Hemendra它永远不会遇到NoSuchElementException错误。如果元素不存在,
driver.findElement
将抛出异常,甚至不会到达
getSize()
部分。这是正确的解决方案,但您将陷入隐式等待。所以试着接球