3

I wonder if someone could help me with an issue I'm having trying to work out and If statement in Java for Webdriver.

When logging into the app I am testing it is possible to be taken to a security questions page before the main page (if a new user etc). What I would like the code in my test to do is if presented with the security questions page fill it in and move on, if not check you are on the main page.

I was able to do this in Selenium RC using

 if (selenium.isTextPresent("User Account Credentials Update")) {   
            selenium.type("//input[@id='securityQuestion']", "A");
            selenium.type("//input[@id='securityAnswer']", "A");
            selenium.type("//input[@id='emailAddress']", "test@test.com");
            selenium.click("update");
            selenium.waitForPageToLoad("30000");
            }


 assertTrue(selenium.isTextPresent("MainPage"));

Playing around with Webdriver I am using:

    if(driver.findElement(By.id("securityQuestion")) != 0) {
                driver.findElement(By.id("securityQuestion")).sendKeys("A");
                driver.findElement(By.id("securityAnswer")).sendKeys("A");
                driver.findElement(By.id("emailAddress")).sendKeys("test@test.com");
                driver.findElement(By.id("update")).click();

Assert.assertTrue("Main Page is not Showing",
            driver.getPageSource().contains("MainPage"));

The Problem with this is is that it always chucks an exception if the Security screen is not displayed. How do I need to set the code so that it ignores the security page stuff if that page is not presented? Thank you for any help :-)

Mattk
  • 93
  • 1
  • 5

3 Answers3

2

You can use driver.findElements as a way to check that a specific element is present without having exceptions thrown. This works because it will return a list of size 0 of WebElements if no element is found. At the moment, if Selenium tries to find an element using findElement and the element doesn't exist, it will throw a NoSuchElementException This means you can replace:

if (driver.findElement(By.id("securityQuestion")) != 0)

with this:

if (driver.findElements(By.id("securityQuestion")).size() != 0)
bagelmakers
  • 384
  • 2
  • 15
  • 1
    I like the `.size()` approach to this. `findElements()` won't throw an exception if it doesnt find it like `findElement()` *(singular)* would. – ddavison Mar 18 '15 at 18:36
2

There is actually nothing wrong in an exception being thrown as long as you catch/handle it.

In other words, I'd follow the EAFP approach here:

try {
    driver.findElement(By.id("securityQuestion"));
    // ...
} catch (NoSuchElementException e) {
    // handle exception, may be at least log in your case
}
Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • The added benefit here, versus the `.findElements()` suggestion, is that in the positive case this is going to be faster - it does not wait the full implicit wait. – SiKing Mar 18 '15 at 20:46
  • @SiKing Both `.findElements()` and `.findElement()` will honor any implicit wait set on the driver before declaring that there is no element matching the query. – Louis Mar 18 '15 at 22:14
  • @Louis Right! That is why I said "in the **positive** case". As soon as the first one is found, `.findElement()` will stop, whereas `.findElements()` will continue to wait for the full duration. – SiKing Mar 18 '15 at 22:28
  • 1
    @SiKing Right. Let me say what I should have said in the first place: `.findElements` will return as soon as there is a match, just like `.findElement` does. – Louis Mar 18 '15 at 22:40
0

I usually just wrap it into a method:

public boolean elementExists(By selector)
{
    try
    {
        driver.findElement(selector)
        return true;
    }
    catch(NoSuchElementException e)
    {
        return false;
    }
}
aholt
  • 2,829
  • 2
  • 10
  • 13