I can show you how to get the description partially using reflection.
First of all, we have to fix the Annotation @Name
because you didn't add RetentionPolicy
:
@Target({ElementType.FIELD, ElementType.TYPE, ElementType.CONSTRUCTOR})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Name {
String Description() default "";
}
Now, what I did and tested, we create storage for the names and we're gonna store them when initializing the Page Objects like this:
public class NameStore {
public static HashMap<WebElement, String> map = new HashMap<>();
public static void store(Object pageObject) {
Field[] fields = pageObject.getClass().getDeclaredFields();
for (Field field : fields) {
Name annotation = field.getAnnotation(Name.class);
if (annotation != null) {
try {
map.put((WebElement) field.get(pageObject), annotation.Description());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
public static String getDescription(WebElement element) {
return map.get(element);
}
}
You pass a Page Object as an argument, @Name
annotation is read and stored into the HashMap<WebElement, String>
Initialize name storing in a constructor:
public PageObject(WebDriver driver) {
PageFactory.initElements(driver, this);
NameStore.store(this); //THIS IS CRUCIAL. Also make sure that's always AFTER PageFactory initialization
}
And now, to update your click
method:
public static void click(WebElement element) throws Throwable {
try {
element.click();
} catch(ElementNotInteractableException E1) {
throw new UnableToInteractWithElementException("Unable To Interact With " + NameStore.get(element));
}
}
Hope it helps!
Disclaimer: I didn't test it in the context of multi-threading. I did not test in the context of a constructor.