Home » Java » Selenium Webdriver: best practice to handle a NoSuchElementException

Selenium Webdriver: best practice to handle a NoSuchElementException

Posted by: admin December 28, 2021 Leave a comment

Questions:

After much searching and reading, I’m still unclear as to the best way to handle a failed assertion using Webdriver. I would have thought this was a common and core piece of functionality. All I want to do is:

  • look for an element
  • if present – tell me
  • if not present – tell me

I want to present the results for a non technical audience, so having it throw ‘NoSuchElementExceptions’ with a full stack trace is not helpful. I simply want a nice message.

My test:

@Test
public void isMyElementPresent(){
  //  WebElement myElement driver.findElement(By.cssSelector("#myElement"));
    if(driver.findElement(By.cssSelector("#myElement"))!=null){
        System.out.println("My element was found on the page");
    }else{
            System.out.println("My Element was not found on the page");
        }
    }

I still get a NoSuchElementException thrown when I force a fail. Do I need a try/catch as well? Can I incorporate Junit assertions and/or Hamcrest to generate a more meaningful message without the need for a System.out.println?

Answers:

I have encountered similar situations. According to the Javadoc for the findElement and findElements APIs, it appears that the findElement behavior is by design. You should use findElements to check for non-present elements.

Since in your case, there’s a chance that the WebElement is not present, you should use findElements instead.

I’d use this as follows.

List<WebElement> elems = driver.findElements(By.cssSelector("#myElement"));
if (elems.size == 0) {
        System.out.println("My element was not found on the page");
} else
        System.out.println("My element was found on the page");
}

###

you can do something to check if element exists

  public boolean isElementExists(By by) {
    boolean isExists = true;
    try {
        driver.findElement(by);
    } catch (NoSuchElementException e) {
        isExists = false;
    }
    return isExists;
}

###

What about using an xPath inside of a try-catch, passing the elementype, attribute and text as follows?

try {
    driver.FindElement(
        By.XPath(string.Format("//{0}[contains(@{1}, '{2}')]", 
        strElemType, strAttribute, strText)));
    return true;
}
catch (Exception) {
    return false;
}

###

Even running it in a try block, it behaves as if unhandled,
neither of the catch blocks runs when the selenium exception occurs.

try {
    wait.Until(webDriver => webDriver.PageSource.Contains(waitforTitle));
    wait.Until(webDriver => webDriver.FindElement(By.Id(waitforControlName)).Displayed);
}
catch (OpenQA.Selenium.NoSuchElementException nse) {
    nse = nse = null;
    success = false;
}
catch (Exception ex) {
    ex = ex = null;
    success = false;
}