From 832a2f496b0500b701f224e6b6d535908ef08342 Mon Sep 17 00:00:00 2001 From: Konstantin Maltsev Date: Wed, 3 May 2023 09:10:34 +0700 Subject: [PATCH 1/3] add ability to specify decorator in properties --- .../ru/sbtqa/tag/pagefactory/HTMLPage.java | 8 +++--- .../html/loader/CustomHtmlElementLoader.java | 9 ++++--- .../html/properties/HtmlConfiguration.java | 4 +++ .../reflection/HtmlReflection.java | 25 ++++++++++++++++++- .../pagefactory/utils/HtmlElementUtils.java | 10 +++++--- 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/HTMLPage.java b/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/HTMLPage.java index eddc43467..d2b6ea39a 100644 --- a/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/HTMLPage.java +++ b/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/HTMLPage.java @@ -1,7 +1,5 @@ package ru.sbtqa.tag.pagefactory; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.junit.Assert; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.WebElement; @@ -13,13 +11,15 @@ import ru.sbtqa.tag.pagefactory.find.Find; import ru.sbtqa.tag.pagefactory.find.HtmlFindUtils; import ru.sbtqa.tag.pagefactory.html.actions.HtmlPageActions; -import ru.sbtqa.tag.pagefactory.html.loader.decorators.CustomHtmlElementDecorator; import ru.sbtqa.tag.pagefactory.html.properties.HtmlConfiguration; import ru.sbtqa.tag.pagefactory.reflection.HtmlReflection; import ru.sbtqa.tag.pagefactory.reflection.Reflection; import ru.sbtqa.tag.pagefactory.utils.PageUtils; import ru.yandex.qatools.htmlelements.loader.decorator.HtmlElementLocatorFactory; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * Inherit your html page objects from this class */ @@ -33,7 +33,7 @@ public abstract class HTMLPage extends WebPage { private static final HtmlConfiguration PROPERTIES = HtmlConfiguration.create(); public HTMLPage() { - super(new CustomHtmlElementDecorator(new HtmlElementLocatorFactory(Environment.getDriverService().getDriver()))); + super(HtmlReflection.getDecorator(new HtmlElementLocatorFactory(Environment.getDriverService().getDriver()))); applyEnvironment(); if (PROPERTIES.getVerifyPage()) { PageUtils.verifyPageByDataTestId(); diff --git a/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/html/loader/CustomHtmlElementLoader.java b/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/html/loader/CustomHtmlElementLoader.java index ce370b70d..0658b8712 100644 --- a/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/html/loader/CustomHtmlElementLoader.java +++ b/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/html/loader/CustomHtmlElementLoader.java @@ -1,16 +1,19 @@ package ru.sbtqa.tag.pagefactory.html.loader; -import java.lang.reflect.InvocationTargetException; import org.openqa.selenium.SearchContext; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.PageFactory; -import ru.sbtqa.tag.pagefactory.html.loader.decorators.CustomHtmlElementDecorator; +import org.openqa.selenium.support.pagefactory.FieldDecorator; +import ru.sbtqa.tag.pagefactory.reflection.HtmlReflection; import ru.yandex.qatools.htmlelements.element.HtmlElement; import ru.yandex.qatools.htmlelements.element.TypifiedElement; import ru.yandex.qatools.htmlelements.exceptions.HtmlElementsException; import ru.yandex.qatools.htmlelements.loader.HtmlElementLoader; import ru.yandex.qatools.htmlelements.loader.decorator.HtmlElementLocatorFactory; import ru.yandex.qatools.htmlelements.pagefactory.CustomElementLocatorFactory; + +import java.lang.reflect.InvocationTargetException; + import static ru.yandex.qatools.htmlelements.utils.HtmlElementUtils.newInstance; public class CustomHtmlElementLoader extends HtmlElementLoader { @@ -45,7 +48,7 @@ public static void populatePageObject(Object page, SearchContext searchContext) public static void populatePageObject(Object page, CustomElementLocatorFactory locatorFactory) { - PageFactory.initElements(new CustomHtmlElementDecorator(locatorFactory), page); + PageFactory.initElements((FieldDecorator) HtmlReflection.getDecorator(locatorFactory), page); } } diff --git a/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/html/properties/HtmlConfiguration.java b/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/html/properties/HtmlConfiguration.java index 04486da80..3aad6b764 100644 --- a/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/html/properties/HtmlConfiguration.java +++ b/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/html/properties/HtmlConfiguration.java @@ -23,6 +23,10 @@ public interface HtmlConfiguration extends WebConfiguration { @DefaultValue("false") boolean getVerifyPage(); + @Key("decorator.path") + @DefaultValue("ru.sbtqa.tag.pagefactory.html.loader.decorators.CustomHtmlElementDecorator") + String getDecoratorReferencePath(); + static HtmlConfiguration create() { return Configuration.init(HtmlConfiguration.class); } diff --git a/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/reflection/HtmlReflection.java b/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/reflection/HtmlReflection.java index 7dc1d6903..beaa69180 100644 --- a/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/reflection/HtmlReflection.java +++ b/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/reflection/HtmlReflection.java @@ -1,13 +1,22 @@ package ru.sbtqa.tag.pagefactory.reflection; -import static java.lang.String.format; import ru.sbtqa.tag.pagefactory.environment.Environment; import ru.sbtqa.tag.pagefactory.exception.ElementSearchError; import ru.sbtqa.tag.pagefactory.find.HtmlFindUtils; +import ru.sbtqa.tag.pagefactory.html.loader.decorators.CustomHtmlElementDecorator; +import ru.sbtqa.tag.pagefactory.html.properties.HtmlConfiguration; import ru.yandex.qatools.htmlelements.element.HtmlElement; +import ru.yandex.qatools.htmlelements.pagefactory.CustomElementLocatorFactory; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import static java.lang.String.format; public class HtmlReflection extends DefaultReflection { + private static final HtmlConfiguration PROPERTIES = HtmlConfiguration.create(); + /** * Execute method with one or more parameters inside of the given block * element @@ -25,4 +34,18 @@ public void executeMethodByTitleInBlock(String blockPath, String actionTitle, Ob throw new ElementSearchError(format("Block not found by path '%s'", blockPath), ex); } } + + public static T getDecorator(CustomElementLocatorFactory factory) { + String referencePath = PROPERTIES.getDecoratorReferencePath(); + try { + Class clazz = Class.forName(referencePath); + Constructor constructor = clazz.getConstructor(CustomElementLocatorFactory.class); + T instance = (T) constructor.newInstance(factory); + LOG.debug("Load decorator from path {}", referencePath); + return instance; + } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | + InvocationTargetException e) { + throw new ElementSearchError(format("Decorator not found by path '%s'", referencePath), e); + } + } } diff --git a/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/utils/HtmlElementUtils.java b/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/utils/HtmlElementUtils.java index 3c49d70f8..49c7d3198 100644 --- a/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/utils/HtmlElementUtils.java +++ b/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/utils/HtmlElementUtils.java @@ -1,16 +1,18 @@ package ru.sbtqa.tag.pagefactory.utils; -import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.PageFactory; - import ru.sbtqa.tag.pagefactory.context.PageContext; import ru.sbtqa.tag.pagefactory.environment.Environment; import ru.sbtqa.tag.pagefactory.html.loader.CustomHtmlElementLoader; -import ru.sbtqa.tag.pagefactory.html.loader.decorators.CustomHtmlElementDecorator; +import ru.sbtqa.tag.pagefactory.reflection.HtmlReflection; import ru.yandex.qatools.htmlelements.element.TypifiedElement; +import ru.yandex.qatools.htmlelements.loader.decorator.HtmlElementDecorator; import ru.yandex.qatools.htmlelements.loader.decorator.HtmlElementLocatorFactory; + +import java.util.List; + import static ru.yandex.qatools.htmlelements.utils.HtmlElementUtils.isTypifiedElement; public class HtmlElementUtils { @@ -50,7 +52,7 @@ public static WebElement getWebElement(T element) { */ public static T createElementWithCustomType(Class clazz, WebElement element) { T customElement = CustomHtmlElementLoader.createTypifiedElement(clazz, element, "Custom"); - CustomHtmlElementDecorator decorator = new CustomHtmlElementDecorator(new HtmlElementLocatorFactory(Environment.getDriverService().getDriver())); + HtmlElementDecorator decorator = HtmlReflection.getDecorator(new HtmlElementLocatorFactory(Environment.getDriverService().getDriver())); PageFactory.initElements(decorator, PageContext.getCurrentPage()); return customElement; } From fd0ed103dac09e2fe446df2b929c22d8afcfbf5b Mon Sep 17 00:00:00 2001 From: Konstantin Maltsev Date: Fri, 5 May 2023 13:01:58 +0700 Subject: [PATCH 2/3] add doc, fix pr issues --- .../src/main/asciidoc/web_elements.asciidoc | 6 +++++- .../html/properties/HtmlConfiguration.java | 4 ++-- .../tag/pagefactory/reflection/HtmlReflection.java | 13 +++++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/page-factory-doc/src/main/asciidoc/web_elements.asciidoc b/page-factory-doc/src/main/asciidoc/web_elements.asciidoc index ea8d96f43..1e92e40ef 100644 --- a/page-factory-doc/src/main/asciidoc/web_elements.asciidoc +++ b/page-factory-doc/src/main/asciidoc/web_elements.asciidoc @@ -30,5 +30,9 @@ public abstract class YourPage extends {pn} { ---- - +Также можно переопределлит декоратор для всего проекта, для этого необходимо добавить следующий параметр в файл конфигурации application.properties +[source,] +---- +plugins.html.decorator.fqcn = ru.sbtqa.tag.pagefactory2example.html.loader.MyCustomHtmlElementDecorator +---- diff --git a/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/html/properties/HtmlConfiguration.java b/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/html/properties/HtmlConfiguration.java index 3aad6b764..4972f2527 100644 --- a/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/html/properties/HtmlConfiguration.java +++ b/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/html/properties/HtmlConfiguration.java @@ -23,9 +23,9 @@ public interface HtmlConfiguration extends WebConfiguration { @DefaultValue("false") boolean getVerifyPage(); - @Key("decorator.path") + @Key("plugins.html.decorator.fqcn") @DefaultValue("ru.sbtqa.tag.pagefactory.html.loader.decorators.CustomHtmlElementDecorator") - String getDecoratorReferencePath(); + String getDecoratorFullyQualifiedClassName(); static HtmlConfiguration create() { return Configuration.init(HtmlConfiguration.class); diff --git a/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/reflection/HtmlReflection.java b/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/reflection/HtmlReflection.java index beaa69180..e28f4a4ca 100644 --- a/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/reflection/HtmlReflection.java +++ b/plugins/html-plugin/src/main/java/ru/sbtqa/tag/pagefactory/reflection/HtmlReflection.java @@ -35,17 +35,22 @@ public void executeMethodByTitleInBlock(String blockPath, String actionTitle, Ob } } + /** + * Get custom decorator instance + * + * @param factory custom element locator factory + */ public static T getDecorator(CustomElementLocatorFactory factory) { - String referencePath = PROPERTIES.getDecoratorReferencePath(); + String fullyQualifiedClassName = PROPERTIES.getDecoratorFullyQualifiedClassName(); try { - Class clazz = Class.forName(referencePath); + Class clazz = Class.forName(fullyQualifiedClassName); Constructor constructor = clazz.getConstructor(CustomElementLocatorFactory.class); T instance = (T) constructor.newInstance(factory); - LOG.debug("Load decorator from path {}", referencePath); + LOG.debug("Loaded decorator: {}", fullyQualifiedClassName); return instance; } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new ElementSearchError(format("Decorator not found by path '%s'", referencePath), e); + throw new ElementSearchError(format("Decorator not found by path '%s'", fullyQualifiedClassName), e); } } } From 159b0c85eb0a670f428663f9cb788aca0d6541db Mon Sep 17 00:00:00 2001 From: Konstantin Maltsev Date: Fri, 5 May 2023 13:18:15 +0700 Subject: [PATCH 3/3] fix typo --- page-factory-doc/src/main/asciidoc/web_elements.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/page-factory-doc/src/main/asciidoc/web_elements.asciidoc b/page-factory-doc/src/main/asciidoc/web_elements.asciidoc index 1e92e40ef..ff8469c73 100644 --- a/page-factory-doc/src/main/asciidoc/web_elements.asciidoc +++ b/page-factory-doc/src/main/asciidoc/web_elements.asciidoc @@ -30,7 +30,7 @@ public abstract class YourPage extends {pn} { ---- -Также можно переопределлит декоратор для всего проекта, для этого необходимо добавить следующий параметр в файл конфигурации application.properties +Также можно переопределить декоратор для всего проекта, для этого необходимо добавить следующий параметр в файл конфигурации application.properties [source,] ---- plugins.html.decorator.fqcn = ru.sbtqa.tag.pagefactory2example.html.loader.MyCustomHtmlElementDecorator