How can I check if an element exist with web driver?
Is using a try-catch really the only possible way?
boolean present;
try {
   driver.findElement(By.id("logoutLink"));
   present = true;
} catch (NoSuchElementException e) {
   present = false;
}
How can I check if an element exist with web driver?
Is using a try-catch really the only possible way?
boolean present;
try {
   driver.findElement(By.id("logoutLink"));
   present = true;
} catch (NoSuchElementException e) {
   present = false;
}
 
    
     
    
    You could alternatively do:
driver.findElements(By.id("...")).size() != 0
Which saves the nasty try/catch
P.S.:
Or more precisely by @JanHrcek here
!driver.findElements(By.id("...")).isEmpty()
 
    
     
    
    I agree with Mike's answer, but there's an implicit 3 second wait if no elements are found which can be switched on/off which is useful if you're performing this action a lot:
driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS);
boolean exists = driver.findElements( By.id("...") ).size() != 0
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
Putting that into a utility method should improve performance if you're running a lot of tests.
 
    
     
    
    As the comment stated, this is in C# not Java but the idea is the same. I've researched this issue extensively and ultimately the issue is, FindElement always returns an exception when the element doesn't exist. There isn't an overloaded option that allows you to get null or anything else. Here is why I prefer this solution over others.
It's actually a very simple and elegant once the method is created. By using FindElementSafe instead of FindElement, I don't "see" the ugly try/catch block and I can use a simple Exists method. That would look something like this:
IWebElement myLink = driver.FindElementSafe(By.Id("myId"));
if (myLink.Exists)
{
   myLink.Click();
}
Here is how you extend IWebElement & IWebDriver
IWebDriver.FindElementSafe
    /// <summary>
    /// Same as FindElement only returns null when not found instead of an exception.
    /// </summary>
    /// <param name="driver">current browser instance</param>
    /// <param name="by">The search string for finding element</param>
    /// <returns>Returns element or null if not found</returns>
    public static IWebElement FindElementSafe(this IWebDriver driver, By by)
    {
        try
        {
            return driver.FindElement(by);
        }
        catch (NoSuchElementException)
        {
            return null;
        }
    }
IWebElement.Exists
    /// <summary>
    /// Requires finding element by FindElementSafe(By).
    /// Returns T/F depending on if element is defined or null.
    /// </summary>
    /// <param name="element">Current element</param>
    /// <returns>Returns T/F depending on if element is defined or null.</returns>
    public static bool Exists(this IWebElement element)
    {
        if (element == null)
        { return false; }
        return true;
    }
You could use polymorphism to modify the IWebDriver class instance of FindElement but that's a bad idea from a maintenance standpoint.
 
    
    This works for me every time:
    if(!driver.findElements(By.xpath("//*[@id='submit']")).isEmpty()){
        // Then click on the submit button
    }else{
        // Do something else as submit button is not there
    }
 
    
     
    
    I extended the Selenium WebDriver implementation, in my case HtmlUnitDriver to expose a method,
public boolean isElementPresent(By by){}
like this:
Here is my code:
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
public class CustomHtmlUnitDriver extends HtmlUnitDriver {
    public static final long DEFAULT_TIMEOUT_SECONDS = 30;
    private long timeout = DEFAULT_TIMEOUT_SECONDS;
    public long getTimeout() {
        return timeout;
    }
    public void setTimeout(long timeout) {
        this.timeout = timeout;
    }
    public boolean isElementPresent(By by) {
        boolean isPresent = true;
        waitForLoad();
        // Search for elements and check if list is empty
        if (this.findElements(by).isEmpty()) {
            isPresent = false;
        }
        // Rise back implicitly wait time
        this.manage().timeouts().implicitlyWait(timeout, TimeUnit.SECONDS);
        return isPresent;
    }
    public void waitForLoad() {
        ExpectedCondition<Boolean> pageLoadCondition = new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver wd) {
                // This will tel if page is loaded
                return "complete".equals(((JavascriptExecutor) wd).executeScript("return document.readyState"));
            }
        };
        WebDriverWait wait = new WebDriverWait(this, timeout);
        // Wait for page complete
        wait.until(pageLoadCondition);
        // Lower implicitly wait time
        this.manage().timeouts().implicitlyWait(100, TimeUnit.MILLISECONDS);
    }
}
Usage:
CustomHtmlUnitDriver wd = new CustomHtmlUnitDriver();
wd.get("http://example.org");
if (wd.isElementPresent(By.id("Accept"))) {
    wd.findElement(By.id("Accept")).click();
}
else {
    System.out.println("Accept button not found on page");
}
 
    
     
    
    You can do an assertion.
See the example
driver.asserts().assertElementFound("Page was not loaded",
By.xpath("//div[@id='actionsContainer']"),Constants.LOOKUP_TIMEOUT);
You can use this this is native:
public static void waitForElementToAppear(Driver driver, By selector, long timeOutInSeconds, String timeOutMessage) {
    try {
        WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
        wait.until(ExpectedConditions.visibilityOfElementLocated(selector));
    } 
    catch (TimeoutException e) {
        throw new IllegalStateException(timeOutMessage);
    }
}
 
    
     
    
    Write the following method using Java:
protected boolean isElementPresent(By by){
    try{
        driver.findElement(by);
        return true;
    }
    catch(NoSuchElementException e){
        return false;
    }
}
Call the above method during an assertion.
 
    
     
    
    String link = driver.findElement(By.linkText(linkText)).getAttribute("href")
This will give you the link the element is pointing to.
 
    
     
    
    With version 2.21.0 of selenium-java.jar you can do this;
driver.findElement(By.id("...")).isDisplayed()
