尝试将Field转换为WebElement时出现Java Reflection错误

时间:2016-05-25 13:22:30

标签: java reflection selenium-webdriver webdriver

我正在努力,我相信这是一个反思问题。

这是事情, 在我的自动化项目中,我正在尝试创建一个帮助器类来验证我的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是一个界面,那么我该如何进行转换呢? 我们欢迎解决问题的新方法。

1 个答案:

答案 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