我正在使用硒pagefactory,并引入了一个注释@Name(Description =“ Username”),我将其用于所有WebElement。 稍后,我需要在自定义方法中找到Description的值,以进行报告,例如:
public static void click(WebElement element) throws Throwable {
try {
element.click();
} catch(ElementNotInteractableException E1) {
throw new UnableToInteractWithElementException("Unable To Interact With " + WebElement Descriptionn);
}
}
我的@Name注释界面和pagefactory如下:
名称界面
@Target({ElementType.FIELD, ElementType.TYPE,ElementType.CONSTRUCTOR})
public @interface Name {
String Description() default "";
}
@Name(Description = "Username")
@FindBy(id="txtLoginID")
public WebElement username;
我在使用反射时遇到的问题是需要定义pagefactory的类名,还需要提供字段名作为字符串“ username”来检索注释值。
我希望能够仅通过向click(WebElement element)方法提供我的WebElement而没有其他对象来检索注释值。
答案 0 :(得分:1)
嗨,我不是思考的专家,我不确定我是否正确回答了这个问题。您可能有另一种最佳的实现方式,但是遵循一个解决方案,创建一个接收WebElement并返回描述的方法:
private static String getDescription(WebElement element) throws IllegalAccessException {
//Get all the fields of the page object.
for (Field field : YOUR_PAGE_OBJECT.class.getDeclaredFields()) {
Name name = field.getAnnotation(Name.class);
//Consider only the ones that is annotated by your @Name
if (name != null) {
WebElement classElement = (WebElement) field.get(element);
//Get the element from the class and compare with your current.
if (classElement != null && (classElement).equals(element)) {
return name.Description();
}
}
}
return ":C"; // or throw something, whatever you want...
}
您的代码将以如下形式结束:
public static void click(WebElement element) throws Throwable {
try {
element.click();
} catch(ElementNotInteractableException E1) {
throw new UnableToInteractWithElementException("Unable To Interact With " + getDescription(element));
}
}
答案 1 :(得分:1)
我可以向您展示如何使用反射部分获得描述。
首先,我们必须修复注释@Name
,因为您没有添加RetentionPolicy
:
@Target({ElementType.FIELD, ElementType.TYPE, ElementType.CONSTRUCTOR})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Name {
String Description() default "";
}
现在,我所做的工作和测试,我们为名称创建存储,并在初始化Page Objects时存储它们,如下所示:
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);
}
}
您将Page对象作为参数传递,@Name
批注将被读取并存储到HashMap<WebElement, String>
初始化存储在构造函数中的名称:
public PageObject(WebDriver driver) {
PageFactory.initElements(driver, this);
NameStore.store(this); //THIS IS CRUCIAL. Also make sure that's always AFTER PageFactory initialization
}
现在,要更新您的click
方法:
public static void click(WebElement element) throws Throwable {
try {
element.click();
} catch(ElementNotInteractableException E1) {
throw new UnableToInteractWithElementException("Unable To Interact With " + NameStore.get(element));
}
}
希望有帮助!
免责声明:我没有在多线程环境中对其进行测试。我没有在构造函数的上下文中进行测试。