diff --git a/pom.xml b/pom.xml index 2ff9793..dda6773 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.aquality-automation aquality-selenium-core - 1.0.2 + 1.1.0 jar Aquality Selenium Core diff --git a/src/main/java/aquality/selenium/core/elements/Element.java b/src/main/java/aquality/selenium/core/elements/Element.java index 7a11dec..c520a8e 100644 --- a/src/main/java/aquality/selenium/core/elements/Element.java +++ b/src/main/java/aquality/selenium/core/elements/Element.java @@ -13,6 +13,7 @@ import org.openqa.selenium.remote.RemoteWebElement; import java.time.Duration; +import java.util.List; import java.util.function.Supplier; public abstract class Element implements IElement { @@ -128,6 +129,16 @@ public T findChildElement(By childLoc, String name, IElemen return getElementFactory().findChildElement(this, childLoc, name, supplier, state); } + @Override + public List findChildElements(By childLoc, String name, Class clazz, ElementState state, ElementsCount count) { + return getElementFactory().findChildElements(this, childLoc, name, clazz, count, state); + } + + @Override + public List findChildElements(By childLoc, String name, IElementSupplier supplier, ElementState state, ElementsCount count) { + return getElementFactory().findChildElements(this, childLoc, name, supplier, count, state); + } + protected T doWithRetry(Supplier action) { return getElementActionRetrier().doWithRetry(action); } diff --git a/src/main/java/aquality/selenium/core/elements/ElementFactory.java b/src/main/java/aquality/selenium/core/elements/ElementFactory.java index 357aabb..5e843ff 100644 --- a/src/main/java/aquality/selenium/core/elements/ElementFactory.java +++ b/src/main/java/aquality/selenium/core/elements/ElementFactory.java @@ -9,6 +9,7 @@ import aquality.selenium.core.waitings.IConditionalWait; import com.google.inject.Inject; import org.openqa.selenium.By; +import org.openqa.selenium.By.ByTagName; import org.openqa.selenium.By.ByXPath; import org.openqa.selenium.InvalidArgumentException; import org.openqa.selenium.WebElement; @@ -26,6 +27,8 @@ public class ElementFactory implements IElementFactory { private static final int XPATH_SUBSTRING_BEGIN_INDEX = 10; + private static final int TAGNAME_SUBSTRING_BEGIN_INDEX = 12; + private static final String TAGNAME_XPATH_PREFIX = "//"; private static final Duration ZERO_TIMEOUT = Duration.ZERO; private final IConditionalWait conditionalWait; @@ -59,10 +62,23 @@ public T findChildElement(IElement parentElement, By childL @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); + By fullLocator = generateAbsoluteChildLocator(parentElement.getLocator(), childLoc); return supplier.get(fullLocator, childName, state); } + @Override + public List findChildElements(IElement parentElement, By childLoc, String name, Class clazz, ElementsCount count, ElementState state) { + IElementSupplier elementSupplier = getDefaultElementSupplier(clazz); + return findChildElements(parentElement, childLoc, name, elementSupplier, count, state); + } + + @Override + public List findChildElements(IElement parentElement, By childLoc, String name, IElementSupplier supplier, ElementsCount count, ElementState state) { + String childName = name == null ? "Child element of ".concat(parentElement.getName()) : name; + By fullLocator = generateAbsoluteChildLocator(parentElement.getLocator(), childLoc); + return findElements(fullLocator, childName, supplier, count, state); + } + @Override public List findElements(By locator, String name, IElementSupplier supplier, ElementsCount count, ElementState state) { @@ -119,14 +135,63 @@ public List findElements(By locator, String name, Class< * @return target element's locator */ protected By generateXpathLocator(By multipleElementsLocator, WebElement webElement, int elementIndex) { - Class supportedLocatorType = ByXPath.class; - if (multipleElementsLocator.getClass().equals(supportedLocatorType)) { + if (isLocatorSupportedForXPathExtraction(multipleElementsLocator)) { return By.xpath( - String.format("(%1$s)[%2$s]", multipleElementsLocator.toString().substring(XPATH_SUBSTRING_BEGIN_INDEX), elementIndex)); + String.format("(%1$s)[%2$s]", extractXPathFromLocator(multipleElementsLocator), 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)); + "Cannot define unique baseLocator for element %1$s. Multiple elements' baseLocator type %2$s is not supported yet", + webElement.toString(), multipleElementsLocator.getClass())); + } + + /** + * Extracts XPath from passed locator. + * Current implementation works only with ByXPath.class and ByTagName locator types, + * but you can implement your own for the specific WebDriver type. + * + * @param locator locator to get xpath from. + * @return extracted XPath. + */ + protected String extractXPathFromLocator(By locator) { + Class supportedLocatorType = ByXPath.class; + if (locator.getClass().equals(supportedLocatorType)) { + return locator.toString().substring(XPATH_SUBSTRING_BEGIN_INDEX); + } + if (locator.getClass().equals(ByTagName.class)){ + return TAGNAME_XPATH_PREFIX + locator.toString().substring(TAGNAME_SUBSTRING_BEGIN_INDEX); + } + throw new InvalidArgumentException(String.format( + "Cannot define xpath from locator %1$s. Locator type %2$s is not %3$s, and is not supported yet", + locator.toString(), locator.getClass(), supportedLocatorType)); + } + + /** + * Generates absolute child locator for target element. + * + * @param parentLoc parent locator + * @param childLoc child locator relative to parent + * @return absolute locator of the child + */ + protected By generateAbsoluteChildLocator(By parentLoc, By childLoc) { + if (isLocatorSupportedForXPathExtraction(parentLoc) && isLocatorSupportedForXPathExtraction(childLoc)) { + String childLocString = extractXPathFromLocator(childLoc); + String parentLocString = extractXPathFromLocator(parentLoc); + return By.xpath(parentLocString.concat( + childLocString.startsWith(".") ? childLocString.substring(1) : childLocString)); + } + return new ByChained(parentLoc, childLoc); + } + + /** + * Defines is the locator can be transformed to xpath or not. + * Current implementation works only with ByXPath.class and ByTagName locator types, + * but you can implement your own for the specific WebDriver type. + * + * @param locator locator to transform + * @return true if the locator can be transformed to xpath, false otherwise. + */ + protected boolean isLocatorSupportedForXPathExtraction(By locator) { + return locator.getClass().equals(ByXPath.class) || locator.getClass().equals(ByTagName.class); } /** diff --git a/src/main/java/aquality/selenium/core/elements/interfaces/IElementFactory.java b/src/main/java/aquality/selenium/core/elements/interfaces/IElementFactory.java index 63e09bf..1ab32d8 100644 --- a/src/main/java/aquality/selenium/core/elements/interfaces/IElementFactory.java +++ b/src/main/java/aquality/selenium/core/elements/interfaces/IElementFactory.java @@ -76,7 +76,7 @@ T findChildElement(IElement parentElement, By childLoc, Str Class clazz, ElementState state); /** - * Finds child element in any state by its locator relative to parent element. + * Finds displayed 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. @@ -87,7 +87,7 @@ T findChildElement(IElement parentElement, By childLoc, Str */ default T findChildElement(IElement parentElement, By childLoc, String name, Class clazz) { - return findChildElement(parentElement, childLoc, name, clazz, ElementState.EXISTS_IN_ANY_STATE); + return findChildElement(parentElement, childLoc, name, clazz, ElementState.DISPLAYED); } /** @@ -177,6 +177,239 @@ default T findChildElement(IElement parentElement, By child return findChildElement(parentElement, childLoc, supplier, ElementState.EXISTS_IN_ANY_STATE); } + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param clazz Class or interface of the elements to be obtained. + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, + Class clazz) { + return findChildElements(parentElement, childLoc, clazz, ElementsCount.ANY); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param clazz Class or interface of the elements to be obtained. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, + Class clazz, ElementsCount count) { + return findChildElements(parentElement, childLoc, clazz, count, ElementState.DISPLAYED); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param clazz Class or interface of the elements to be obtained. + * @param state Visibility state of child elements. + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, + Class clazz, + ElementState state) { + return findChildElements(parentElement, childLoc, clazz, ElementsCount.ANY, state); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param clazz Class or interface of the elements to be obtained. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @param state Visibility state of child elements. + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, + Class clazz, ElementsCount count, + ElementState state) { + return findChildElements(parentElement, childLoc, null, clazz, count, state); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param name Child elements name. + * @param clazz Class or interface of the elements to be obtained. + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, String name, + Class clazz) { + return findChildElements(parentElement, childLoc, name, clazz, ElementsCount.ANY); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param name Child elements name. + * @param clazz Class or interface of the elements to be obtained. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, String name, + Class clazz, ElementsCount count) { + return findChildElements(parentElement, childLoc, name, clazz, count, ElementState.DISPLAYED); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param name Child elements name. + * @param clazz Class or interface of the elements to be obtained. + * @param state Visibility state of child elements. + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, String name, + Class clazz, ElementState state) { + return findChildElements(parentElement, childLoc, name, clazz, ElementsCount.ANY, state); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param clazz Class or interface of the elements to be obtained. + * @param name Child elements name. + * @param parentElement Parent element for relative search of child elements. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @param state Visibility state of target elements. + * @param Type of the target elements. + * @return List of child elements. + */ + List findChildElements(IElement parentElement, By childLoc, String name, Class clazz, + ElementsCount count, ElementState state); + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param supplier Required elements' supplier. + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, + IElementSupplier supplier) { + return findChildElements(parentElement, childLoc, supplier, ElementsCount.ANY); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param supplier Required elements' supplier. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, + IElementSupplier supplier, ElementsCount count) { + return findChildElements(parentElement, childLoc, supplier, count, ElementState.DISPLAYED); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param supplier Required elements' supplier. + * @param state Visibility state of child elements. + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, + IElementSupplier supplier, + ElementState state) { + return findChildElements(parentElement, childLoc, supplier, ElementsCount.ANY, state); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @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 child elements. + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, + IElementSupplier supplier, ElementsCount count, + ElementState state) { + return findChildElements(parentElement, childLoc, null, supplier, count, state); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param name Child elements name. + * @param supplier Required elements' supplier. + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, String name, + IElementSupplier supplier) { + return findChildElements(parentElement, childLoc, name, supplier, ElementsCount.ANY); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param name Child elements name. + * @param supplier Required elements' supplier. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, String name, + IElementSupplier supplier, ElementsCount count) { + return findChildElements(parentElement, childLoc, name, supplier, count, ElementState.DISPLAYED); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param name Child elements name. + * @param supplier Required elements' supplier. + * @param state Visibility state of child elements. + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, String name, + IElementSupplier supplier, ElementState state) { + return findChildElements(parentElement, childLoc, name, supplier, ElementsCount.ANY, state); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param supplier Required elements' supplier. + * @param name Child elements name. + * @param parentElement Parent element for relative search of child elements. + * @param state Visibility state of child elements. + * @param Type of the target elements. + * @return List of child elements. + */ + List findChildElements(IElement parentElement, By childLoc, String name, + IElementSupplier supplier, ElementsCount count, ElementState state); + /** * Find list of elements. * @@ -191,6 +424,62 @@ default T findChildElement(IElement parentElement, By child List findElements(By locator, String name, IElementSupplier supplier, ElementsCount count, ElementState state); + /** + * Find list of elements. + * + * @param locator Elements selector. + * @param name Child element name. + * @param supplier Required elements' supplier. + * @param state Visibility state of target elements. + * @param Type of the target element. + * @return List of elements. + */ + default List findElements(By locator, String name, IElementSupplier supplier, + ElementState state) { + return findElements(locator, name, supplier, ElementsCount.ANY, state); + } + + /** + * Find list of elements. + * + * @param locator Elements selector. + * @param supplier Required elements' supplier. + * @param state Visibility state of target elements. + * @param Type of the target element. + * @return List of elements. + */ + default List findElements(By locator, IElementSupplier supplier, + ElementState state) { + return findElements(locator, null, supplier, state); + } + + /** + * Find list of displayed 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 Type of the target element. + * @return List of elements. + */ + default List findElements(By locator, String name, IElementSupplier supplier, ElementsCount count) { + return findElements(locator, name, supplier, count, ElementState.DISPLAYED); + } + + /** + * Find list of displayed elements. + * + * @param locator Elements selector. + * @param name Child element name. + * @param supplier Required elements' supplier. + * @param Type of the target element. + * @return List of elements. + */ + default List findElements(By locator, String name, IElementSupplier supplier) { + return findElements(locator, name, supplier, ElementsCount.ANY); + } + /** * Find list of elements. * @@ -213,19 +502,33 @@ default List findElements(By locator, IElementSupplier Type of the target element. * @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 name Child element name. + * @param clazz Class or interface of the element to be obtained. + * @param state Visibility state of target elements. + * @param Type of the target element. + * @return List of elements. + */ + default List findElements(By locator, String name, Class clazz, ElementState state) { + return findElements(locator, name, clazz, ElementsCount.ANY, 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). - * @param state Visibility state of target elements. + * @param state Visibility state of target elements. * @param Type of the target element. * @return List of elements. */ @@ -233,6 +536,19 @@ default List findElements(By locator, Class clazz, El return findElements(locator, null, clazz, count, state); } + /** + * Find list of elements. + * + * @param locator Elements selector. + * @param clazz Class or interface of the element to be obtained. + * @param state Visibility state of target elements. + * @param Type of the target element. + * @return List of elements. + */ + default List findElements(By locator, Class clazz, ElementState state) { + return findElements(locator, null, clazz, ElementsCount.ANY, state); + } + /** * Find list of elements. * diff --git a/src/main/java/aquality/selenium/core/elements/interfaces/IParent.java b/src/main/java/aquality/selenium/core/elements/interfaces/IParent.java index 58857a3..5203f9f 100644 --- a/src/main/java/aquality/selenium/core/elements/interfaces/IParent.java +++ b/src/main/java/aquality/selenium/core/elements/interfaces/IParent.java @@ -1,8 +1,11 @@ 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; + public interface IParent { /** @@ -104,4 +107,209 @@ default T findChildElement(By childLoc, IElementSupplier default T findChildElement(By childLoc, IElementSupplier supplier) { return findChildElement(childLoc, null, supplier, ElementState.DISPLAYED); } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param clazz Class or interface of the elements to be obtained. + * @return List of child elements. + */ + default List findChildElements(By childLoc, Class clazz) { + return findChildElements(childLoc, clazz, ElementsCount.ANY); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param clazz Class or interface of the elements to be obtained. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of child elements. + */ + default List findChildElements(By childLoc, Class clazz, ElementsCount count) { + return findChildElements(childLoc, clazz, ElementState.DISPLAYED, count); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param clazz Class or interface of the elements to be obtained. + * @param state Visibility state of child elements. + * @return List of child elements. + */ + default List findChildElements(By childLoc, Class clazz, ElementState state) { + return findChildElements(childLoc, clazz, state, ElementsCount.ANY); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param clazz Class or interface of the elements to be obtained. + * @param state Visibility state of child elements. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of child elements. + */ + default List findChildElements(By childLoc, Class clazz, ElementState state, + ElementsCount count) { + return findChildElements(childLoc, null, clazz, state, count); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param name Child elements name. + * @param clazz Class or interface of the elements to be obtained. + * @return List of child elements. + */ + default List findChildElements(By childLoc, String name, Class clazz) { + return findChildElements(childLoc, name, clazz, ElementsCount.ANY); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param name Child elements name. + * @param clazz Class or interface of the elements to be obtained. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of child elements. + */ + default List findChildElements(By childLoc, String name, Class clazz, ElementsCount count) { + return findChildElements(childLoc, name, clazz, ElementState.DISPLAYED, count); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param name Child elements name. + * @param clazz Class or interface of the elements to be obtained. + * @param state Visibility state of child elements. + * @return List of child elements. + */ + default List findChildElements(By childLoc, String name, Class clazz, ElementState state) { + return findChildElements(childLoc, name, clazz, state, ElementsCount.ANY); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param Type of the target elements. + * @param childLoc Locator of child elements relative to its parent. + * @param name Child elements name. + * @param clazz Class or interface of the elements to be obtained. + * @param state Visibility state of target elements. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of child elements. + */ + List findChildElements(By childLoc, String name, Class clazz, ElementState state, + ElementsCount count); + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param supplier Required elements' supplier. + * @return List of child elements. + */ + default List findChildElements(By childLoc, IElementSupplier supplier) { + return findChildElements(childLoc, supplier, ElementsCount.ANY); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param supplier Required elements' supplier. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of child elements. + */ + default List findChildElements(By childLoc, IElementSupplier supplier, + ElementsCount count) { + return findChildElements(childLoc, supplier, ElementState.DISPLAYED, count); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param supplier Required elements' supplier. + * @param state Visibility state of child elements. + * @return List of child elements. + */ + default List findChildElements(By childLoc, IElementSupplier supplier, + ElementState state) { + return findChildElements(childLoc, supplier, state, ElementsCount.ANY); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param supplier Required elements' supplier. + * @param state Visibility state of child elements. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of child elements. + */ + default List findChildElements(By childLoc, IElementSupplier supplier, ElementState state, + ElementsCount count) { + return findChildElements(childLoc, null, supplier, state, count); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param name Child elements name. + * @param supplier Required elements' supplier. + * @return List of child elements. + */ + default List findChildElements(By childLoc, String name, IElementSupplier supplier) { + return findChildElements(childLoc, name, supplier, ElementsCount.ANY); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param name Child elements name. + * @param supplier Required elements' supplier. + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of child elements. + */ + default List findChildElements(By childLoc, String name, IElementSupplier supplier, + ElementsCount count) { + return findChildElements(childLoc, name, supplier, ElementState.DISPLAYED, count); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param name Child elements name. + * @param supplier Required elements' supplier. + * @param state Visibility state of child elements. + * @return List of child elements. + */ + default List findChildElements(By childLoc, String name, IElementSupplier supplier, + ElementState state) { + return findChildElements(childLoc, name, supplier, state, ElementsCount.ANY); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param Type of the target elements. + * @param childLoc Locator of child elements relative to its parent. + * @param name Child elements name. + * @param supplier Required elements' supplier. + * @param state Visibility state of child elements. + * @return List of child elements. + */ + List findChildElements(By childLoc, String name, IElementSupplier supplier, + ElementState state, ElementsCount count); } diff --git a/src/test/java/tests/applications/windowsApp/CalculatorWindow.java b/src/test/java/tests/applications/windowsApp/CalculatorWindow.java index 9a49340..829e408 100644 --- a/src/test/java/tests/applications/windowsApp/CalculatorWindow.java +++ b/src/test/java/tests/applications/windowsApp/CalculatorWindow.java @@ -17,6 +17,10 @@ public static CustomElement getWindowLabel() { return new CustomElement(getWindowLocator(), "Window", ElementState.DISPLAYED); } + public static CustomElement getWindowByXPathLabel() { + return new CustomElement(By.xpath("//Window"), "Window", ElementState.DISPLAYED); + } + public static By getOneButtonLoc() { return By.name("1"); } @@ -41,6 +45,18 @@ public static By getEqualsButtonByXPath() { return By.xpath("//*[@Name='=']"); } + public static By getRelativeXPathLocator() { + return By.xpath("//*[@Name='=']"); + } + + public static By getDottedXPathLocator() { + return By.xpath("//*[@Name='=']/parent::Window"); + } + + public static By getTagNameLocator() { + return By.tagName("Button"); + } + public static By getResultsLabelLoc() { return MobileBy.AccessibilityId("48"); } diff --git a/src/test/java/tests/elements/factory/ElementFactoryTests.java b/src/test/java/tests/elements/factory/ElementFactoryTests.java index 8a221d2..7df2455 100644 --- a/src/test/java/tests/elements/factory/ElementFactoryTests.java +++ b/src/test/java/tests/elements/factory/ElementFactoryTests.java @@ -5,46 +5,22 @@ 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 aquality.selenium.core.elements.interfaces.IElementSupplier; 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.applications.windowsApp.AqualityServices; import tests.applications.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; +import java.util.List; - private CustomElementFactory customFactory() { - return new CustomElementFactory(AqualityServices.get(IConditionalWait.class), - AqualityServices.get(IElementFinder.class), AqualityServices.get(ILocalizationManager.class)); - } +public class ElementFactoryTests implements ITestWithApplication, IFindElementsTests { 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"); } @@ -64,72 +40,11 @@ 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.getEqualsButtonLoc(), ICustomElement.class, ElementsCount.MORE_THEN_ZERO)); - } - @Test public void shouldThrowIllegalArgumentExceptionInFindElementsElementTypeIsUnknown() { Assert.assertThrows(IllegalArgumentException.class, () -> defaultFactory().findElements(CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class)); @@ -204,4 +119,54 @@ public IApplication getApplication() { public boolean isApplicationStarted() { return AqualityServices.isApplicationStarted(); } + + @Override + public List findElements(By locator, Class clazz, ElementsCount count) { + return customFactory().findElements(locator, clazz, count); + } + + @Override + public List findElements(By locator, String name, Class clazz, ElementState state) { + return customFactory().findElements(locator, name, clazz, state); + } + + @Override + public List findElements(By locator, Class clazz, ElementState state) { + return customFactory().findElements(locator, clazz, state); + } + + @Override + public List findElements(By locator, Class clazz) { + return customFactory().findElements(locator, clazz); + } + + @Override + public List findElements(By locator, String name, Class clazz) { + return customFactory().findElements(locator, name, clazz); + } + + @Override + public List findElements(By locator, String name, IElementSupplier supplier, ElementsCount count, ElementState state) { + return customFactory().findElements(locator, name, supplier, count, state); + } + + @Override + public List findElements(By locator, String name, IElementSupplier supplier, ElementState state) { + return customFactory().findElements(locator, name, supplier, state); + } + + @Override + public List findElements(By locator, IElementSupplier supplier, ElementState state) { + return customFactory().findElements(locator, supplier, state); + } + + @Override + public List findElements(By locator, String name, IElementSupplier supplier) { + return customFactory().findElements(locator, name, supplier); + } + + @Override + public List findElements(By locator, IElementSupplier supplier, ElementsCount count, ElementState state) { + return customFactory().findElements(locator, supplier, count, state); + } } diff --git a/src/test/java/tests/elements/factory/FindChildElementsTests.java b/src/test/java/tests/elements/factory/FindChildElementsTests.java new file mode 100644 index 0000000..f5e3642 --- /dev/null +++ b/src/test/java/tests/elements/factory/FindChildElementsTests.java @@ -0,0 +1,93 @@ +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.IElementSupplier; +import org.openqa.selenium.By; +import org.testng.Assert; +import org.testng.annotations.Test; +import tests.ITestWithApplication; +import tests.applications.windowsApp.AqualityServices; +import tests.applications.windowsApp.CalculatorWindow; + +import java.util.List; + +public class FindChildElementsTests implements ITestWithApplication, IFindElementsTests { + + @Override + public IApplication getApplication() { + return AqualityServices.getApplication(); + } + + @Override + public boolean isApplicationStarted() { + return AqualityServices.isApplicationStarted(); + } + + private IElement getParent() { + return CalculatorWindow.getWindowByXPathLabel(); + } + + @Override + public List findElements(By locator, Class clazz, ElementsCount count) { + return customFactory().findChildElements(getParent(), locator, clazz, count); + } + + @Override + public List findElements(By locator, String name, Class clazz, ElementState state) { + return customFactory().findChildElements(getParent(), locator, name, clazz, state); + } + + @Override + public List findElements(By locator, Class clazz, ElementState state) { + return customFactory().findChildElements(getParent(), locator, clazz, state); + } + + @Override + public List findElements(By locator, Class clazz) { + return customFactory().findChildElements(getParent(), locator, clazz); + } + + @Override + public List findElements(By locator, String name, Class clazz) { + return customFactory().findChildElements(getParent(), locator, name, clazz); + } + + @Override + public List findElements(By locator, String name, IElementSupplier supplier, ElementsCount count, ElementState state) { + return customFactory().findChildElements(getParent(), locator, name, supplier, count, state); + } + + @Override + public List findElements(By locator, String name, IElementSupplier supplier, ElementState state) { + return customFactory().findChildElements(getParent(), locator, name, supplier, state); + } + + @Override + public List findElements(By locator, IElementSupplier supplier, ElementState state) { + return customFactory().findChildElements(getParent(), locator, supplier, state); + } + + @Override + public List findElements(By locator, String name, IElementSupplier supplier) { + return customFactory().findChildElements(getParent(), locator, name, supplier); + } + + @Override + public List findElements(By locator, IElementSupplier supplier, ElementsCount count, ElementState state) { + return customFactory().findChildElements(getParent(), locator, supplier, count, state); + } + + @Test + public void testShouldBePossibleToWorkWithElementsFoundBySpecificLocatorOfParent() { + List elements = customFactory().findChildElements( + CalculatorWindow.getWindowLabel(), + CalculatorWindow.getEqualsButtonByXPath(), + CustomElement::new); + Assert.assertFalse(elements.isEmpty()); + Assert.assertEquals(elements.stream().map(IElement::getElement).toArray().length, elements.size(), + "elements count not match to expected"); + } +} diff --git a/src/test/java/tests/elements/factory/IFindElementsTests.java b/src/test/java/tests/elements/factory/IFindElementsTests.java new file mode 100644 index 0000000..1f418e2 --- /dev/null +++ b/src/test/java/tests/elements/factory/IFindElementsTests.java @@ -0,0 +1,153 @@ +package tests.elements.factory; + +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.IElementFinder; +import aquality.selenium.core.elements.interfaces.IElementSupplier; +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.DataProvider; +import org.testng.annotations.Test; +import tests.applications.windowsApp.AqualityServices; +import tests.applications.windowsApp.CalculatorWindow; + +import java.util.ArrayList; +import java.util.List; + +public interface IFindElementsTests { + String CONDITION_TIMEOUT_KEY = "timeouts.timeoutCondition"; + String NEW_TIMEOUT_VALUE = "5"; + int XPATH_SUBSTRING_BEGIN_INDEX = 10; + + List findElements(By locator, Class clazz, ElementsCount count); + + List findElements(By locator, String name, Class clazz, ElementState state); + + List findElements(By locator, Class clazz, ElementState state); + + List findElements(By locator, Class clazz); + + List findElements(By locator, String name, Class clazz); + + List findElements(By locator, String name, IElementSupplier supplier, ElementsCount count, + ElementState state); + + List findElements(By locator, String name, IElementSupplier supplier, ElementState state); + + List findElements(By locator, IElementSupplier supplier, ElementState state); + + List findElements(By locator, String name, IElementSupplier supplier); + + List findElements(By locator, IElementSupplier supplier, ElementsCount count, + ElementState state); + + default CustomElementFactory customFactory() { + return new CustomElementFactory(AqualityServices.get(IConditionalWait.class), + AqualityServices.get(IElementFinder.class), AqualityServices.get(ILocalizationManager.class)); + } + + @Test(dataProvider = "getSupportedLocators") + default void testShouldBePossibleToWorkWithElementsFoundBySpecificLocator(By locator) { + List elements = findElements(locator, "some elements", CustomElement::new, ElementState.EXISTS_IN_ANY_STATE); + Assert.assertFalse(elements.isEmpty()); + Assert.assertEquals(elements.stream().map(IElement::getElement).toArray().length, elements.size(), + "elements count not match to expected"); + } + + @DataProvider + default Object[] getSupportedLocators() { + List locators = new ArrayList<>(); + locators.add(CalculatorWindow.getDottedXPathLocator()); + locators.add(CalculatorWindow.getTagNameLocator()); + locators.add(CalculatorWindow.getRelativeXPathLocator()); + return locators.toArray(); + } + + @Test + default void shouldBePossibleToFindCustomElementsViaCustomFactory() { + Assert.assertTrue(findElements(CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class).size() > 1); + } + + @Test + default void shouldBePossibleToFindCustomElementsViaCustomFactoryWithCustomElementsCount() { + Assert.assertTrue(findElements(CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class, ElementsCount.MORE_THEN_ZERO).size() > 1); + } + + @Test + default void shouldBePossibleToFindCustomElementsViaSupplierWithDefaultName() { + Assert.assertTrue(findElements( + CalculatorWindow.getEqualsButtonByXPath(), CustomElement::new, ElementsCount.MORE_THEN_ZERO, + ElementState.EXISTS_IN_ANY_STATE).size() > 1); + } + + @Test + default void shouldBePossibleToFindCustomElementsViaSupplierWithCustomName() { + String customName = "56789"; + Assert.assertTrue(findElements( + CalculatorWindow.getEqualsButtonByXPath(), customName, CustomElement::new) + .get(0).getName().contains(customName)); + } + + @Test + default void shouldBePossibleToFindCustomElementsViaSupplierWithoutName() { + Assert.assertFalse(findElements( + CalculatorWindow.getEqualsButtonByXPath(), CustomElement::new, ElementState.EXISTS_IN_ANY_STATE) + .get(0).getName().isEmpty()); + } + + @Test + default void shouldBePossibleToFindCustomElementsViaSupplierWithCustomState() { + Assert.assertEquals(findElements( + CalculatorWindow.getEqualsButtonByXPath(), "equals", CustomElement::new, ElementsCount.ANY, ElementState.EXISTS_IN_ANY_STATE) + .get(0).getState(), ElementState.EXISTS_IN_ANY_STATE); + } + + @Test + default void shouldBePossibleToFindCustomElementsViaCustomFactoryWithDefaultElementsCount() { + Assert.assertTrue(findElements(CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class, ElementState.EXISTS_IN_ANY_STATE).size() > 1); + } + + @Test + default void shouldSetCorrectParametersWhenFindElements() { + String customName = "asd"; + ICustomElement element = 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 + default void shouldBePossibleToFindCustomElementsViaCustomFactoryWithZeroElementsCount() { + Assert.assertTrue(findElements(By.xpath("//any"), ICustomElement.class, ElementsCount.ANY).isEmpty()); + } + + @Test(groups = "timeout") + default void shouldThrowTimeoutExceptionWhenCountIsNotExpected() { + Assert.assertThrows(TimeoutException.class, () -> findElements(CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class, ElementsCount.ZERO)); + } + + @Test + default void shouldThrowInvalidArgumentExceptionInFindElementsWhenLocatorIsNotSupported() { + Assert.assertThrows(InvalidArgumentException.class, + () -> findElements(CalculatorWindow.getEqualsButtonLoc(), "equals", ICustomElement.class, ElementState.EXISTS_IN_ANY_STATE)); + } + + @BeforeGroups("timeout") + default void setupTimeout() { + System.setProperty(CONDITION_TIMEOUT_KEY, NEW_TIMEOUT_VALUE); + AqualityServices.resetInjector(); + } + + @AfterGroups("timeout") + default void resetTimeout() { + System.clearProperty(CONDITION_TIMEOUT_KEY); + AqualityServices.resetInjector(); + } +}