36

Im trying the code below but it seems it does not work... Can someone show me the best way to do this?

public void verifyThatCommentDeleted(final String text) throws Exception {
    new WebDriverWait(driver, 5).until(new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver input) {
                try {
                    input.findElement(By.xpath(String.format(
                            Locators.CHECK_TEXT_IN_FIRST_STATUS_BOX, text)));
                    return false;
                } catch (NoSuchElementException e) {
                    return true;
                }
            }
        });
    }
Ripon Al Wasim
  • 36,924
  • 42
  • 155
  • 176
Roman Iuvshin
  • 1,872
  • 10
  • 24
  • 40
  • 1
    As an alternative, You can use "WebdriverBackedSelenium" and use selenium.isElementPresent("Locator"); – Manpreet Singh Sep 04 '12 at 21:36
  • 2
    First of all input.findElements(By.xpath("//xpath")).size() > 0 is better way to verify element's existence than wrapping findBy in try..catch. Second thing is: what do you mean by "it does not work"? Does it hang? Throws an exception? Returns incorrect results? – JacekM Sep 05 '12 at 14:58

10 Answers10

52

Instead of doing findElement, do findElements and check the length of the returned elements is 0. This is how I'm doing using WebdriverJS and I expect the same will work in Java

Xolv.io
  • 2,483
  • 1
  • 15
  • 17
  • 15
    Actually, this is also what the official docs recommend: _"findElement should not be used to look for non-present elements, use findElements(By) and assert zero length response instead."_ [Javadoc for WebElement#findElement](http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/WebElement.html#findElement%28org.openqa.selenium.By%29) – sleske Feb 13 '14 at 14:10
  • 4
    Yes it's the official way to do but but unfortunately the [docs](https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/WebElement.html#findElements-org.openqa.selenium.By-) also say: *"This method is affected by the 'implicit wait' times in force at the time of execution."* So you then might end up doing something like ```driver.manage.timeouts.implicitlyWait(10, TimeUnit.MILLISECONDS)``` (maybe with a ```finally``` to reset the timeout again). – RedYeti Oct 29 '20 at 16:11
39

i usually couple of methods (in pair) for verification whether element is present or not:

public boolean isElementPresent(By locatorKey) {
    try {
        driver.findElement(locatorKey);
        return true;
    } catch (org.openqa.selenium.NoSuchElementException e) {
        return false;
    }
}

public boolean isElementVisible(String cssLocator){
    return driver.findElement(By.cssSelector(cssLocator)).isDisplayed();
}

Note that sometimes selenium can find elements in DOM but they can be invisible, consequently selenium will not be able to interact with them. So in this case method checking for visibility helps.

If you want to wait for the element until it appears the best solution i found is to use fluent wait:

public WebElement fluentWait(final By locator){
    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
            .withTimeout(30, TimeUnit.SECONDS)
            .pollingEvery(5, TimeUnit.SECONDS)
            .ignoring(NoSuchElementException.class);

    WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
        public WebElement apply(WebDriver driver) {
            return driver.findElement(locator);
        }
    });

    return foo;
};

Hope this helps)

nhahtdh
  • 55,989
  • 15
  • 126
  • 162
eugene.polschikov
  • 7,254
  • 2
  • 31
  • 44
  • 1
    Your code probably suffers from a race condition: The element may be removed between the call to `findElement` and `isDisplayed` - meaning you will get random `StaleElementReferenceException`s. – sleske Feb 13 '14 at 14:14
  • @sleske, every case should be considered particularly, i.e we need to decide for element :1) whether it present on the page /not present 2) vsibile/not visible. So combo fluentWait(#selector).isDisplayed() will handle it because: 1) if element not present >>exception noSuchElement 2) if elemet present >> then we get boolen for its visibility. – eugene.polschikov Feb 14 '14 at 12:29
  • A potential suggestion for isElementVisible: public boolean isElementVisible(By locatorKey) { return driver.findElement(locatorKey).isDisplayed(); } Thanks for your comments. – JohnP2 Jun 16 '17 at 16:13
6

Use findElements instead of findElement.

findElements will return an empty list if no matching elements are found instead of an exception. Also, we can make sure that the element is present or not.

Ex: List elements = driver.findElements(By.yourlocatorstrategy);

if(elements.size()>0){
    do this..
 } else {
    do that..
 }
  • 1
    Welcome to SO! Although this is a correct (and well formatted) answer it is already listed within the answers section and it's almost 5 years old, so it doesn't really bring anything new to the table. Take a look at unanswered questions to start helping out! – JNYRanger Jul 06 '17 at 20:29
4

Unable to comment to The Meteor Test Manual, since I have no rep, but I wanted to provide an example that took me quite awhile to figure out:

Assert.assertEquals(0, wd.findElements(By.locator("locator")).size());

This assertion verifies that there are no matching elements in the DOM and returns the value of Zero, so the assertion passes when the element is not present. Also it would fail if it was present.

2
public boolean isDisplayed(WebElement element) {
        try {
            return element.isDisplayed();
        } catch (NoSuchElementException e) {
            return false;
        }
    }

If you wan t to check that element is displayed on the page your check should be:

if(isDisplayed(yourElement){
...
}
else{
...
}
Norayr Sargsyan
  • 1,737
  • 1
  • 12
  • 26
0
int i=1;

while (true) {
  WebElementdisplay=driver.findElement(By.id("__bar"+i+"-btnGo"));
  System.out.println(display);

  if (display.isDisplayed()==true)
  { 
    System.out.println("inside if statement"+i);
    driver.findElement(By.id("__bar"+i+"-btnGo")).click();
    break;
  }
  else
  {
    System.out.println("inside else statement"+ i);
    i=i+1;
  }
}
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
  • how to check the id by incrementing the i value it throw an exception – Avijit Samal Jul 19 '16 at 12:39
  • It does throw an exception. I was going to mention this. The proper way to do this is to get the length of "findElements" and see if it equals "0" or not. If it's 0, then the element is NOT there. If it's more than "1", the element is still present. The only thing that would kill this logic is if there are several elements on the page with the same ID or NAME. In that case you could talk to the development team OR just get it by another means such as XPath. – IamBatman Oct 31 '16 at 18:43
  • Apparently my edit got rejected, so here was my comment in the edit. "The "WebElementdisplay" would result in an error, needs a space "WebElement display". The "i = i + 1", simply should be done as "i++". The (display.isDisplayed == true) should simply just be (display.isDisplayed)." – IamBatman Nov 01 '16 at 16:20
0
WebElement element = driver.findElement(locator);
Assert.assertNull(element);

The above assertion will pass if element is not present.

skumar
  • 180
  • 3
  • 17
0

In Python for assertion I use:

assert len(driver.find_elements_by_css_selector("your_css_selector")) == 0
vitaliis
  • 4,082
  • 5
  • 18
  • 40
0

My answer is much more simpler and it works for me

while(true) {
if (driver.getPageSource().contains("Enter the text of the element you wanted to check")==false) 
{//Put your code here 
    break;
}   
else if (isElementPresent(element you are trying to find)==true)
{
                //put your code here 
                break;
}

}

Sharutkarsh
  • 17
  • 2
  • 8
-3
    WebElement element = driver.findElement(locator);

    Assert.assertFalse(element.isDisplayed());

The assertion will pass if the element is not present, otherwise it will fail.