Test if element is present using Selenium WebDriver?

JavaSeleniumSelenium Webdriver

Java Problem Overview


Is there a way how to test if an element is present? Any findElement method would end in an exception, but that is not what I want, because it can be that an element is not present and that is okay, that is not a fail of the test, so an exception can not be the solution.

I've found this post: https://stackoverflow.com/questions/6992993/selenium-c-sharp-webdriver-wait-until-element-is-present But this is for C# and I am not very good at it. Can anyone translate the code into Java? I am sorry guys, I tried it out in Eclipse but I don't get it right into Java code.

This is the code:

public static class WebDriverExtensions{
    public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds){

        if (timeoutInSeconds > 0){
            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
            return wait.Until(drv => drv.FindElement(by));
        }

        return driver.FindElement(by);
    }
}

Java Solutions


Solution 1 - Java

Use findElements instead of findElement.

findElements will return an empty list if no matching elements are found instead of an exception.

To check that an element is present, you could try this

Boolean isPresent = driver.findElements(By.yourLocator).size() > 0

This will return true if at least one element is found and false if it does not exist.

The official documentation recommends this method: > findElement should not be used to look for non-present elements, use findElements(By) and assert zero length response instead.

Solution 2 - Java

What about a private method that simply looks for the element and determines if it is present like this:

private boolean existsElement(String id) {
	try {
		driver.findElement(By.id(id));
	} catch (NoSuchElementException e) {
		return false;
	}
	return true;
}

This would be quite easy and does the job.

Edit: you could even go further and take a By elementLocator as parameter, eliminating problems if you want to find the element by something other than id.

Solution 3 - Java

I found that this works for Java:

WebDriverWait waiter = new WebDriverWait(driver, 5000);
waiter.until( ExpectedConditions.presenceOfElementLocated(by) );
driver.FindElement(by);

Solution 4 - Java

public static WebElement FindElement(WebDriver driver, By by, int timeoutInSeconds)
{
	WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds);
	wait.until( ExpectedConditions.presenceOfElementLocated(by) ); //throws a timeout exception if element not present after waiting <timeoutInSeconds> seconds
	return driver.findElement(by);
}

Solution 5 - Java

I had the same issue. For me, depending on a user's permission level, some links, buttons and other elements will not show on the page. Part of my suite was testing that the elements that SHOULD be missing, are missing. I spent hours trying to figure this out. I finally found the perfect solution.

What this does, is tells the browser to look for any and all elements based specified. If it results in 0, that means no elements based on the specification was found. Then i have the code execute an if statement to let me know it was not found.

This is in C#, so translations would need to be done to Java. But shouldnt be too hard.

public void verifyPermission(string link)
{
    IList<IWebElement> adminPermissions = driver.FindElements(By.CssSelector(link));
    if (adminPermissions.Count == 0)
    {
        Console.WriteLine("User's permission properly hidden");
    }
}

There's also another path you can take depending on what you need for your test.

The following snippet is checking to see if a very specific element exists on the page. Depending on the element's existence I have the test execute an if else.

If the element exists and is displayed on the page, I have console.write let me know and move on. If the element in question exists, I cannot execute the test I needed, which is the main reasoning behind needing to set this up.

If the element Does Not exists, and is not displayed on the page. I have the else in the if else execute the test.

IList<IWebElement> deviceNotFound = driver.FindElements(By.CssSelector("CSS LINK GOES HERE"));
//if the element specified above results in more than 0 elements and is displayed on page execute the following, otherwise execute whats in the else statement
if (deviceNotFound.Count > 0 && deviceNotFound[0].Displayed){
    //script to execute if element is found
} else {
    //Test script goes here.
}

I know I'm a little late on the response to the OP. Hopefully this helps someone!

Solution 6 - Java

Try this: Call this method and pass 3 arguments:

  1. WebDriver variable. // assuming driver_variable as driver.
  2. The element which you are going to check. Should provide from By method. // ex: By.id("id")
  3. Time limit in seconds.

Example: waitForElementPresent(driver, By.id("id"), 10 );

public static WebElement waitForElementPresent(WebDriver driver, final By by, int timeOutInSeconds) {

		WebElement element; 

		try{
			driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait() 
			
			WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds); 
			element = wait.until(ExpectedConditions.presenceOfElementLocated(by));
			
			driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); //reset implicitlyWait
			return element; //return the element
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return null; 
	}

