我正在努力,我相信这是一个反思问题。
这是事情, 在我的自动化项目中,我正在尝试创建一个帮助器类来验证我的Web应用程序中的页面标签,并创建一个仅包含标签字段的@annotation。
看起来像这样:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface ExpectedLabel{
String label() default "";
}
在我的Page Class中,我有一个字段:
@ExpectedLabel(label="Faça seu Login")
@FindBy(how = How.XPATH, using = "//*[@id='login']/form/h3")
private WebElement facaSeuLoginLabel;
这是我的帮助类方法来验证标签:
@SuppressWarnings("rawtypes")
public boolean validateLabels(Class validationClass){
for (Field field: validationClass.getDeclaredFields()) {
if(field.getType() == WebElement.class && field.isAnnotationPresent(ExpectedLabel.class)){
field.setAccessible(true);
ExpectedLabel expectedLabel = field.getAnnotation(ExpectedLabel.class);
if (StringUtils.isNotBlank(expectedLabel.label())){
try {
WebElement element = (WebElement) field.get(WebElement.class);
if(!StringUtils.equals(element.getText(), expectedLabel.label())){
LoggerUtil.warn("O campo "+field.getName()+" da Page "+validationClass.getSimpleName()+" tem um label invalido! Esperado : ("+expectedLabel.label()+") Obtido: ("+element.getText()+")!", validationClass.getSimpleName());
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
return true;
}
问题是,我必须调用WebElement.getText()来访问Real Page标签,然后在注释@ ExpectedLabel.label中与那个标签进行比较。 无论我尝试什么,只是不能将字段转换为WebElement。
我已经尝试创建一个名为WebElementImpl的WebElement实现并完成转换,但仍然无效。 其他无效的方法是尝试直接从Field调用getText()方法,获取他的公共方法,但我不认为这是可能的。
以下是尝试转换对象时遇到的异常:
java.lang.IllegalArgumentException: Can not set org.openqa.selenium.WebElement field com.org.pages.LoginPage.facaSeuLoginLabel to java.lang.Class
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:55)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
at java.lang.reflect.Field.get(Field.java:379)
at com.org.helpers.LabelValidatorUtil.validateLabels(LabelValidatorUtil.java:20)
at com.org.telas.LoginPageTest.loginPageValidationTest(LoginPageTest.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:86)
Obs:WebElement是一个界面,那么我该如何进行转换呢? 我们欢迎解决问题的新方法。
答案 0 :(得分:0)
问题是你传递了要读取字段的错误对象。按照这一行:
WebElement element = (WebElement) field.get(WebElement.class);
传递给field.get()的对象是java.lang.Class类型,所以你实际上要求像java.lang.Class.fieldName
这样的东西,“fieldName”就是这个字段的名字。当前的迭代是。
您的问题中缺少的是从中读取相关字段的对象。 这必须是您正在验证的对象。您应该在validate方法中获取它,或者更好的是,只接收对象:
public boolean validateLabels(Object object) {
Class<?> validationClass = object.getClass();
for (Field field: validationClass.getDeclaredFields()) {
if(field.getType() == WebElement.class && field.isAnnotationPresent(ExpectedLabel.class)){
field.setAccessible(true);
ExpectedLabel expectedLabel = field.getAnnotation(ExpectedLabel.class);
if (StringUtils.isNotBlank(expectedLabel.label())){
try {
WebElement element = (WebElement) field.get(object);
if(!StringUtils.equals(element.getText(), expectedLabel.label())){
LoggerUtil.warn("O campo "+field.getName()+" da Page "+validationClass.getSimpleName()+" tem um label invalido! Esperado : ("+expectedLabel.label()+") Obtido: ("+element.getText()+")!", validationClass.getSimpleName());
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
return true;
}
该方法现在正在接收具有要验证的值的对象,然后从中推断出该类。
如上所述,最重要的变化是:field.get(object)
检查get的java文档:https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Field.html#get%28java.lang.Object%29