Take the 2-minute tour ×
Software Quality Assurance & Testing Stack Exchange is a question and answer site for software quality control experts, automation engineers, and software testers. It's 100% free, no registration required.

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.

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

4 Answers 4

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

share|improve this answer
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. –  startoftext Feb 8 '14 at 18:55

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)

share|improve this answer

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.

share|improve this answer
1  
The OP is specifically catching the exact exception, while you're catching the generic –  Yamikuronue May 14 at 12:26

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);
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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