diff --git a/src/main/java/aquality/selenium/core/applications/AqualityModule.java b/src/main/java/aquality/selenium/core/applications/AqualityModule.java index 94de27d..fb0a8a7 100644 --- a/src/main/java/aquality/selenium/core/applications/AqualityModule.java +++ b/src/main/java/aquality/selenium/core/applications/AqualityModule.java @@ -2,6 +2,7 @@ import aquality.selenium.core.configurations.*; import aquality.selenium.core.elements.IElementsModule; +import aquality.selenium.core.elements.interfaces.IElementFactory; import aquality.selenium.core.elements.interfaces.IElementFinder; import aquality.selenium.core.localization.ILocalizationManager; import aquality.selenium.core.localization.ILocalizationModule; @@ -45,5 +46,6 @@ protected void configure() { bind(ILocalizedLogger.class).to(getLocalizedLoggerImplementation()).in(Singleton.class); bind(IConditionalWait.class).to(getConditionalWaitImplementation()); bind(IElementFinder.class).to(getElementFinderImplementation()); + bind(IElementFactory.class).to(getElementFactoryImplementation()); } } diff --git a/src/main/java/aquality/selenium/core/elements/ElementFactory.java b/src/main/java/aquality/selenium/core/elements/ElementFactory.java new file mode 100644 index 0000000..edacc1d --- /dev/null +++ b/src/main/java/aquality/selenium/core/elements/ElementFactory.java @@ -0,0 +1,165 @@ +package aquality.selenium.core.elements; + +import aquality.selenium.core.elements.interfaces.IElement; +import aquality.selenium.core.elements.interfaces.IElementFactory; +import aquality.selenium.core.elements.interfaces.IElementFinder; +import aquality.selenium.core.elements.interfaces.IElementSupplier; +import aquality.selenium.core.localization.ILocalizationManager; +import aquality.selenium.core.logging.Logger; +import aquality.selenium.core.waitings.IConditionalWait; +import com.google.inject.Inject; +import org.openqa.selenium.By; +import org.openqa.selenium.By.ByXPath; +import org.openqa.selenium.InvalidArgumentException; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.pagefactory.ByChained; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeoutException; + +public class ElementFactory implements IElementFactory { + + private static final int XPATH_SUBSTRING_BEGIN_INDEX = 10; + private static final long ZERO_TIMEOUT = 0L; + + private final IConditionalWait conditionalWait; + private final IElementFinder elementFinder; + private final ILocalizationManager localizationManager; + + @Inject + public ElementFactory(IConditionalWait conditionalWait, IElementFinder elementFinder, ILocalizationManager localizationManager) { + this.conditionalWait = conditionalWait; + this.elementFinder = elementFinder; + this.localizationManager = localizationManager; + } + + @Override + public T getCustomElement(IElementSupplier elementSupplier, By locator, String name, ElementState state) { + return elementSupplier.get(locator, name, state); + } + + @Override + public T getCustomElement(Class clazz, By locator, String name, ElementState state) { + IElementSupplier elementSupplier = getDefaultElementSupplier(clazz); + return getCustomElement(elementSupplier, locator, name, state); + } + + @Override + public T findChildElement(IElement parentElement, By childLoc, String name, Class clazz, ElementState state) { + IElementSupplier elementSupplier = getDefaultElementSupplier(clazz); + return findChildElement(parentElement, childLoc, name, elementSupplier, state); + } + + @Override + public T findChildElement(IElement parentElement, By childLoc, String name, IElementSupplier supplier, ElementState state) { + String childName = name == null ? "Child element of ".concat(parentElement.getName()) : name; + By fullLocator = new ByChained(parentElement.getLocator(), childLoc); + return supplier.get(fullLocator, childName, state); + } + + @Override + public List findElements(By locator, String name, IElementSupplier supplier, + ElementsCount count, ElementState state) { + try { + waitForElementsCount(locator, count, state); + } catch (TimeoutException e) { + throw new org.openqa.selenium.TimeoutException(e.getMessage()); + } + List webElements = elementFinder.findElements(locator, state, ZERO_TIMEOUT); + String namePrefix = name == null ? "element" : name; + List list = new ArrayList<>(); + for (int index = 1; index <= webElements.size(); index++) { + WebElement webElement = webElements.get(index - 1); + String currentName = String.format("%1$s %2$s", namePrefix, index); + T element = supplier.get(generateXpathLocator(locator, webElement, index), currentName, state); + list.add(element); + } + return list; + } + + protected void waitForElementsCount(By locator, ElementsCount count, ElementState state) throws TimeoutException { + switch (count) { + case ZERO: + conditionalWait.waitForTrue(() -> elementFinder.findElements(locator, state, ZERO_TIMEOUT).isEmpty(), + localizationManager.getLocalizedMessage("loc.elements.found.but.should.not", + locator.toString(), state.toString())); + break; + case MORE_THEN_ZERO: + conditionalWait.waitForTrue(() -> !elementFinder.findElements(locator, state, ZERO_TIMEOUT).isEmpty(), + localizationManager.getLocalizedMessage("loc.no.elements.found.by.locator", + locator.toString(), state.toString())); + break; + case ANY: + conditionalWait.waitFor(() -> elementFinder.findElements(locator, state, ZERO_TIMEOUT) != null); + break; + default: + throw new IllegalArgumentException("No such expected value: ".concat(count.toString())); + } + } + + @Override + public List findElements(By locator, String name, Class clazz, + ElementsCount count, ElementState state) { + IElementSupplier elementSupplier = getDefaultElementSupplier(clazz); + return findElements(locator, name, elementSupplier, count, state); + } + + /** + * Generates xpath locator for target element. + * + * @param multipleElementsLocator locator used to find elements. Currently only {@link ByXPath} locators are supported. + * @param webElement target element. + * @param elementIndex index of target element. + * @return target element's locator + */ + protected By generateXpathLocator(By multipleElementsLocator, WebElement webElement, int elementIndex) { + Class supportedLocatorType = ByXPath.class; + if (multipleElementsLocator.getClass().equals(supportedLocatorType)) { + return By.xpath( + String.format("(%1$s)[%2$s]", multipleElementsLocator.toString().substring(XPATH_SUBSTRING_BEGIN_INDEX), elementIndex)); + } + throw new InvalidArgumentException(String.format( + "Cannot define unique baseLocator for element %1$s. Multiple elements' baseLocator %2$s is not %3$s, and is not supported yet", + webElement.toString(), multipleElementsLocator, supportedLocatorType)); + } + + /** + * Gets map between elements interfaces and their implementations. + * Can be extended for custom elements with custom interfaces. + * + * @return Map where key is interface and value is its implementation. + */ + protected Map, Class> getElementTypesMap() { + return new HashMap<>(); + } + + protected Class resolveElementClass(Class clazz) { + if (clazz.isInterface() && !getElementTypesMap().containsKey(clazz)) { + throw new IllegalArgumentException( + String.format("Interface %1$s is not found in getElementTypesMap()", clazz)); + } + + return clazz.isInterface() ? (Class) getElementTypesMap().get(clazz) : clazz; + } + + protected IElementSupplier getDefaultElementSupplier(Class clazz) { + return (locator, name, state) -> { + try { + Constructor ctor = resolveElementClass(clazz) + .getDeclaredConstructor(By.class, String.class, ElementState.class); + ctor.setAccessible(true); + T instance = ctor.newInstance(locator, name, state); + ctor.setAccessible(false); + return instance; + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { + Logger.getInstance().debug(e.getMessage()); + throw new IllegalArgumentException("Something went wrong during element casting"); + } + }; + } +} diff --git a/src/main/java/aquality/selenium/core/elements/ElementsCount.java b/src/main/java/aquality/selenium/core/elements/ElementsCount.java new file mode 100644 index 0000000..c400bcf --- /dev/null +++ b/src/main/java/aquality/selenium/core/elements/ElementsCount.java @@ -0,0 +1,7 @@ +package aquality.selenium.core.elements; + +public enum ElementsCount { + ZERO, + MORE_THEN_ZERO, + ANY +} diff --git a/src/main/java/aquality/selenium/core/elements/IElementsModule.java b/src/main/java/aquality/selenium/core/elements/IElementsModule.java index 1b3f982..33aee0d 100644 --- a/src/main/java/aquality/selenium/core/elements/IElementsModule.java +++ b/src/main/java/aquality/selenium/core/elements/IElementsModule.java @@ -1,5 +1,6 @@ package aquality.selenium.core.elements; +import aquality.selenium.core.elements.interfaces.IElementFactory; import aquality.selenium.core.elements.interfaces.IElementFinder; /** @@ -12,4 +13,11 @@ public interface IElementsModule { default Class getElementFinderImplementation() { return ElementFinder.class; } + + /** + * @return class which implements IElementFactory + */ + default Class getElementFactoryImplementation() { + return ElementFactory.class; + } } diff --git a/src/main/java/aquality/selenium/core/elements/interfaces/IElement.java b/src/main/java/aquality/selenium/core/elements/interfaces/IElement.java new file mode 100644 index 0000000..f3b5b63 --- /dev/null +++ b/src/main/java/aquality/selenium/core/elements/interfaces/IElement.java @@ -0,0 +1,38 @@ +package aquality.selenium.core.elements.interfaces; + +import org.openqa.selenium.By; +import org.openqa.selenium.remote.RemoteWebElement; + +public interface IElement extends IParent { + + /** + * Gets clear WebElement. + * + * @return WebElement + */ + default RemoteWebElement getElement() { + return getElement(null); + } + + /** + * Gets clear WebElement. + * + * @param timeout Timeout for waiting + * @return WebElement + */ + RemoteWebElement getElement(Long timeout); + + /** + * Gets element name. + * + * @return name + */ + String getName(); + + /** + * Gets element locator. + * + * @return locator + */ + By getLocator(); +} diff --git a/src/main/java/aquality/selenium/core/elements/interfaces/IElementFactory.java b/src/main/java/aquality/selenium/core/elements/interfaces/IElementFactory.java new file mode 100644 index 0000000..7d9f9fa --- /dev/null +++ b/src/main/java/aquality/selenium/core/elements/interfaces/IElementFactory.java @@ -0,0 +1,269 @@ +package aquality.selenium.core.elements.interfaces; + +import aquality.selenium.core.elements.ElementState; +import aquality.selenium.core.elements.ElementsCount; +import org.openqa.selenium.By; + +import java.util.List; + +/** + * Defines the interface used to create the elements. + */ +public interface IElementFactory { + + /** + * Create custom element according to passed parameters. + * + * @param elementSupplier Delegate that defines constructor of element. + * @param locator Locator of the target element. + * @param name Name of the target element. + * @param Type of the target element. + * @return Instance of custom element. + */ + default T getCustomElement(IElementSupplier elementSupplier, By locator, String name) { + return getCustomElement(elementSupplier, locator, name, ElementState.DISPLAYED); + } + + /** + * Create custom element according to passed parameters. + * + * @param elementSupplier Delegate that defines constructor of element. + * @param locator Locator of the target element. + * @param name Name of the target element. + * @param state Visibility state of the target element. + * @param Type of the target element. + * @return Instance of custom element. + */ + T getCustomElement(IElementSupplier elementSupplier, By locator, String name, ElementState state); + + /** + * Create custom element according to passed parameters. + * + * @param clazz Class or interface of the element to be obtained. + * @param locator Locator of the target element. + * @param name Name of the target element. + * @param Type of the target element. + * @return Instance of custom element. + */ + default T getCustomElement(Class clazz, By locator, String name) { + return getCustomElement(clazz, locator, name, ElementState.DISPLAYED); + } + + /** + * Create custom element according to passed parameters. + * + * @param clazz Class or interface of the element to be obtained. + * @param locator Locator of the target element. + * @param name Name of the target element. + * @param state Visibility state of the target element. + * @param Type of the target element. + * @return Instance of custom element. + */ + T getCustomElement(Class clazz, By locator, String name, ElementState state); + + /** + * Finds child element by its locator relative to parent element. + * + * @param childLoc Locator of child element relative to its parent. + * @param clazz Class or interface of the element to be obtained. + * @param name Child element name. + * @param parentElement Parent element for relative search of child element. + * @param state Visibility state of target element. + * @return Child element. + */ + T findChildElement(IElement parentElement, By childLoc, String name, + Class clazz, ElementState state); + + /** + * Finds child element in any state by its locator relative to parent element. + * + * @param childLoc Locator of child element relative to its parent. + * @param clazz Class or interface of the element to be obtained. + * @param name Child element name. + * @param parentElement Parent element for relative search of child element. + * @return Child element. + */ + default T findChildElement(IElement parentElement, By childLoc, String name, + Class clazz) { + return findChildElement(parentElement, childLoc, name, clazz, ElementState.EXISTS_IN_ANY_STATE); + } + + /** + * Finds child element by its locator relative to parent element. + * + * @param childLoc Locator of child element relative to its parent. + * @param clazz Class or interface of the element to be obtained. + * @param parentElement Parent element for relative search of child element. + * @param state Visibility state of child element. + * @return Child element. + */ + default T findChildElement(IElement parentElement, By childLoc, + Class clazz, ElementState state) { + return findChildElement(parentElement, childLoc, null, clazz, state); + } + + /** + * Finds child element existing in any state by its locator relative to parent element. + * + * @param childLoc Locator of child element relative to its parent. + * @param clazz Class or interface of the element to be obtained. + * @param parentElement Parent element for relative search of child element. + * @return Child element. + */ + default T findChildElement(IElement parentElement, By childLoc, + Class clazz) { + return findChildElement(parentElement, childLoc, null, clazz, ElementState.EXISTS_IN_ANY_STATE); + } + + /** + * Finds child element existing in any state by its locator relative to parent element. + * + * @param childLoc Locator of child element relative to its parent. + * @param supplier Required element's supplier. + * @param name Child element name. + * @param parentElement Parent element for relative search of child element. + * @return Child element. + */ + default T findChildElement(IElement parentElement, By childLoc, String name, + IElementSupplier supplier) { + return findChildElement(parentElement, childLoc, name, supplier, ElementState.EXISTS_IN_ANY_STATE); + } + + /** + * Finds child element by its locator relative to parent element. + * + * @param childLoc Locator of child element relative to its parent. + * @param supplier Required element's supplier. + * @param name Child element name. + * @param parentElement Parent element for relative search of child element. + * @param state Visibility state of child element. + * @return Child element. + */ + T findChildElement(IElement parentElement, By childLoc, String name, + IElementSupplier supplier, ElementState state); + + /** + * Finds child element by its locator relative to parent element. + * + * @param childLoc Locator of child element relative to its parent. + * @param supplier Required element's supplier. + * @param parentElement Parent element for relative search of child element. + * @param state Visibility state of child element. + * @return Child element. + */ + default T findChildElement(IElement parentElement, By childLoc, + IElementSupplier supplier, ElementState state) { + return findChildElement(parentElement, childLoc, null, supplier, state); + } + + /** + * Finds child element existing in any state by its locator relative to parent element. + * + * @param childLoc Locator of child element relative to its parent. + * @param supplier Required element's supplier. + * @param parentElement Parent element for relative search of child element. + * @return Child element. + */ + default T findChildElement(IElement parentElement, By childLoc, + IElementSupplier supplier) { + return findChildElement(parentElement, childLoc, supplier, ElementState.EXISTS_IN_ANY_STATE); + } + + /** + * Find list of elements. + * + * @param locator Elements selector. + * @param name Child element name. + * @param supplier Required elements' supplier. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @param state Visibility state of target elements. + * @return List of elements. + */ + List findElements(By locator, String name, IElementSupplier supplier, ElementsCount count, + ElementState state); + + /** + * Find list of elements. + * + * @param locator Elements selector. + * @param supplier Required elements' supplier. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @param state Visibility state of target elements. + * @return List of elements. + */ + default List findElements(By locator, IElementSupplier supplier, ElementsCount count, + ElementState state) { + return findElements(locator, null, supplier, count, state); + } + + /** + * Find list of elements. + * + * @param locator Elements selector. + * @param name Child element name. + * @param clazz Class or interface of the element to be obtained. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of elements. + */ + List findElements(By locator, String name, Class clazz, ElementsCount count, ElementState state); + + /** + * Find list of elements. + * + * @param locator Elements selector. + * @param clazz Class or interface of the element to be obtained. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of elements. + */ + default List findElements(By locator, Class clazz, ElementsCount count, ElementState state) { + return findElements(locator, null, clazz, count, state); + } + + /** + * Find list of elements. + * + * @param locator Elements selector. + * @param clazz Class or interface of elements to be obtained. + * @return List of elements. + */ + default List findElements(By locator, Class clazz) { + return findElements(locator, clazz, ElementsCount.ANY, ElementState.DISPLAYED); + } + + /** + * Find list of elements. + * + * @param locator Elements selector. + * @param clazz Class or interface of elements to be obtained. + * @param name Child element name. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of elements. + */ + default List findElements(By locator, String name, Class clazz, ElementsCount count) { + return findElements(locator, name, clazz, count, ElementState.DISPLAYED); + } + + /** + * Find list of elements. + * + * @param locator Elements selector. + * @param name Child element name. + * @param clazz Class or interface of elements to be obtained. + * @return List of elements. + */ + default List findElements(By locator, String name, Class clazz) { + return findElements(locator, name, clazz, ElementsCount.ANY); + } + + /** + * Find list of elements. + * + * @param locator Elements selector. + * @param clazz Class or interface of elements to be obtained. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of elements. + */ + default List findElements(By locator, Class clazz, ElementsCount count) { + return findElements(locator, clazz, count, ElementState.DISPLAYED); + } +} diff --git a/src/main/java/aquality/selenium/core/elements/interfaces/IElementSupplier.java b/src/main/java/aquality/selenium/core/elements/interfaces/IElementSupplier.java new file mode 100644 index 0000000..ffe7115 --- /dev/null +++ b/src/main/java/aquality/selenium/core/elements/interfaces/IElementSupplier.java @@ -0,0 +1,30 @@ +package aquality.selenium.core.elements.interfaces; + +import aquality.selenium.core.elements.ElementState; +import org.openqa.selenium.By; + +/** + * Describes interface to supply class which implements IElement interface + * @param type of the element to be supplied + */ +public interface IElementSupplier { + + /** + * Returns an instance of element + * @param locator By locator + * @param name output name in logs + * @param state desired element's state + * @return an instance of element + */ + T get(By locator, String name, ElementState state); + + /** + * Returns an instance of element which desired to be in DISPLAYED {@link ElementState} + * @param locator By locator + * @param name output name in logs + * @return an instance of element + */ + default T get(By locator, String name) { + return get(locator, name, ElementState.DISPLAYED); + } +} diff --git a/src/main/java/aquality/selenium/core/elements/interfaces/IParent.java b/src/main/java/aquality/selenium/core/elements/interfaces/IParent.java new file mode 100644 index 0000000..9efa4f9 --- /dev/null +++ b/src/main/java/aquality/selenium/core/elements/interfaces/IParent.java @@ -0,0 +1,38 @@ +package aquality.selenium.core.elements.interfaces; + +import aquality.selenium.core.elements.ElementState; +import org.openqa.selenium.By; + +public interface IParent { + + /** + * Find an element in the parent element + * + * @param childLoc Child element locator + * @param clazz class or interface of the element to be obtained + * @return found child element + */ + default T findChildElement(By childLoc, Class clazz){ + return findChildElement(childLoc, clazz, ElementState.DISPLAYED); + } + + /** + * Find an element in the parent element + * + * @param childLoc Child element locator + * @param clazz class or interface of the element to be obtained + * @param state visibility state of target element + * @return found child element + */ + T findChildElement(By childLoc, Class clazz, ElementState state); + + /** + * Find an element in the parent element + * + * @param childLoc Child element locator + * @param supplier required element's supplier + * @param state visibility state of target element + * @return found child element + */ + T findChildElement(By childLoc, IElementSupplier supplier, ElementState state); +} diff --git a/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java b/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java index e5a2f0c..79cc46b 100644 --- a/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java +++ b/src/main/java/aquality/selenium/core/waitings/ConditionalWait.java @@ -99,7 +99,7 @@ private boolean isConditionSatisfied(BooleanSupplier condition, Collection T findChildElement(By childLoc, Class clazz, ElementState state) { + throw new NotImplementedException("not implemented in tests"); + } + + @Override + public T findChildElement(By childLoc, IElementSupplier supplier, ElementState state) { + throw new NotImplementedException("not implemented in tests"); + } + + public ElementState getState() { + return state; + } +} diff --git a/src/test/java/tests/elements/factory/CustomElementFactory.java b/src/test/java/tests/elements/factory/CustomElementFactory.java new file mode 100644 index 0000000..b3bb37c --- /dev/null +++ b/src/test/java/tests/elements/factory/CustomElementFactory.java @@ -0,0 +1,24 @@ +package tests.elements.factory; + +import aquality.selenium.core.elements.ElementFactory; +import aquality.selenium.core.elements.interfaces.IElement; +import aquality.selenium.core.elements.interfaces.IElementFinder; +import aquality.selenium.core.localization.ILocalizationManager; +import aquality.selenium.core.waitings.IConditionalWait; + +import java.util.HashMap; +import java.util.Map; + +public class CustomElementFactory extends ElementFactory { + CustomElementFactory(IConditionalWait conditionalWait, IElementFinder elementFinder, ILocalizationManager localizationManager) { + super(conditionalWait, elementFinder, localizationManager); + } + + @Override + protected Map, Class> getElementTypesMap() { + Map, Class> typesMap = new HashMap<>(); + typesMap.put(ICustomElement.class, CustomElement.class); + return typesMap; + } +} + diff --git a/src/test/java/tests/elements/factory/ElementFactoryTests.java b/src/test/java/tests/elements/factory/ElementFactoryTests.java new file mode 100644 index 0000000..746617c --- /dev/null +++ b/src/test/java/tests/elements/factory/ElementFactoryTests.java @@ -0,0 +1,207 @@ +package tests.elements.factory; + +import aquality.selenium.core.applications.IApplication; +import aquality.selenium.core.elements.ElementState; +import aquality.selenium.core.elements.ElementsCount; +import aquality.selenium.core.elements.interfaces.IElement; +import aquality.selenium.core.elements.interfaces.IElementFactory; +import aquality.selenium.core.elements.interfaces.IElementFinder; +import aquality.selenium.core.localization.ILocalizationManager; +import aquality.selenium.core.waitings.IConditionalWait; +import org.openqa.selenium.By; +import org.openqa.selenium.InvalidArgumentException; +import org.openqa.selenium.TimeoutException; +import org.testng.Assert; +import org.testng.annotations.AfterGroups; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; +import tests.ITestWithApplication; +import tests.application.windowsApp.AqualityServices; +import tests.application.windowsApp.CalculatorWindow; + +public class ElementFactoryTests implements ITestWithApplication { + private static final String CONDITION_TIMEOUT_KEY = "timeouts.timeoutCondition"; + private static final String NEW_TIMEOUT_VALUE = "5"; + private static final int XPATH_SUBSTRING_BEGIN_INDEX = 10; + + private CustomElementFactory customFactory() { + return new CustomElementFactory(AqualityServices.get(IConditionalWait.class), + AqualityServices.get(IElementFinder.class), AqualityServices.get(ILocalizationManager.class)); + } + + private IElementFactory defaultFactory() { + return AqualityServices.get(IElementFactory.class); + } + + @BeforeGroups("timeout") + public void setupTimeout() { + System.setProperty(CONDITION_TIMEOUT_KEY, NEW_TIMEOUT_VALUE); + AqualityServices.resetInjector(); + } + + @AfterGroups("timeout") + public void resetTimeout() { + System.clearProperty(CONDITION_TIMEOUT_KEY); + AqualityServices.resetInjector(); + } + + private IElement getParentElement() { + return customFactory().getCustomElement(ICustomElement.class, CalculatorWindow.getWindowLocator(), "window"); + } + + @Test + public void shouldBePossibleToCreateCustomElementViaCustomFactory() { + Assert.assertNotNull(customFactory().getCustomElement(ICustomElement.class, By.name("any"), "any")); + } + + @Test + public void shouldBePossibleToCreateCustomElementViaCustomFactoryUsingImplementation() { + Assert.assertNotNull(customFactory().getCustomElement(CustomElement.class, By.name("any"), "any")); + } + + @Test + public void shouldBePossibleToCreateCustomElementViaDefaultFactoryUsingSupplier() { + Assert.assertNotNull(defaultFactory().getCustomElement(CustomElement::new, By.name("any"), "any")); + } + + @Test + public void shouldBePossibleToFindCustomElementsViaCustomFactory() { + Assert.assertTrue(customFactory().findElements(CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class).size() > 1); + } + + @Test + public void shouldBePossibleToFindCustomElementsViaDefaultFactoryUsingImplementation() { + Assert.assertTrue(defaultFactory().findElements(CalculatorWindow.getEqualsButtonByXPath(), CustomElement.class).size() > 1); + } + + @Test + public void shouldBePossibleToFindCustomElementsViaCustomFactoryWithCustomElementsCount() { + Assert.assertTrue(customFactory().findElements(CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class, ElementsCount.MORE_THEN_ZERO).size() > 1); + } + + @Test + public void shouldBePossibleToFindCustomElementsViaSupplierWithDefaultName() { + Assert.assertTrue(customFactory().findElements( + CalculatorWindow.getEqualsButtonByXPath(), CustomElement::new, ElementsCount.MORE_THEN_ZERO, + ElementState.EXISTS_IN_ANY_STATE).size() > 1); + } + + @Test + public void shouldBePossibleToFindCustomElementsViaSupplierWithCustomName() { + String customName = "56789"; + Assert.assertTrue(customFactory().findElements( + CalculatorWindow.getEqualsButtonByXPath(), customName, CustomElement::new, ElementsCount.MORE_THEN_ZERO, + ElementState.EXISTS_IN_ANY_STATE).get(0).getName().contains(customName)); + } + + @Test + public void shouldBePossibleToFindCustomElementsViaSupplierWithCustomState() { + Assert.assertEquals(customFactory().findElements( + CalculatorWindow.getEqualsButtonByXPath(), CustomElement::new, ElementsCount.MORE_THEN_ZERO, + ElementState.EXISTS_IN_ANY_STATE).get(0).getState(), ElementState.EXISTS_IN_ANY_STATE); + } + + @Test + public void shouldBePossibleToFindCustomElementsViaCustomFactoryWithDefaultElementsCount() { + Assert.assertTrue(customFactory().findElements(CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class, ElementsCount.ANY).size() > 1); + } + + @Test + public void shouldSetCorrectParametersWhenFindElements() { + String customName = "asd"; + ICustomElement element = customFactory().findElements(CalculatorWindow.getEqualsButtonByXPath(), customName, ICustomElement.class).get(1); + Assert.assertNotEquals(element.getName(), customName); + Assert.assertTrue(element.getName().contains(customName)); + Assert.assertTrue(element.getLocator().toString().contains(CalculatorWindow.getEqualsButtonByXPath().toString().substring(XPATH_SUBSTRING_BEGIN_INDEX))); + } + + @Test + public void shouldBePossibleToFindCustomElementsViaCustomFactoryWithZeroElementsCount() { + Assert.assertTrue(customFactory().findElements(By.name("any"), ICustomElement.class, ElementsCount.ANY).isEmpty()); + } + + @Test(groups = "timeout") + public void shouldThrowTimeoutExceptionWhenCountIsNotExpected() { + Assert.assertThrows(TimeoutException.class, () -> customFactory().findElements(CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class, ElementsCount.ZERO)); + } + + @Test + public void shouldThrowInvalidArgumentExceptionInFindElementsWhenLocatorIsNotSupported() { + Assert.assertThrows(InvalidArgumentException.class, () -> customFactory().findElements(CalculatorWindow.getEqualsButton(), ICustomElement.class, ElementsCount.MORE_THEN_ZERO)); + } + + @Test + public void shouldThrowIllegalArgumentExceptionInFindElementsElementTypeIsUnknown() { + Assert.assertThrows(IllegalArgumentException.class, () -> defaultFactory().findElements(CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class)); + } + + @Test + public void shouldThrowIllegalArgumentExceptionInFindChildElementElementTypeIsUnknown() { + Assert.assertThrows(IllegalArgumentException.class, () -> defaultFactory().findChildElement(getParentElement(), CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class)); + } + + @Test + public void shouldThrowIllegalArgumentExceptionInGetCustomElementElementTypeIsUnknown() { + Assert.assertThrows(IllegalArgumentException.class, () -> defaultFactory().getCustomElement(ICustomElement.class, CalculatorWindow.getEqualsButtonByXPath(), "")); + } + + @Test + public void shouldBePossibleToFindChildElementViaCustomFactory() { + IElement parent = getParentElement(); + Assert.assertNotNull(customFactory().findChildElement(parent, CalculatorWindow.getEqualsButton(), ICustomElement.class)); + } + + @Test + public void shouldBePossibleToFindChildElementWithSpecificName() { + IElement parent = getParentElement(); + String name = "123"; + Assert.assertEquals(customFactory().findChildElement(parent, CalculatorWindow.getEqualsButton(), name, ICustomElement.class).getName(), name); + } + + @Test + public void shouldBePossibleToFindChildElementWithSpecificNameUsingSupplier() { + IElement parent = getParentElement(); + String name = "123"; + Assert.assertEquals(customFactory().findChildElement(parent, CalculatorWindow.getEqualsButton(), name, CustomElement::new).getName(), name); + } + + @Test + public void shouldBePossibleToFindChildElementViaCustomFactoryUsingSupplier() { + IElement parent = getParentElement(); + Assert.assertNotNull(customFactory().findChildElement(parent, CalculatorWindow.getEqualsButton(), CustomElement::new)); + } + + @Test + public void shouldBePossibleToFindChildElementViaDefaultFactoryUsingImplementation() { + IElement parent = defaultFactory().getCustomElement(CustomElement.class, CalculatorWindow.getWindowLocator(), "window"); + Assert.assertNotNull(defaultFactory().findChildElement(parent, CalculatorWindow.getEqualsButton(), CustomElement.class)); + } + + @Test + public void shouldBePossibleToFindChildElementWithCustomState() { + IElement parent = getParentElement(); + Assert.assertEquals( + defaultFactory().findChildElement(parent, CalculatorWindow.getEqualsButton(), CustomElement.class, + ElementState.EXISTS_IN_ANY_STATE).getState(), + ElementState.EXISTS_IN_ANY_STATE); + } + + @Test + public void shouldSetCorrectParametersWhenGettingElement() { + String name = "1some2"; + CustomElement element = defaultFactory().getCustomElement(CustomElement::new, CalculatorWindow.getEqualsButton(), name, ElementState.EXISTS_IN_ANY_STATE); + Assert.assertEquals(element.getLocator(), CalculatorWindow.getEqualsButton()); + Assert.assertEquals(element.getName(), name); + Assert.assertEquals(element.getState(), ElementState.EXISTS_IN_ANY_STATE); + } + + @Override + public IApplication getApplication() { + return AqualityServices.getApplication(); + } + + @Override + public boolean isApplicationStarted() { + return AqualityServices.isApplicationStarted(); + } +} diff --git a/src/test/java/tests/elements/factory/ICustomElement.java b/src/test/java/tests/elements/factory/ICustomElement.java new file mode 100644 index 0000000..b91bb06 --- /dev/null +++ b/src/test/java/tests/elements/factory/ICustomElement.java @@ -0,0 +1,6 @@ +package tests.elements.factory; + +import aquality.selenium.core.elements.interfaces.IElement; + +public interface ICustomElement extends IElement { +} diff --git a/src/test/resources/TestSuite.xml b/src/test/resources/TestSuite.xml index cacebc9..5d297dd 100644 --- a/src/test/resources/TestSuite.xml +++ b/src/test/resources/TestSuite.xml @@ -28,6 +28,7 @@ + \ No newline at end of file