Access the By class created using @FindBy annotation in Selenium

Recently I needed to increase the information the NoSuchElementException contained when using Selenium’s @FindBy annotation. During this I stumbled across a way to get access to the By class created from the @FindBy.

For example say we have the following PageObject


public class testPageObject {
   @FindBy(css = "h1[name='test']")
   WebElement testElement1;

   @FindBy(xpath = "//*[class='test']")
   WebElement testElement2;

   @FindBy(id = "test")
   WebElement testElement3;


   public testPageObject() {
       //Cache the WebElements using a 5 second wait
       PageFactory.initElements(new AjaxElementLocatorFactory(driver, 5), this);
   }

   public void printBy() {
        By testElement1 = getBy("testElement1");
        By testElement2 = getBy("testElement2");
        By testElement3 = getBy("testElement3");

        System.out.println(testElement1);
        System.out.println(testElement2);
        System.out.println(testElement3);
   }

   private By getBy(String fieldName) {
       try {
            return new Annotations(this.getClass().getDeclaredField(fieldName)).buildBy();
       } catch (NoSuchFieldException e) { return null; }
   }
}

The solution is to use Selenium’s built in Annotations class which takes a field and call buildBy() to return the By class for that field.

The output of the printBy() function:

By.selector: h1[name=’test’]
By.xpath: //*[class=’test’]
By.id: test