Solution 7 - Java

This works for me:

 if(!driver.findElements(By.xpath("//*[@id='submit']")).isEmpty()){
    //THEN CLICK ON THE SUBMIT BUTTON
}else{
    //DO SOMETHING ELSE AS SUBMIT BUTTON IS NOT THERE
}

Solution 8 - Java

You can make the code run faster by shorting the selenium timeout before your try catch statement.

I use the following code to check if an element is present.

protected boolean isElementPresent(By selector) {
    selenium.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
    logger.debug("Is element present"+selector);
    boolean returnVal = true;
    try{
        selenium.findElement(selector);
    } catch (NoSuchElementException e){
        returnVal = false;
    } finally {
        selenium.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
    }
    return returnVal;
}

Solution 9 - Java

Write the following function/methos using Java:

protected boolean isElementPresent(By by){
		try{
			driver.findElement(by);
			return true;
		}
		catch(NoSuchElementException e){
			return false;
		}
	}

Call the method with appropriate parameter during assertion.

Solution 10 - Java

if you are using rspec-Webdriver in ruby, you can use this script assuming that an element should really not be present and it is a passed test.

First, write this method first from your class RB file

class Test
 def element_present?
    begin
        browser.find_element(:name, "this_element_id".displayed?
        rescue Selenium::WebDriver::Error::NoSuchElementError
            puts "this element should not be present"
        end
 end

Then, on your spec file, call that method.

  before(:all) do    
    @Test= Test.new(@browser)
  end

 @Test.element_present?.should == nil

If your the element is NOT present, your spec will pass, but if the element is present , it will throw an error, test failed.

Solution 11 - Java

Personally, I always go for a mixture of the above answers and create a re-usable static Utility method that uses the size() > 0 suggestion:

public Class Utility {
   ...
   public static boolean isElementExist(WebDriver driver, By by) {
      return driver.findElements(by).size() > 0;
   ...
}

This is neat, re-usable, maintainable ... all that good stuff ;-)

Solution 12 - Java

public boolean isElementDisplayed() {
        return !driver.findElements(By.xpath("...")).isEmpty();
    }

Solution 13 - Java

Simplest way I found in Java is:

List<WebElement> linkSearch=  driver.findElements(By.id("linkTag"));
int checkLink=linkSearch.size();
if(checkLink!=0){  //do something you want}
				    	

Solution 14 - Java

To find a particular Element is present or not, we have to use findElements() method instead of findElement()..

int i=driver.findElements(By.xpath(".......")).size();
if(i=0)
System.out.println("Element is not present");
else
System.out.println("Element is present");

this is worked for me.. suggest me if i am wrong..

Solution 15 - Java

This should do it:

try {
    driver.findElement(By.id(id));
} catch (NoSuchElementException e) {
    //do what you need here if you were expecting
    //the element wouldn't exist
}

Solution 16 - Java

You can try implicit wait:

WebDriver driver = new FirefoxDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
driver.Url = "http://somedomain/url_that_delays_loading";
IWebElement myDynamicElement = driver.FindElement(By.Id("someDynamicElement"));

Or You can try explicit wait one:

IWebDriver driver = new FirefoxDriver();
driver.Url = "http://somedomain/url_that_delays_loading";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
    {
        return d.FindElement(By.Id("someDynamicElement"));
    });

Explicit will check if element is present before some action. Implicit wait could be call in every place in the code. For example after some AJAX actions.

More you can find at SeleniumHQ page

Solution 17 - Java

Giving my snippet of code. So, the below method checks if a random web element 'Create New Application' button exists on a page or not. Note that I have used the wait period as 0 seconds.

public boolean isCreateNewApplicationButtonVisible(){
    WebDriverWait zeroWait = new WebDriverWait(driver, 0);
    ExpectedCondition<WebElement> c = ExpectedConditions.presenceOfElementLocated(By.xpath("//input[@value='Create New Application']"));
    try {
        zeroWait.until(c);
    	logger.debug("Create New Application button is visible");
        return true;
    } catch (TimeoutException e) {
    	logger.debug("Create New Application button is not visible");
        return false;
    }
}

Solution 18 - Java

I would use something like (with Scala [the code in old "good" Java 8 may be similar to this]):

object SeleniumFacade {

  def getElement(bySelector: By, maybeParent: Option[WebElement] = None, withIndex: Int = 0)(implicit driver: RemoteWebDriver): Option[WebElement] = {
    val elements = maybeParent match {
      case Some(parent) => parent.findElements(bySelector).asScala
      case None => driver.findElements(bySelector).asScala
    }
    if (elements.nonEmpty) {
      Try { Some(elements(withIndex)) } getOrElse None
    } else None
  }
  ...
}

so then,

val maybeHeaderLink = SeleniumFacade getElement(By.xpath(".//a"), Some(someParentElement))

Solution 19 - Java

In 2022 this can now be done without an annoying delay, or affecting your current implicit wait value.

First bump your selenium driver to latest (currently 4.1.2) then you can use getImplicitWaitTimeout then set timeout to 0 to avoid a wait then restore your previous implicit wait value whatever it was:



Duration implicitWait = driver.manage().timeouts().getImplicitWaitTimeout();
driver.manage().timeouts().implicitlyWait(Duration.ofMillis(0));
final List<WebElement> signOut = driver.findElements(By.linkText("Sign Out"));
driver.manage().timeouts().implicitlyWait(implicitWait); // Restore implicit wait to previous value

if (!signOut.isEmpty()) {
    ....
}


Solution 20 - Java

Can you try below code using isDispplayed() method to verify element is present or not:

WebElement element=driver.findElements(By.xpath(""));
element.isDispplayed();

Solution 21 - Java

There could be multiple reasons due to which you might observe exceptions while locating a WebElement using Selenium driver.

I would suggest you to apply the below suggestions for different scenarios:

Scenario 1: You just want to find out if a certain WebElement is present on Screen or NOT. For example Save button icon will only appear until the form is fully filled and you may want to check if Save button is present or not in your test.

Use the below code -

public Boolean isElementLoaded(By locator){
        return !getWebElements(this.driver.findElements(locator), locator).isEmpty();
    }

Scenario 2: You want to wait before a WebElement becomes visible on UI

public List<WebElement> waitForElementsToAppear(By locator) {
    return wait.until(visibilityOfAllElementsLocatedBy(by));
}

Scenario 3: Your test is flaky because the WebElement becomes stale sometimes and gets detached from DOM.

 protected final List<Class<? extends WebDriverException>> exceptionList = List.of(NoSuchWindowException.class, NoSuchFrameException.class, NoAlertPresentException.class, InvalidSelectorException.class, ElementNotVisibleException.class, ElementNotSelectableException.class, TimeoutException.class, NoSuchSessionException.class, StaleElementReferenceException.class);

    public WebElement reactivateWebElement(By by, WebElement element){
        try {
            wait.ignoreAll(exceptionList)
                    .until(refreshed(visibilityOf(element)));
            logger.info(("Element is available.").concat(BLANK).concat(element.toString()));

        } catch (WebDriverException exception) {
            logger.warn(exception.getMessage());
        } return this.driver.findElement(by);
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiontesterView Question on Stackoverflow
Solution 1 - Javael rosoView Answer on Stackoverflow
Solution 2 - JavaDennisView Answer on Stackoverflow
Solution 3 - JavaTango BenView Answer on Stackoverflow
Solution 4 - JavaRedDeckWinsView Answer on Stackoverflow
Solution 5 - JavaTashaView Answer on Stackoverflow
Solution 6 - JavaPrabu AnanthakrishnanView Answer on Stackoverflow
Solution 7 - JavaAmstel BytesView Answer on Stackoverflow
Solution 8 - JavaEsotericNonsenseView Answer on Stackoverflow
Solution 9 - JavaRipon Al WasimView Answer on Stackoverflow
Solution 10 - JavagrayshellView Answer on Stackoverflow
Solution 11 - JavaCharlie SeligmanView Answer on Stackoverflow
Solution 12 - JavahelloWorldView Answer on Stackoverflow
Solution 13 - Javaback2backView Answer on Stackoverflow
Solution 14 - JavaSubbarao GaddamView Answer on Stackoverflow
Solution 15 - JavaScott HelmeView Answer on Stackoverflow
Solution 16 - JavastreserView Answer on Stackoverflow
Solution 17 - JavaRambo7View Answer on Stackoverflow
Solution 18 - JavasesView Answer on Stackoverflow
Solution 19 - JavaslonikView Answer on Stackoverflow
Solution 20 - Javaarpita biswasView Answer on Stackoverflow
Solution 21 - JavaUchiha SuryajitView Answer on Stackoverflow