Я создал среду для автоматического тестирования, которая принимает файл Cucumber и объект страницы и использует клейкий код для запуска автоматических тестов. Этот связующий код основывается на рефлексии для создания экземпляров элементов на веб-странице в реальном времени, например:
/**
* Returns a PageElement object for a given elementName string from current page. Gets current page reference, replaces page name space characters qith '_'
*
* @param elementName String name of requested element
* @return PageElement the requested element
* @throws PageNotFoundException if no page object found or defined.
* @throws NoSuchElementException if element is not found or defined.
*/
public static PageElement getElement(String elementName) throws NoSuchElementException, PageNotFoundException {
Page page = PageManager.getPage();
elementName = elementName.replaceAll("\\s+", "_").toLowerCase();
Method pageElementName = null;
try { // Create a Method object to store the PageElementwe want to exercise;
pageElementName = page.getClass().getMethod(elementName);
} catch (NoSuchMethodException e) {
String errorMessage = StringUtils.format("Element {} is not defined for the page object {}. Make sure you have spelled the page object name correctly in your Cucumber step definition and in the page object.", elementName, page
.getClass().getSimpleName());
log.error(errorMessage);
throw new NoSuchElementException(errorMessage, e);
}
PageElement element = null;
try { // Invoke the creation of the PageElement and return it into a variable if no exception is thrown.
element = (PageElement) pageElementName.invoke(page);
log.trace("PageElement Name: " + pageElementName.getName());
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
String errorMessage = StringUtils.format("PageElement {} could not be found on Page {}. Please ensure the element is defined on the page.", pageElementName.getName(), page.getName());
log.error(errorMessage);
throw new NoSuchElementException(errorMessage);
}
return element;
}
Если мне нужно вернуть что-то вроде выпадающего объекта, который имеет больше методов, чем стандартный объект, я сделать это с помощью метода, который преобразует возвращаемый объект:
/**
* Returns the Dropdown associated with the element name on the currently active
* page.
*
* @param elementName String the name of the element to be returned
* @return Dropdown the dropdown associated with the element name on the currently active page
* @throws NoSuchElementException if the element cannot be found
* @throws PageNotFoundException if the page cannot be found
*/
public static Dropdown getElementAsDropdown(String elementName) throws SentinelException {
return (Dropdown) getElement(elementName);
}
В настоящее время у меня есть три раскрывающихся объекта, и все они по-разному определены внутри объекта страницы:
public Dropdown state_dropdown() { return new Dropdown(ID, "state"); }
public MaterialUISelect age_dropdown() { return new MaterialUISelect(XPATH, "//*[@id=\"demo-simple-select\"]"); }
public PrimeNGDropdown city_dropdown() { return new PrimeNGDropdown(XPATH, "//p-dropdown[1]"); }
Я хочу иметь возможность определить все три раскрывающихся списка в объекте Page как Dropdown
и получить код, чтобы выяснить, какой это, когда объект создается. Причина этого в том, что я хочу сделать создание объекта страницы как можно более надежным, поскольку большинство тестеров, использующих инфраструктуру, не очень технически подкованы.
Мне кажется, что для этого мне нужен фабричный метод, но я не могу понять, где это идет в моем коде. Это go в коде getElement ? Это go в выпадающем коде объекта ? Я все об этом думаю неправильно, и я должен использовать другое решение? Я в растерянности, несмотря на то, что отклонил это от пары других разработчиков.