diff --git a/pom.xml b/pom.xml index 54fd48a..732aac6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.aquality-automation aquality-selenium - 2.3.1 + 2.4.0 jar Aquality Selenium Library around Selenium WebDriver @@ -73,7 +73,7 @@ com.github.aquality-automation aquality-selenium-core - 1.0.2 + 1.1.0 diff --git a/src/main/java/aquality/selenium/elements/ElementFactory.java b/src/main/java/aquality/selenium/elements/ElementFactory.java index 4a26eee..e22cf52 100644 --- a/src/main/java/aquality/selenium/elements/ElementFactory.java +++ b/src/main/java/aquality/selenium/elements/ElementFactory.java @@ -8,8 +8,11 @@ import aquality.selenium.elements.interfaces.*; import com.google.inject.Inject; import org.openqa.selenium.By; -import org.openqa.selenium.By.ByXPath; +import org.openqa.selenium.By.ByClassName; +import org.openqa.selenium.By.ById; +import org.openqa.selenium.By.ByName; import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ByIdOrName; import java.util.HashMap; import java.util.Map; @@ -21,6 +24,15 @@ public ElementFactory(IConditionalWait conditionalWait, IElementFinder elementFi super(conditionalWait, elementFinder, localizationManager); } + private static Map, String> getLocatorToXPathTemplateMap() { + Map, String> locatorToXPathTemplateMap = new HashMap<>(); + locatorToXPathTemplateMap.put(ByClassName.class, "//*[contains(@class,'%s')]"); + locatorToXPathTemplateMap.put(ByName.class, "//*[@name='%s']"); + locatorToXPathTemplateMap.put(ById.class, "//*[@id='%s']"); + locatorToXPathTemplateMap.put(ByIdOrName.class, "//*[@id='%1$s' or @name='%1$s']"); + return locatorToXPathTemplateMap; + } + @Override protected Map, Class> getElementTypesMap() { Map, Class> typesMap = new HashMap<>(); @@ -44,8 +56,40 @@ protected Map locatorClass = locator.getClass(); + return getLocatorToXPathTemplateMap().containsKey(locator.getClass()) + ? String.format(getLocatorToXPathTemplateMap().get(locatorClass), locValuableString) + : super.extractXPathFromLocator(locator); + } } diff --git a/src/main/java/aquality/selenium/elements/interfaces/IElement.java b/src/main/java/aquality/selenium/elements/interfaces/IElement.java index e12db36..7047874 100644 --- a/src/main/java/aquality/selenium/elements/interfaces/IElement.java +++ b/src/main/java/aquality/selenium/elements/interfaces/IElement.java @@ -1,6 +1,7 @@ package aquality.selenium.elements.interfaces; import aquality.selenium.core.elements.ElementState; +import aquality.selenium.core.elements.ElementsCount; import aquality.selenium.elements.ElementType; import aquality.selenium.elements.HighlightState; import aquality.selenium.elements.actions.JsActions; @@ -8,6 +9,8 @@ import org.openqa.selenium.By; import org.openqa.selenium.Keys; +import java.util.List; + public interface IElement extends aquality.selenium.core.elements.interfaces.IElement { /** @@ -154,4 +157,114 @@ default T findChildElement(By childLoc, ElementType element default T findChildElement(By childLoc, String name, ElementType elementType) { return findChildElement(childLoc, name, elementType, ElementState.DISPLAYED); } + + /** + * Finds displayed 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 elementType type of the element to be obtained + * @return List of child elements. + */ + default List findChildElements(By childLoc, ElementType elementType) { + return findChildElements(childLoc, elementType, ElementsCount.ANY); + } + + /** + * Finds displayed 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 elementType type of the element to be obtained + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of child elements. + */ + default List findChildElements(By childLoc, ElementType elementType, ElementsCount count) { + return findChildElements(childLoc, elementType, ElementState.DISPLAYED, count); + } + + /** + * 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 elementType type of the element to be obtained + * @param state Visibility state of child elements. + * @return List of child elements. + */ + default List findChildElements(By childLoc, ElementType elementType, ElementState state) { + return findChildElements(childLoc, elementType, 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 elementType type of the element 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, ElementType elementType, ElementState state, + ElementsCount count) { + return findChildElements(childLoc, null, elementType, state, count); + } + + /** + * Finds displayed 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 elementType type of the element to be obtained + * @return List of child elements. + */ + default List findChildElements(By childLoc, String name, ElementType elementType) { + return findChildElements(childLoc, name, elementType, ElementsCount.ANY); + } + + /** + * Finds displayed 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 elementType type of the element to be obtained + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of child elements. + */ + default List findChildElements(By childLoc, String name, ElementType elementType, ElementsCount count) { + return findChildElements(childLoc, name, elementType, ElementState.DISPLAYED, count); + } + + /** + * 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 elementType type of the element to be obtained + * @param state Visibility state of child elements. + * @return List of child elements. + */ + default List findChildElements(By childLoc, String name, ElementType elementType, ElementState state) { + return findChildElements(childLoc, name, elementType, 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 elementType type of the element 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. + */ + default List findChildElements(By childLoc, String name, ElementType elementType, + ElementState state, ElementsCount count) { + return findChildElements(childLoc, name, elementType.getClazz(), state, count); + } } diff --git a/src/main/java/aquality/selenium/elements/interfaces/IElementFactory.java b/src/main/java/aquality/selenium/elements/interfaces/IElementFactory.java index d7e9537..13cd99a 100644 --- a/src/main/java/aquality/selenium/elements/interfaces/IElementFactory.java +++ b/src/main/java/aquality/selenium/elements/interfaces/IElementFactory.java @@ -261,6 +261,7 @@ default T findChildElement(IElement parentElement, By child /** * Find list of elements * + * @param Type of the target elements. * @param locator Elements selector * @param name elements' name. * @param type Type of elements to be obtained @@ -339,4 +340,128 @@ default List findElements(By locator, String name, Eleme default List findElements(By locator, ElementType type, ElementsCount count) { return findElements(locator, type, count, ElementState.DISPLAYED); } + + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param Type of the target elements. + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param type Type of elements to be obtained + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, ElementType type) { + return findChildElements(parentElement, childLoc, type, ElementsCount.ANY); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param Type of the target elements. + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param type Type of 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, ElementType type, + ElementsCount count) { + return findChildElements(parentElement, childLoc, type, count, ElementState.DISPLAYED); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param Type of the target elements. + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param type Type of elements to be obtained + * @param state Visibility state of child elements. + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, + ElementType type, ElementState state) { + return findChildElements(parentElement, childLoc, type, ElementsCount.ANY, state); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param Type of the target elements. + * @param parentElement Parent element for relative search of child elements. + * @param childLoc Locator of child elements relative to its parent. + * @param type Type 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 child elements. + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, ElementType type, + ElementsCount count, ElementState state) { + return findChildElements(parentElement, childLoc, null, type, count, state); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param Type of the target elements. + * @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 type Type of the element to be obtained + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, + String name, ElementType type) { + return findChildElements(parentElement, childLoc, name, type, ElementsCount.ANY); + } + + /** + * Finds displayed child elements by their locator relative to parent element. + * + * @param Type of the target elements. + * @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 type Type of the element to be obtained + * @param count Expected number of elements that have to be found (zero, more then zero, any). + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, String name, + ElementType type, ElementsCount count) { + return findChildElements(parentElement, childLoc, name, type, count, ElementState.DISPLAYED); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param Type of the target elements. + * @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 type Type of the element to be obtained + * @param state Visibility state of child elements. + * @return List of child elements. + */ + default List findChildElements(IElement parentElement, By childLoc, String name, + ElementType type, ElementState state) { + return findChildElements(parentElement, childLoc, name, type, ElementsCount.ANY, state); + } + + /** + * Finds child elements by their locator relative to parent element. + * + * @param childLoc Locator of child elements relative to its parent. + * @param type Type of the element 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. + */ + default List findChildElements(IElement parentElement, By childLoc, String name, + ElementType type, ElementsCount count, ElementState state) { + return findChildElements(parentElement, childLoc, name, type.getClazz(), count, state); + } } diff --git a/src/main/java/aquality/selenium/forms/Form.java b/src/main/java/aquality/selenium/forms/Form.java index 970af87..03b7eae 100644 --- a/src/main/java/aquality/selenium/forms/Form.java +++ b/src/main/java/aquality/selenium/forms/Form.java @@ -7,7 +7,9 @@ import org.openqa.selenium.By; import org.openqa.selenium.Dimension; - +/** + * Defines base class for any UI form. + */ public abstract class Form { /** * Locator for specified form @@ -51,7 +53,7 @@ public String getName() { * False - form is not opened */ public boolean isDisplayed() { - return getElementFactory().getLabel(locator, name).state().waitForDisplayed(); + return getFormLabel().state().waitForDisplayed(); } /** @@ -64,11 +66,23 @@ public void scrollBy(int x, int y) { getFormLabel().getJsActions().scrollBy(x, y); } + /** + * Gets size of form element defined by its locator. + * + * @return Size of the form element. + */ public Dimension getSize() { return getFormLabel().getElement().getSize(); } - private ILabel getFormLabel() { + + /** + * Gets Label of form element defined by its locator and name. + * Could be used to find child elements relative to form element. + * + * @return Label of form element. + */ + protected ILabel getFormLabel() { return getElementFactory().getLabel(locator, name); } diff --git a/src/test/java/automationpractice/forms/ProductTabContentForm.java b/src/test/java/automationpractice/forms/ProductTabContentForm.java new file mode 100644 index 0000000..e6c3ef7 --- /dev/null +++ b/src/test/java/automationpractice/forms/ProductTabContentForm.java @@ -0,0 +1,62 @@ +package automationpractice.forms; + +import aquality.selenium.core.elements.ElementState; +import aquality.selenium.core.elements.ElementsCount; +import aquality.selenium.elements.ElementType; +import aquality.selenium.elements.interfaces.ILabel; +import aquality.selenium.forms.Form; +import org.openqa.selenium.By; +import org.openqa.selenium.support.ByIdOrName; + +import java.util.List; + +public class ProductTabContentForm extends Form { + + private static final By LIST_ELEMENTS_XPATH = By.xpath("//ul[@id='blockbestsellers']//li"); + private static final By DOTTED_XPATH = By.xpath(".//ul[@id='blockbestsellers']//li[not(@style='display:none')]"); + private static final By BEST_SELLERS_BY_ID = By.id("blockbestsellers"); + private static final By INPUT_BY_NAME = By.name("controller"); + private static final By INPUT_BY_ID_OR_NAME = new ByIdOrName("controller"); + private static final By ITEM_BY_CSS_SELECTOR = By.cssSelector(".submenu-container"); + private static final By ITEM_BY_CLASS_NAME = By.className("submenu-container"); + + public ProductTabContentForm() { + super(By.className("tab-content"), "Product tab content"); + } + + public List getListElements(ElementState state, ElementsCount count) { + return getElementFactory().findElements(LIST_ELEMENTS_XPATH, ElementType.LABEL, count, state); + } + + public List getListElementsById(ElementState state, ElementsCount count) { + return getElementFactory().findElements(BEST_SELLERS_BY_ID, ElementType.LABEL, count, state); + } + + public List getListElementsByName(ElementState state, ElementsCount count) { + return getElementFactory().findElements(INPUT_BY_NAME, ElementType.LABEL, count, state); + } + + public List getListElementsByIdOrName(ElementState state, ElementsCount count) { + return getElementFactory().findElements(INPUT_BY_ID_OR_NAME, ElementType.LABEL, count, state); + } + + public List getListElementsByClassName(ElementState state, ElementsCount count) { + return getElementFactory().findElements(ITEM_BY_CLASS_NAME, ElementType.LABEL, count, state); + } + + public List getListElementsByCss(ElementState state, ElementsCount count) { + return getElementFactory().findElements(ITEM_BY_CSS_SELECTOR, ElementType.LABEL, count, state); + } + + public ILabel getChildElementByNonXPath(ElementState state) { + return getFormLabel().findChildElement(BEST_SELLERS_BY_ID, ElementType.LABEL, state); + } + + public List getListElementsByDottedXPath(ElementState state, ElementsCount count) { + return getElementFactory().findElements(DOTTED_XPATH, ElementType.LABEL, count, state); + } + + public List getChildElementsByDottedXPath(ElementState state, ElementsCount count) { + return getFormLabel().findChildElements(DOTTED_XPATH, ElementType.LABEL, state, count); + } +} diff --git a/src/test/java/tests/integration/HiddenElementsTests.java b/src/test/java/tests/integration/HiddenElementsTests.java index fb9b24a..7ef47c6 100644 --- a/src/test/java/tests/integration/HiddenElementsTests.java +++ b/src/test/java/tests/integration/HiddenElementsTests.java @@ -4,34 +4,65 @@ import aquality.selenium.core.elements.ElementState; import aquality.selenium.core.elements.ElementsCount; import aquality.selenium.elements.interfaces.ILabel; +import automationpractice.forms.ProductTabContentForm; import automationpractice.forms.SliderForm; import org.testng.Assert; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import tests.BaseTest; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.function.Function; import static automationpractice.Constants.URL_AUTOMATIONPRACTICE; public class HiddenElementsTests extends BaseTest { + private static final ProductTabContentForm productsForm = new ProductTabContentForm(); + @BeforeMethod @Override protected void beforeMethod() { AqualityServices.getBrowser().goTo(URL_AUTOMATIONPRACTICE); } + + @DataProvider + private Object[] getHiddenElementListProviders() { + List>> providers = new ArrayList<>(); + ElementState state = ElementState.EXISTS_IN_ANY_STATE; + providers.add(count -> productsForm.getListElements(state, count)); + providers.add(count -> productsForm.getListElementsById(state, count)); + providers.add(count -> productsForm.getListElementsByName(state, count)); + providers.add(count -> productsForm.getListElementsByIdOrName(state, count)); + providers.add(count -> productsForm.getListElementsByClassName(state, count)); + providers.add(count -> productsForm.getListElementsByCss(state, count)); + providers.add(count -> productsForm.getListElementsByDottedXPath(state, count)); + providers.add(count -> productsForm.getChildElementsByDottedXPath(state, count)); + providers.add(count -> Collections.singletonList(productsForm.getChildElementByNonXPath(state))); + return providers.toArray(); + } + @Test public void testHiddenElementExist() { Assert.assertTrue(new SliderForm().getBtnAddToCart(ElementState.EXISTS_IN_ANY_STATE).state().isExist()); } - @Test - public void testHiddenElementsExist() { - List listElements = new SliderForm().getListElements(ElementState.EXISTS_IN_ANY_STATE, ElementsCount.MORE_THEN_ZERO); + @Test(dataProvider = "getHiddenElementListProviders") + public void testHiddenElementsExist(Function> elementsListProvider) { + List listElements = elementsListProvider.apply(ElementsCount.MORE_THEN_ZERO); + Assert.assertFalse(listElements.isEmpty()); + Assert.assertTrue(listElements.stream().allMatch(el -> el.state().isExist())); + } + + @Test(dataProvider = "getHiddenElementListProviders") + public void testHiddenElementsNotDisplayed(Function> elementsListProvider) { + List listElements = elementsListProvider.apply(ElementsCount.MORE_THEN_ZERO); Assert.assertFalse(listElements.isEmpty()); - Assert.assertTrue(listElements.stream().allMatch(el -> el.state().waitForExist())); + Assert.assertTrue(listElements.stream().noneMatch(el -> el.state().isDisplayed())); } @Test