7

I am using selenium web driver and appium as this is mobile application automation,

I am trying to check that if element is there or not and based on that I have put conditions.

 long starttime = System.currentTimeMillis();
 long endtime = starttime + 60*1000; // 60 seconds * 1000 ms/sec;


while(System.currentTimeMillis() < endtime)
{

    notcount = driver.findElement(By.id(AppConstants.notificationcount));

}

if(notcount.equals(null))

{

    System.out.println("No Element found");
}
else
{

    //SOME ANOTHER STEPS
}

Here issue is when element is not there , instead to redirect to ELSE part , selenium stops execution and throwing exception.

I do not want to use List -findelements here as that is taking long time to find element.

  • 1
    I googled for "selenium wait and if not found do something" first two hits had the solution :) See my answer. – Niels van Reijmersdal Aug 7 '15 at 12:01
13

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.

Text copied from: https://stackoverflow.com/questions/7991522/selenium-webdriver-test-if-element-is-present

Another posbility is to use a Try/Catch construction, see this for more info: https://stackoverflow.com/questions/6521270/webdriver-check-if-an-element-exists

  • Yes I agree and already tried this solution but it takes long time to search element even if element is not there and that's why I have mentioned that I do not want to use LIST or findelements for this. – Helping Hands Aug 10 '15 at 2:59
  • Use the try/catch construction instead then. But how much longer does it really take? Wouldn't except to much, unless your finding hundreds of elements. Also I wonder if your really want to continue the test if an element cannot be found, why are you looking for it then? Let the test fail. – Niels van Reijmersdal Aug 10 '15 at 6:40
  • I am also surprised that I am finding only 1 element and for that only webdriver is taking long time. I want test continue in manner like if element not found then go to ELSE part.. – Helping Hands Aug 10 '15 at 7:12
  • 3
    Having if/then/else constructs in the test is an anti-pattern to me. The test should describe one execution path and avoid any logic. If something blocks this execution path, then fail fast, as suggested. If you want to cover multiple execution paths then create multiple tests where each covers one execution path. – dzieciou Aug 19 '15 at 5:35
6

What you are experiencing is a fast-fail type of behavior when you use .findElement . You don't really need to use .findElements(el) to get a soft-fail behavior. What you could do is something like this instead:

protected void checkElementPresence(final WebDriver driver,final By by,final String errorMsg){
  new WebDriverWaitWithMessage(driver,10).failWith(errorMsg).until(new ExpectedCondition<Boolean>(){
    @Override public Boolean apply(    WebDriver webDriver){
      try {
        return driver.findElement(by).isDisplayed();
      }
 catch (      NoSuchElementException ignored) {
        return false;
      }
catch (      StaleElementReferenceException ignored) {
        return false;
      }
    }
  }
);

But requires this support class:

protected static class WebDriverWaitWithMessage extends WebDriverWait {

        private String message;

        public WebDriverWaitWithMessage(WebDriver driver, long timeOutInSeconds) {
            super(driver, timeOutInSeconds);
        }

        public WebDriverWait failWith(String message) {
            if (message == null || message.length() == 0) {
                throw new IllegalArgumentException("Error message must not be null nor empty");
            }
            this.message = message;
            return this;
        }

        @Override
        public <V> V until(Function<? super WebDriver, V> isTrue) {
            if (message == null) {
                return super.until(isTrue);
            } else {
                try {
                    return super.until(isTrue);
                } catch (TimeoutException e) {
                    throw new TimeoutException(message, e);
                }
            }
        }
    }
2

(note I haven't tried this in java, but this is how to do it in C#)

You should place the findelement in a try/catch block, so that if the element is not found you can catch the exception and do the correct thing.

It would look something like this:

try
{
    driver.FindElement(By.CssSelector("selector"));
} 
catch(NoSuchElementException)
{
    Console.WriteLine("Element does not exist!");
} 

Edit:
I will note that it looks like you are trying to implement your own webdriver wait behavior, so maybe look into the first answer here: https://stackoverflow.com/questions/11736027/webdriver-wait-for-element which explains how to wait for elements with explicit waits in Java.

0

Use Exception handling block for that line of codes. try { } catch { } finally { } If the element is not found then it execute the codes in the finally block and continue to other lines of code

  • 1
    Please expand on your answer to explain how it improves on the existing answers - particularly the accepted answer. – Kate Paulk Dec 13 '17 at 12:18
0
public void sellProduct(){                          

            try {
                for(int i=0; i< 5 ;i++){
                    try {
                        if(!driver.findElements(By.xpath("/html/body/div[@class='container']/table[@class='table table-striped'][2]/tbody[@id='bought']/tr[@id="+i+"]/th[4]/button")).isEmpty())            {
                            try {
                                driver.findElement(By.xpath("/html/body/div[@class='container']/table[@class='table table-striped'][2]/tbody[@id='bought']/tr[@id="+i+"]/th[4]/button")).click();
                            } catch (NoSuchElementException e) {
                                e.printStackTrace();
                            }
                        }

                        else{
                            try {
                                System.out.println("no products to sell ");
                            } catch (NoSuchElementException e) {
                                e.printStackTrace();
                            }
                        }
                    } catch (NoSuchElementException e) {
                        e.printStackTrace();
                    }

                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

I wrote this code but keep on getting the issue target widow is already closed, I want the loop to exit when there is no web element found.

  • Does the accepted answer to this question help you? If not, please post this as its own question and explain why the accepted answer here is not helping. Please do not post "I'm having the same question" as an answer - your post is likely to be deleted. – Kate Paulk Jan 24 '18 at 16:53
0

I use C# but this is the method I use:

/// <summary>
    /// Looks to see if the passed in element is on the webpage or not. Returns true or false.
    /// </summary>
    /// <param name="by"></param>
    /// <param name="element"></param>
    /// <param name="driver"></param>
    /// <returns></returns>
    public static bool tryToFindElement(By by, out IWebElement element, IWebDriver driver)
    {
        try
        {
            element = driver.FindElement(by);
        }
        catch (NoSuchElementException)
        {
            element = null;
            return false;
        }
        return true;
    }

    /// <summary>
    /// Checks to see if the web element is displayed and enabled.
    /// </summary>
    /// <param name="element"></param>
    /// <returns></returns>
    public static bool isElementVisible(IWebElement element)
    {
        return element.Displayed && element.Enabled;
    }

I call it like this:

if (tryToFindElement(By.CssSelector("<CSS Selector>"), out element, driver))
                {
                    bool visible = isElementVisible(element);
                    if (visible == true)
                    {
                     //Do something
                    }
                }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.