24

In Selenium 2 I want to ensure that an element on the page that the driver has loaded does not exist. I'm including my naive implementation here.

    WebElement deleteLink = null;
    try {
        deleteLink = driver.findElement(By.className("commentEdit"));
    } catch (NoSuchElementException e) {

    }
    assertTrue(deleteLink != null);

Is there a more elegant way that basically verifies to assert that NoSuchElementException was thrown?

Han
  • 5,374
  • 5
  • 31
  • 31

9 Answers9

42

If you are testing using junit and that is the only thing you are testing you could make the test expect an exception using

@Test (expected=NoSuchElementException.class)
public void someTest() {
    driver.findElement(By.className("commentEdit"));
}

Or you could use the findElements method that returns an list of elements or an empty list if none are found (does not throw NoSuchElementException):

...
List<WebElement> deleteLinks = driver.findElements(By.className("commentEdit"));
assertTrue(deleteLinks.isEmpty());
...

or

....
assertTrue(driver.findElements(By.className("commentEdit")).isEmpty());
....
Community
  • 1
  • 1
mark-cs
  • 4,677
  • 24
  • 32
  • Good solution. However, it has problems with ImplicitWait, as calls to findElement(s) implicitly wait for element to show up. – tishma Oct 17 '12 at 16:24
  • 1
    You can get around that by setting the wait time to 1 sec or whatever timeout you want. I set that as a default so that in my solution, I created an .net extension method to add a .exists() method. driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(1)); – Brantley Blanchard Aug 02 '13 at 20:16
13

You can use this:

Boolean exist = driver.findElements(By.whatever(whatever)).size() == 0;

If it doesn't exist will return true.

Will
  • 4,299
  • 5
  • 32
  • 50
Shehab Mostafa
  • 131
  • 1
  • 2
4

I split out page classes so I don't have to define elements more than once. My nunit and mbunit test classes call those page classes. I haven't tried this out yet but this is how I'm thinking about doing it so I can use .exists() like I did with WatiN.

Extension Class:

public static class ExtensionMethods
{
   public static IWebElement ElementById(this IWebDriver driver, string id)
   {
      IWebElement e = null;
      try 
      {
         e = driver.FindElement(By.Id(id));
      }
      catch (NoSuchElement){}
      return e;
   }
   public static bool Exists(this IWebElement e) 
   {
      if (e == null)
         return false;  
      return true;
   }
}

Page Class:

public IWebElement SaveButton { get { try { return driver.ElementById("ctl00_m_m_body_body_cp2_btnSave")); } }

Test Class:

MyPageClass myPageClass = new MyPageClass(driver);
if (myPageClass.SaveButton.Exists())
{
   Console.WriteLine("element doesn't exist");
}
Brantley Blanchard
  • 1,208
  • 3
  • 14
  • 23
3

You can retrieve a list of elements by using driver.findElements("Your elements") and then search for the element. if the list doesn't contains the element you got yourself your desired behavior :)

Guy Engel
  • 2,436
  • 1
  • 17
  • 13
1

If you're using the Javascript API, you can use WebElement.findElements(). This method will return a Promise with an array of found elements. You can check the length of the array to ensure no items were found.

driver.findElements(By.css('.selector')).then(function(elements) {
  expect(elements.length).to.equal(0)
})

I'm using Chai assertion library inside the Promise's callback to expect a certain value.

Reference: https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html

png
  • 1,130
  • 14
  • 18
1

Best solution

  protected boolean isElementPresent(WebElement el){
        try{
            el.isDisplayed();
            return true;
        }
        catch(NoSuchElementException e){
            return false;
        }
    }
0
public boolean exist(WebElement el){
   try {
      el.isDisplayed();
      return true;
   }catch (NoSuchElementException e){
      return false;
   }
}

if(exist(By.id("Locator details"))==false)

or

WebElement el= driver.findElementby(By.locator("locator details")
public boolean exists(WebElement el)
 try{
  if (el!=null){
   if (el.isDisplayed()){
     return true;

    }
   }
 }catch (NoSuchElementException e){
   return false;
 }
}
Sonali Das
  • 943
  • 1
  • 7
  • 24
0

Using webdriver find_element_xxx() will raise exception in my code and take us the waiting time of implicit/explicit webdriver wait.

I will go for DOM element check

webdriver.execute_script("return document.querySelector('your css class')")

p.s.

Also found similar discussion on our QA-main sister site here


For full check for visibility+existence

    # check NOT visible the :aftermeet and :viewintro
    #                   !                .      .                       !       !offsetWidth to check visible in pure js ref. https://stackoverflow.com/a/20281623/248616
    css='yourcss'; e=wd.execute_script(f"return document.querySelector('{css}').offsetWidth > 0") ; assert not e

    # check NOT exists :viewintro
    css='yourcss'; e=wd.execute_script(f"return document.querySelector('{css}')") ; assert not e
Nam G VU
  • 33,193
  • 69
  • 233
  • 372
-3

Use assertFalse :)

assertFalse(isElementPresent(By.className("commentEdit")));