3

My question is like Problem catching Selenium Webdriver NoSuchElementException but there is no answer to resolve an issue.

Class SmallLoginLocators:

public class SmallLoginLocators {
    public final String PASSWORD1 = "__nothing";
    public final String PASSWORD2 = "password";
    @FindBy (name = PASSWORD1)
    public WebElement passwordField1;
    @FindBy (name = PASSWORD2)
    public WebElement passwordField2;
}

There is password text field with different locators on two pages. Test can start from any of these pages. So I try to access that webelement:

public WebElement getPasswordField() {
    SmallLoginLocators slogin = PageFactory.initElements(wd, SmallLoginLocators.class);
    WebElement password;
    try {
        password = slogin.passwordField1;
    } catch (NoSuchElementException e) {
        password = slogin.passwordField2;
    }
    return password;
}

getPasswordField() returnes NoSuchElementException on line

password = slogin.passwordField1;

BUT!!! that is not handled by catch (NoSuchElementException e).

Q1: Why?

Q2: How to resolve?

Note: NoSuchElementException I get is from org.openqa.selenium.NoSuchElementException and imports are valid. I suspectthat the issue is in PageFactory.initElements source, but my junior knowledge of java has not given me any chance to understand.

2
  • Why don't you post the code of PageFactory.initElements? Commented Nov 8, 2013 at 2:44
  • 1
    If you want to actually know what's being thrown, add a catch (Throwable t) { t.printStackTrace(); }
    – user246
    Commented May 13, 2015 at 21:11

4 Answers 4

2

My answer is not directly to your question. It is advice. You should not use try catch for logic realization. Program languages (Java, c#, python etc) have if ... else statements. And you can use them for your problem.

not debugged code, simply for example

if(slogin.passwordField1.Existed)
{ 
  return slogin.passwordField1;
} 
else 
{
  return slogin.passwordField2;
}

You can find how realize existed property in Internet (it is easy) and you will levelup you developer skills

1
  • 1
    There are times when the code your calling will throw an exception for a given circumstance that you need to be able to handle gracefully. Its not always possible to go in and re-factor or change the code to not throw an exception in that case. It could be a library or it could be a huge amount of legacy code you inherited that you have no time to refactor. This is why I do not like the concept of exceptions. They are meant to be used for things that are exceptional but often what you consider exceptional I expect may happen. Commented Feb 8, 2014 at 18:55
1

if you have different elements locators and you want to acces to them in single way, you can use @FindAll anotations:

@FindAll(value = { 
        @FindBy(css = " ... "), 
        @FindBy(css = " ... ") 
        })
List<WebElement> elementsList;

(first element from the list will be used)

1

This line:

password = slogin.passwordField1;

Is a simple assignment. It's not the line that throws the exception. PageFactory will attempt to lazy-initialize the field when it is used, not just referenced; I'm not 100% clear on whether assignment is considered a use, but it's very likely that it's the return statement that's throwing instead. For this use case, I'm thinking letting PageFactory initialize your field is doing more harm than good. I'd say, use a traditional find here.

It can be written entirely without exceptions that way, too:

public WebElement getPasswordField() {
    SmallLoginLocators slogin = new SmallLoginLocators();
    List<WebElement> candidates = wd.find(By.Name(slogin.PASSWORD1));
    if (candidates.size <= 0) candidates = wd.find(By.Name(slogin.PASSWORD2));
    return candidates.get(0);
}
-1

When we look at the try and catch we can see that we normally use catch (Exception e); but in the case of Webdriver we will have to use catch (Throwable e).

So try to use this:

public WebElement getPasswordField() {
    SmallLoginLocators slogin = PageFactory.initElements(wd, SmallLoginLocators.class);
    WebElement password;
    try {
        password = slogin.passwordField1;
    } catch (**Throwable** e) {
        password = slogin.passwordField2;
    }
    return password;
}

This resolved my issue.

1
  • 2
    The OP is specifically catching the exact exception, while you're catching the generic Commented May 14, 2015 at 12:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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