From 4c72a4124b0983a8c01e745ffbc917555be15510 Mon Sep 17 00:00:00 2001 From: "Meleshko, Aleksey2" Date: Thu, 21 May 2020 12:07:22 +0300 Subject: [PATCH 1/9] Implemented findChildElements with all overloads --- .../core/elements/ElementFactory.java | 13 + .../elements/interfaces/IElementFactory.java | 241 +++++++++++++++++- 2 files changed, 250 insertions(+), 4 deletions(-) diff --git a/src/main/java/aquality/selenium/core/elements/ElementFactory.java b/src/main/java/aquality/selenium/core/elements/ElementFactory.java index 357aabb..4e4e4af 100644 --- a/src/main/java/aquality/selenium/core/elements/ElementFactory.java +++ b/src/main/java/aquality/selenium/core/elements/ElementFactory.java @@ -63,6 +63,19 @@ public T findChildElement(IElement parentElement, By childL 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 = new ByChained(parentElement.getLocator(), childLoc); + return findElements(fullLocator, childName, supplier, count, state); + } + @Override public List findElements(By locator, String name, IElementSupplier supplier, ElementsCount count, ElementState state) { 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..9cb7657 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. * @@ -213,7 +446,7 @@ default List findElements(By locator, IElementSupplier Type of the target element. * @return List of elements. */ @@ -225,7 +458,7 @@ default List findElements(By locator, IElementSupplier Type of the target element. * @return List of elements. */ From 2d802fd3342c4ac2117f4c368123809ff292c166 Mon Sep 17 00:00:00 2001 From: "Meleshko, Aleksey2" Date: Thu, 21 May 2020 12:22:12 +0300 Subject: [PATCH 2/9] Add findChildElements methods to IParent and Element with all overloads --- .../selenium/core/elements/Element.java | 11 + .../core/elements/interfaces/IParent.java | 220 ++++++++++++++++++ 2 files changed, 231 insertions(+) diff --git a/src/main/java/aquality/selenium/core/elements/Element.java b/src/main/java/aquality/selenium/core/elements/Element.java index 7a11dec..6b53f4c 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, ElementsCount count, ElementState state) { + return getElementFactory().findChildElements(this, childLoc, name, clazz, count, state); + } + + @Override + public List findChildElements(By childLoc, String name, IElementSupplier supplier, ElementsCount count, ElementState state) { + 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/interfaces/IParent.java b/src/main/java/aquality/selenium/core/elements/interfaces/IParent.java index 58857a3..b8ce07f 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,221 @@ 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, count, ElementState.DISPLAYED); + } + + /** + * 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, 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 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(By childLoc, + Class clazz, ElementsCount count, + ElementState state) { + return findChildElements(childLoc, null, clazz, count, state); + } + + /** + * 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, count, ElementState.DISPLAYED); + } + + /** + * 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, 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 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(By childLoc, String name, Class clazz, + ElementsCount count, ElementState state); + + /** + * 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, count, ElementState.DISPLAYED); + } + + /** + * 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, 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 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(By childLoc, + IElementSupplier supplier, ElementsCount count, + ElementState state) { + return findChildElements(childLoc, null, supplier, count, state); + } + + /** + * 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, count, ElementState.DISPLAYED); + } + + /** + * 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, 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 state Visibility state of child elements. + * @param Type of the target elements. + * @return List of child elements. + */ + List findChildElements(By childLoc, String name, + IElementSupplier supplier, ElementsCount count, ElementState state); } From 149e79072353e9a20d17141046ae1901c5dd927e Mon Sep 17 00:00:00 2001 From: "Meleshko, Aleksey2" Date: Thu, 21 May 2020 13:54:04 +0300 Subject: [PATCH 3/9] Implement findChildElements tests for WinAppDriver-based factory --- .../windowsApp/CalculatorWindow.java | 4 + .../factory/CustomElementFactory.java | 27 ++++ .../elements/factory/ElementFactoryTests.java | 113 +++++------------ .../factory/FindChildElementsTests.java | 55 +++++++++ .../elements/factory/IFindElementsTests.java | 116 ++++++++++++++++++ 5 files changed, 230 insertions(+), 85 deletions(-) create mode 100644 src/test/java/tests/elements/factory/FindChildElementsTests.java create mode 100644 src/test/java/tests/elements/factory/IFindElementsTests.java diff --git a/src/test/java/tests/applications/windowsApp/CalculatorWindow.java b/src/test/java/tests/applications/windowsApp/CalculatorWindow.java index 9a49340..f9d48b7 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"); } diff --git a/src/test/java/tests/elements/factory/CustomElementFactory.java b/src/test/java/tests/elements/factory/CustomElementFactory.java index b3bb37c..a07146e 100644 --- a/src/test/java/tests/elements/factory/CustomElementFactory.java +++ b/src/test/java/tests/elements/factory/CustomElementFactory.java @@ -1,15 +1,23 @@ package tests.elements.factory; import aquality.selenium.core.elements.ElementFactory; +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.By.ByXPath; +import org.openqa.selenium.InvalidArgumentException; import java.util.HashMap; +import java.util.List; import java.util.Map; public class CustomElementFactory extends ElementFactory { + private static final int XPATH_SUBSTRING_BEGIN_INDEX = 10; CustomElementFactory(IConditionalWait conditionalWait, IElementFinder elementFinder, ILocalizationManager localizationManager) { super(conditionalWait, elementFinder, localizationManager); } @@ -20,5 +28,24 @@ protected Map, Class> getElementTy typesMap.put(ICustomElement.class, CustomElement.class); return typesMap; } + + @Override + public List findChildElements(IElement parentElement, By childLoc, String name, + IElementSupplier supplier, ElementsCount count, + ElementState state) { + By fullLocator = By.xpath( + extractXPathFromLocator(parentElement.getLocator()).concat(extractXPathFromLocator(childLoc))); + return findElements(fullLocator, name, supplier, count, state); + } + + private String extractXPathFromLocator(By locator) { + Class supportedLocatorType = ByXPath.class; + if (locator.getClass().equals(supportedLocatorType)) { + return locator.toString().substring(XPATH_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)); + } } diff --git a/src/test/java/tests/elements/factory/ElementFactoryTests.java b/src/test/java/tests/elements/factory/ElementFactoryTests.java index 8a221d2..904bfe1 100644 --- a/src/test/java/tests/elements/factory/ElementFactoryTests.java +++ b/src/test/java/tests/elements/factory/ElementFactoryTests.java @@ -6,45 +6,24 @@ 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.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.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 +43,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 +122,29 @@ 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, 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, 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..7dd0819 --- /dev/null +++ b/src/test/java/tests/elements/factory/FindChildElementsTests.java @@ -0,0 +1,55 @@ +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 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, 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, IElementSupplier supplier, ElementsCount count, ElementState state) { + return customFactory().findChildElements(getParent(), locator, supplier, count, state); + } +} 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..680ff57 --- /dev/null +++ b/src/test/java/tests/elements/factory/IFindElementsTests.java @@ -0,0 +1,116 @@ +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.Test; +import tests.applications.windowsApp.AqualityServices; +import tests.applications.windowsApp.CalculatorWindow; + +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, 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, 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 + 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, ElementsCount.MORE_THEN_ZERO, + ElementState.EXISTS_IN_ANY_STATE).get(0).getName().contains(customName)); + } + + @Test + default void shouldBePossibleToFindCustomElementsViaSupplierWithCustomState() { + Assert.assertEquals(findElements( + CalculatorWindow.getEqualsButtonByXPath(), CustomElement::new, ElementsCount.MORE_THEN_ZERO, + ElementState.EXISTS_IN_ANY_STATE).get(0).getState(), ElementState.EXISTS_IN_ANY_STATE); + } + + @Test + default void shouldBePossibleToFindCustomElementsViaCustomFactoryWithDefaultElementsCount() { + Assert.assertTrue(findElements(CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class, ElementsCount.ANY).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(), ICustomElement.class, ElementsCount.MORE_THEN_ZERO)); + } + + @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(); + } +} From c6cbec968563aa48e02f0268f693ace817704661 Mon Sep 17 00:00:00 2001 From: "Meleshko, Aleksey2" Date: Thu, 21 May 2020 14:28:33 +0300 Subject: [PATCH 4/9] Implement dotted locator test --- .../tests/applications/windowsApp/CalculatorWindow.java | 4 ++++ .../java/tests/elements/factory/IFindElementsTests.java | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/test/java/tests/applications/windowsApp/CalculatorWindow.java b/src/test/java/tests/applications/windowsApp/CalculatorWindow.java index f9d48b7..253a767 100644 --- a/src/test/java/tests/applications/windowsApp/CalculatorWindow.java +++ b/src/test/java/tests/applications/windowsApp/CalculatorWindow.java @@ -45,6 +45,10 @@ public static By getEqualsButtonByXPath() { return By.xpath("//*[@Name='=']"); } + public static By getDottedXPathLocator() { + return By.xpath("//*[@Name='=']/parent::Window"); + } + public static By getResultsLabelLoc() { return MobileBy.AccessibilityId("48"); } diff --git a/src/test/java/tests/elements/factory/IFindElementsTests.java b/src/test/java/tests/elements/factory/IFindElementsTests.java index 680ff57..2878da8 100644 --- a/src/test/java/tests/elements/factory/IFindElementsTests.java +++ b/src/test/java/tests/elements/factory/IFindElementsTests.java @@ -41,6 +41,14 @@ default CustomElementFactory customFactory() { AqualityServices.get(IElementFinder.class), AqualityServices.get(ILocalizationManager.class)); } + @Test + default void testShouldBePossibleToWorkWithElementsFoundByDottedLocator(){ + List elements = findElements(CalculatorWindow.getDottedXPathLocator(), ICustomElement.class); + Assert.assertFalse(elements.isEmpty()); + Assert.assertEquals(elements.stream().map(IElement::getElement).toArray().length, elements.size(), + "elements count not match to expected"); + } + @Test default void shouldBePossibleToFindCustomElementsViaCustomFactory() { Assert.assertTrue(findElements(CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class).size() > 1); From b8b81b772cf404b5ed556c36f397f4a62a06efbd Mon Sep 17 00:00:00 2001 From: "Meleshko, Aleksey2" Date: Thu, 21 May 2020 16:32:32 +0300 Subject: [PATCH 5/9] Implement tests to cover rest of ElementFactory methods, add overloads --- .../core/elements/ElementFactory.java | 64 ++++++++++++-- .../elements/interfaces/IElementFactory.java | 83 +++++++++++++++++++ .../windowsApp/CalculatorWindow.java | 4 + .../factory/CustomElementFactory.java | 27 ------ .../elements/factory/ElementFactoryTests.java | 28 ++++++- .../factory/FindChildElementsTests.java | 40 ++++++++- .../elements/factory/IFindElementsTests.java | 46 ++++++++-- 7 files changed, 245 insertions(+), 47 deletions(-) diff --git a/src/main/java/aquality/selenium/core/elements/ElementFactory.java b/src/main/java/aquality/selenium/core/elements/ElementFactory.java index 4e4e4af..2f86cea 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,7 +62,7 @@ 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); } @@ -72,7 +75,7 @@ public List findChildElements(IElement parentElement, By @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 = new ByChained(parentElement.getLocator(), childLoc); + By fullLocator = generateAbsoluteChildLocator(parentElement.getLocator(), childLoc); return findElements(fullLocator, childName, supplier, count, state); } @@ -132,14 +135,61 @@ 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 (isLocatorSupportedForXPathGeneration(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 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 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 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) { + return isLocatorSupportedForXPathGeneration(parentLoc) + && isLocatorSupportedForXPathGeneration(childLoc) + && !extractXPathFromLocator(childLoc).startsWith(".") + ? By.xpath(extractXPathFromLocator(parentLoc).concat(extractXPathFromLocator(childLoc))) + : 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 isLocatorSupportedForXPathGeneration(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 9cb7657..1ab32d8 100644 --- a/src/main/java/aquality/selenium/core/elements/interfaces/IElementFactory.java +++ b/src/main/java/aquality/selenium/core/elements/interfaces/IElementFactory.java @@ -424,6 +424,62 @@ List findChildElements(IElement parentElement, By childL 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. * @@ -452,6 +508,20 @@ default List findElements(By locator, IElementSupplier 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. * @@ -466,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/test/java/tests/applications/windowsApp/CalculatorWindow.java b/src/test/java/tests/applications/windowsApp/CalculatorWindow.java index 253a767..8f9e91f 100644 --- a/src/test/java/tests/applications/windowsApp/CalculatorWindow.java +++ b/src/test/java/tests/applications/windowsApp/CalculatorWindow.java @@ -49,6 +49,10 @@ 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/CustomElementFactory.java b/src/test/java/tests/elements/factory/CustomElementFactory.java index a07146e..b3bb37c 100644 --- a/src/test/java/tests/elements/factory/CustomElementFactory.java +++ b/src/test/java/tests/elements/factory/CustomElementFactory.java @@ -1,23 +1,15 @@ package tests.elements.factory; import aquality.selenium.core.elements.ElementFactory; -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.By.ByXPath; -import org.openqa.selenium.InvalidArgumentException; import java.util.HashMap; -import java.util.List; import java.util.Map; public class CustomElementFactory extends ElementFactory { - private static final int XPATH_SUBSTRING_BEGIN_INDEX = 10; CustomElementFactory(IConditionalWait conditionalWait, IElementFinder elementFinder, ILocalizationManager localizationManager) { super(conditionalWait, elementFinder, localizationManager); } @@ -28,24 +20,5 @@ protected Map, Class> getElementTy typesMap.put(ICustomElement.class, CustomElement.class); return typesMap; } - - @Override - public List findChildElements(IElement parentElement, By childLoc, String name, - IElementSupplier supplier, ElementsCount count, - ElementState state) { - By fullLocator = By.xpath( - extractXPathFromLocator(parentElement.getLocator()).concat(extractXPathFromLocator(childLoc))); - return findElements(fullLocator, name, supplier, count, state); - } - - private String extractXPathFromLocator(By locator) { - Class supportedLocatorType = ByXPath.class; - if (locator.getClass().equals(supportedLocatorType)) { - return locator.toString().substring(XPATH_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)); - } } diff --git a/src/test/java/tests/elements/factory/ElementFactoryTests.java b/src/test/java/tests/elements/factory/ElementFactoryTests.java index 904bfe1..7df2455 100644 --- a/src/test/java/tests/elements/factory/ElementFactoryTests.java +++ b/src/test/java/tests/elements/factory/ElementFactoryTests.java @@ -5,10 +5,7 @@ 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.elements.interfaces.IElementSupplier; -import aquality.selenium.core.localization.ILocalizationManager; -import aquality.selenium.core.waitings.IConditionalWait; import org.openqa.selenium.By; import org.testng.Assert; import org.testng.annotations.Test; @@ -128,6 +125,16 @@ public List findElements(By locator, Class clazz, Ele 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); @@ -143,6 +150,21 @@ public List findElements(By locator, String name, IEleme 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 index 7dd0819..f5e3642 100644 --- a/src/test/java/tests/elements/factory/FindChildElementsTests.java +++ b/src/test/java/tests/elements/factory/FindChildElementsTests.java @@ -6,13 +6,15 @@ 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 { +public class FindChildElementsTests implements ITestWithApplication, IFindElementsTests { @Override public IApplication getApplication() { @@ -33,6 +35,16 @@ public List findElements(By locator, Class clazz, Ele 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); @@ -48,8 +60,34 @@ public List findElements(By locator, String name, IEleme 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 index 2878da8..6d26c48 100644 --- a/src/test/java/tests/elements/factory/IFindElementsTests.java +++ b/src/test/java/tests/elements/factory/IFindElementsTests.java @@ -13,10 +13,12 @@ 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 { @@ -26,6 +28,10 @@ public interface IFindElementsTests { 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); @@ -33,6 +39,12 @@ public interface IFindElementsTests { 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); @@ -41,14 +53,22 @@ default CustomElementFactory customFactory() { AqualityServices.get(IElementFinder.class), AqualityServices.get(ILocalizationManager.class)); } - @Test - default void testShouldBePossibleToWorkWithElementsFoundByDottedLocator(){ - List elements = findElements(CalculatorWindow.getDottedXPathLocator(), ICustomElement.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()); + return locators.toArray(); + } + @Test default void shouldBePossibleToFindCustomElementsViaCustomFactory() { Assert.assertTrue(findElements(CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class).size() > 1); @@ -70,20 +90,27 @@ default void shouldBePossibleToFindCustomElementsViaSupplierWithDefaultName() { default void shouldBePossibleToFindCustomElementsViaSupplierWithCustomName() { String customName = "56789"; Assert.assertTrue(findElements( - CalculatorWindow.getEqualsButtonByXPath(), customName, CustomElement::new, ElementsCount.MORE_THEN_ZERO, - ElementState.EXISTS_IN_ANY_STATE).get(0).getName().contains(customName)); + 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(), CustomElement::new, ElementsCount.MORE_THEN_ZERO, - ElementState.EXISTS_IN_ANY_STATE).get(0).getState(), ElementState.EXISTS_IN_ANY_STATE); + 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, ElementsCount.ANY).size() > 1); + Assert.assertTrue(findElements(CalculatorWindow.getEqualsButtonByXPath(), ICustomElement.class, ElementState.EXISTS_IN_ANY_STATE).size() > 1); } @Test @@ -107,7 +134,8 @@ default void shouldThrowTimeoutExceptionWhenCountIsNotExpected() { @Test default void shouldThrowInvalidArgumentExceptionInFindElementsWhenLocatorIsNotSupported() { - Assert.assertThrows(InvalidArgumentException.class, () -> findElements(CalculatorWindow.getEqualsButtonLoc(), ICustomElement.class, ElementsCount.MORE_THEN_ZERO)); + Assert.assertThrows(InvalidArgumentException.class, + () -> findElements(CalculatorWindow.getEqualsButtonLoc(), "equals", ICustomElement.class, ElementState.EXISTS_IN_ANY_STATE)); } @BeforeGroups("timeout") From dd0adf9acac4055867c3cce4b13ec2cac6dd04aa Mon Sep 17 00:00:00 2001 From: "Meleshko, Aleksey2" Date: Thu, 21 May 2020 16:40:40 +0300 Subject: [PATCH 6/9] Update package version +semver:feature --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 1de0ac8b28607576bc5437a961f0bd3325a4f8d9 Mon Sep 17 00:00:00 2001 From: "Meleshko, Aleksey2" Date: Thu, 21 May 2020 19:52:17 +0300 Subject: [PATCH 7/9] Reordered findChildElements method parameters --- .../selenium/core/elements/Element.java | 4 +- .../core/elements/interfaces/IParent.java | 192 ++++++++---------- 2 files changed, 92 insertions(+), 104 deletions(-) diff --git a/src/main/java/aquality/selenium/core/elements/Element.java b/src/main/java/aquality/selenium/core/elements/Element.java index 6b53f4c..c520a8e 100644 --- a/src/main/java/aquality/selenium/core/elements/Element.java +++ b/src/main/java/aquality/selenium/core/elements/Element.java @@ -130,12 +130,12 @@ public T findChildElement(By childLoc, String name, IElemen } @Override - public List findChildElements(By childLoc, String name, Class clazz, ElementsCount count, ElementState state) { + 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, ElementsCount count, ElementState state) { + public List findChildElements(By childLoc, String name, IElementSupplier supplier, ElementState state, ElementsCount count) { return getElementFactory().findChildElements(this, childLoc, name, supplier, count, state); } 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 b8ce07f..5203f9f 100644 --- a/src/main/java/aquality/selenium/core/elements/interfaces/IParent.java +++ b/src/main/java/aquality/selenium/core/elements/interfaces/IParent.java @@ -111,217 +111,205 @@ default T findChildElement(By childLoc, IElementSupplier /** * 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 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) { + 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). + * @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, count, ElementState.DISPLAYED); + 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. + * @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, ElementsCount.ANY, state); + 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 count Expected number of elements that have to be found (zero, more then zero, any). - * @param state Visibility state 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. + * @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, - ElementState state) { - return findChildElements(childLoc, null, clazz, count, state); + 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. + * @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) { + 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). + * @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, count, ElementState.DISPLAYED); + 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. + * @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, ElementsCount.ANY, state); + 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 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 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. + * @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, - ElementsCount count, ElementState state); + 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. + * @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) { + 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). + * @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, count, ElementState.DISPLAYED); + 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. + * @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, + default List findChildElements(By childLoc, IElementSupplier supplier, ElementState state) { - return findChildElements(childLoc, supplier, ElementsCount.ANY, 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 count Expected number of elements that have to be found (zero, more then zero, any). - * @param state Visibility state 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. + * @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, - ElementState state) { - return findChildElements(childLoc, null, supplier, count, state); + 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. + * @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) { + 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). + * @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, count, ElementState.DISPLAYED); + 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. + * @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, ElementsCount.ANY, state); + 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 childLoc Locator of child elements relative to its parent. - * @param supplier Required elements' supplier. - * @param name Child elements name. - * @param state Visibility state of child elements. - * @param Type of the target elements. + * @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, ElementsCount count, ElementState state); + List findChildElements(By childLoc, String name, IElementSupplier supplier, + ElementState state, ElementsCount count); } From de7517b41771ec4abd9464f2f13d519a64944a34 Mon Sep 17 00:00:00 2001 From: "Meleshko, Aleksey2" Date: Fri, 22 May 2020 11:56:42 +0300 Subject: [PATCH 8/9] Rename method isLocatorSupportedForXPathGeneration to isLocatorSupportedForXPathExtraction --- .../aquality/selenium/core/elements/ElementFactory.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/aquality/selenium/core/elements/ElementFactory.java b/src/main/java/aquality/selenium/core/elements/ElementFactory.java index 2f86cea..46677ae 100644 --- a/src/main/java/aquality/selenium/core/elements/ElementFactory.java +++ b/src/main/java/aquality/selenium/core/elements/ElementFactory.java @@ -135,7 +135,7 @@ public List findElements(By locator, String name, Class< * @return target element's locator */ protected By generateXpathLocator(By multipleElementsLocator, WebElement webElement, int elementIndex) { - if (isLocatorSupportedForXPathGeneration(multipleElementsLocator)) { + if (isLocatorSupportedForXPathExtraction(multipleElementsLocator)) { return By.xpath( String.format("(%1$s)[%2$s]", extractXPathFromLocator(multipleElementsLocator), elementIndex)); } @@ -173,8 +173,8 @@ protected String extractXPathFromLocator(By locator) { * @return absolute locator of the child */ protected By generateAbsoluteChildLocator(By parentLoc, By childLoc) { - return isLocatorSupportedForXPathGeneration(parentLoc) - && isLocatorSupportedForXPathGeneration(childLoc) + return isLocatorSupportedForXPathExtraction(parentLoc) + && isLocatorSupportedForXPathExtraction(childLoc) && !extractXPathFromLocator(childLoc).startsWith(".") ? By.xpath(extractXPathFromLocator(parentLoc).concat(extractXPathFromLocator(childLoc))) : new ByChained(parentLoc, childLoc); @@ -188,7 +188,7 @@ && isLocatorSupportedForXPathGeneration(childLoc) * @param locator locator to transform * @return true if the locator can be transformed to xpath, false otherwise. */ - protected boolean isLocatorSupportedForXPathGeneration(By locator) { + protected boolean isLocatorSupportedForXPathExtraction(By locator) { return locator.getClass().equals(ByXPath.class) || locator.getClass().equals(ByTagName.class); } From c41517bf9f4e937f95b41c401caffa476eaeae46 Mon Sep 17 00:00:00 2001 From: "Meleshko, Aleksey2" Date: Fri, 22 May 2020 19:00:41 +0300 Subject: [PATCH 9/9] Add xpath generation in generateAbsoluteChildLocator method for relative child locators --- .../selenium/core/elements/ElementFactory.java | 12 +++++++----- .../applications/windowsApp/CalculatorWindow.java | 4 ++++ .../tests/elements/factory/IFindElementsTests.java | 1 + 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/aquality/selenium/core/elements/ElementFactory.java b/src/main/java/aquality/selenium/core/elements/ElementFactory.java index 46677ae..5e843ff 100644 --- a/src/main/java/aquality/selenium/core/elements/ElementFactory.java +++ b/src/main/java/aquality/selenium/core/elements/ElementFactory.java @@ -173,11 +173,13 @@ protected String extractXPathFromLocator(By locator) { * @return absolute locator of the child */ protected By generateAbsoluteChildLocator(By parentLoc, By childLoc) { - return isLocatorSupportedForXPathExtraction(parentLoc) - && isLocatorSupportedForXPathExtraction(childLoc) - && !extractXPathFromLocator(childLoc).startsWith(".") - ? By.xpath(extractXPathFromLocator(parentLoc).concat(extractXPathFromLocator(childLoc))) - : new ByChained(parentLoc, 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); } /** diff --git a/src/test/java/tests/applications/windowsApp/CalculatorWindow.java b/src/test/java/tests/applications/windowsApp/CalculatorWindow.java index 8f9e91f..829e408 100644 --- a/src/test/java/tests/applications/windowsApp/CalculatorWindow.java +++ b/src/test/java/tests/applications/windowsApp/CalculatorWindow.java @@ -45,6 +45,10 @@ 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"); } diff --git a/src/test/java/tests/elements/factory/IFindElementsTests.java b/src/test/java/tests/elements/factory/IFindElementsTests.java index 6d26c48..1f418e2 100644 --- a/src/test/java/tests/elements/factory/IFindElementsTests.java +++ b/src/test/java/tests/elements/factory/IFindElementsTests.java @@ -66,6 +66,7 @@ default Object[] getSupportedLocators() { List locators = new ArrayList<>(); locators.add(CalculatorWindow.getDottedXPathLocator()); locators.add(CalculatorWindow.getTagNameLocator()); + locators.add(CalculatorWindow.getRelativeXPathLocator()); return locators.toArray(); }