2017-01-14 5 views
0

Я создал тестовую среду с Selenium и настроил ExtentReports для отчета об испытаниях. Используемая объектная модель страницы и аннотация @FindBy для полей для создания собственного хранилища WebElements для каждой страницы. Теперь я хотел бы создать пользовательскую аннотацию @nameПользовательская реализация аннотации для имени WebElements в отчете об испытаниях

@Name(description = "google main page") 
@FindBy(linkText = "Gmail") 
private WebElement gmail; 

И реализация для него, чтобы иметь возможность использовать описание каждого WebElement позже в моем докладе. У меня есть собственная реализация клик() метод

public static void click(WebElement element) { 
    try{ 
     element.click(); 
     TestReport.addLog(LogStatus.INFO, "Element "+NameImpl.getDescription(element)+" clicked"); 
    } catch (NoSuchElementException e) { 
     TestReport.addLog(LogStatus.ERROR, "Element "+NameImpl.getDescription(element)+" not found"); 
    } 
} 

Я могу получить описание всех элементов пометки в классе с отражением как здесь

Is it possible to read the value of a annotation in java?

, но не могу получить описание определенного элемента используется в моем методе кликов.

Любые идеи, как достичь этого?

ответ

0

Как раз по параметру, переданному методу click, нет никакой возможности получить аннотации. Эта причина заключается в аннотации на поле gmail, а не на классе WebElement. Таким образом, единственный способом получить @Name аннотацию является первым получить Field отображающей gmail поля, и это должно быть сделано через объявляющий класс:

ClassWithGmailField.class.getField("gmail").getAnnotation(Name.class).description() 

Просто от параметра метода click, вы могли бы только достичь аннотаций, определенных на самом WebElement класса, например:

@SomeAnnotation 
public class WebElement {...} 

, но это не полезно ни для чего в вашем случае.

Чтобы достичь чего-то похожее на то, что вы хотите, вы могли бы потенциально:

  • рефлексивно анализировать класс, извлечь все @Name «d поля и собирать мета вместе со значениями поля, возможно, в какой-то обертки например NamedElement, который будет иметь описание от @Name и сам WebElement
  • Отражающе вызываем метод click, предоставляя ему мета-нужный (описание в вашем случае). Но для этого вам нужно как-то узнать, какой метод вызывать для каждого поля (например, по еще одной аннотации), делая вашу логику закодированной внешним по отношению к вашему фактическому коду. Может иметь смысл в некоторых случаях, но, вероятно, плохая идея в целом.

Быстрая (Неоткомпилированная, непроверенных) пример кода первой идеи:

public class NamedElement extends WebElement { 

    public String description; 
    public WebElement element; 

    public NamedElement(String description, WebElement element) { 
    this.description = description; 
    this.element = element; 
    } 
} 

public class NamedElementExtractor { 

    public static Collection<NamedElement> getNamedElements(Object instanceWithWebElements) { 
    //instanceWithElements in your case would be an instance of the class that has the "gmail" field, i.e. the one I referred to as ClassWithGmailField above 
    Collection<NamedElement> namedElements = new List<NamedElement>(); 
    for (Field field : instanceWithWebElements.getClass().getDeclaredFields()) { 
     field.setAccessible(true); 
     //maybe first check field.isAnnotationPresent(Name.class) 
     String desc = field.getAnnotation(Name.class).description(); 
     WebElement element = field.getValue(instanceWithWebElements); 
     namedElements.add(new NamedElement(desc, element)); 
    } 
    } 
} 

... 

for (NamedElement namedElement : NamedElementExtractor.getNamedElements(instanceWithWebElements))) { 
    Click.click(namedElement); 
} 

... 

public static void click(NamedElement namedElement) { 
    try{ 
    namedElement.element.click(); 
    TestReport.addLog(LogStatus.INFO, "Element "+ namedElement.description +" clicked"); 
    } catch (NoSuchElementException e) { 
    TestReport.addLog(LogStatus.ERROR, "Element "+ namedElement.description +" not found"); 
    } 
} 

Понятия не имею, если это целесообразно/использовать в вашем случае, но это пища для размышлений.