Skip to content

Commit

Permalink
Feature/99 implement find child elements (#100)
Browse files Browse the repository at this point in the history
* Update aquality selenium core library version

* Enhance ElementFactory to generate more productive xpath for multiple elements

* Define additional overloads for findChildElements in IElement and IElementFactory

* Implement getFormElement() to call findChildElement and FindChildElements from Form to resolve #99
  • Loading branch information
mialeska authored May 29, 2020
1 parent 6617e08 commit 143fcd3
Show file tree
Hide file tree
Showing 7 changed files with 400 additions and 11 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.github.aquality-automation</groupId>
<artifactId>aquality-selenium</artifactId>
<version>2.3.1</version>
<version>2.4.0</version>
<packaging>jar</packaging>
<name>Aquality Selenium</name>
<description>Library around Selenium WebDriver</description>
Expand Down Expand Up @@ -73,7 +73,7 @@
<dependency>
<groupId>com.github.aquality-automation</groupId>
<artifactId>aquality-selenium-core</artifactId>
<version>1.0.2</version>
<version>1.1.0</version>
</dependency>

<dependency>
Expand Down
48 changes: 46 additions & 2 deletions src/main/java/aquality/selenium/elements/ElementFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -21,6 +24,15 @@ public ElementFactory(IConditionalWait conditionalWait, IElementFinder elementFi
super(conditionalWait, elementFinder, localizationManager);
}

private static Map<Class<? extends By>, String> getLocatorToXPathTemplateMap() {
Map<Class<? extends By>, 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<? extends aquality.selenium.core.elements.interfaces.IElement>, Class<? extends aquality.selenium.core.elements.interfaces.IElement>> getElementTypesMap() {
Map<Class<? extends aquality.selenium.core.elements.interfaces.IElement>, Class<? extends aquality.selenium.core.elements.interfaces.IElement>> typesMap = new HashMap<>();
Expand All @@ -44,8 +56,40 @@ protected Map<Class<? extends aquality.selenium.core.elements.interfaces.IElemen
*/
@Override
protected By generateXpathLocator(By multipleElementsLocator, WebElement webElement, int elementIndex) {
return multipleElementsLocator.getClass().equals(ByXPath.class)
return isLocatorSupportedForXPathExtraction(multipleElementsLocator)
? super.generateXpathLocator(multipleElementsLocator, webElement, elementIndex)
: By.xpath((String) AqualityServices.getBrowser().executeScript(JavaScript.GET_ELEMENT_XPATH, webElement));
}

/**
* Defines is the locator can be transformed to xpath or not.
*
* @param locator locator to transform
* @return true if the locator can be transformed to xpath, false otherwise.
*/
@Override
protected boolean isLocatorSupportedForXPathExtraction(By locator) {
return getLocatorToXPathTemplateMap().containsKey(locator.getClass())
|| super.isLocatorSupportedForXPathExtraction(locator);
}

/**
* Extracts XPath from passed locator.
*
* @param locator locator to get xpath from.
* @return extracted XPath.
*/
@Override
protected String extractXPathFromLocator(By locator) {
String locatorString = locator.toString();
int indexOfDots = locatorString.indexOf(':');
String locValuableString = indexOfDots == -1
// case ByIdOrName:
? locatorString.substring(locatorString.indexOf('"')).replace("\"", "")
: locatorString.substring(indexOfDots + 1).trim();
Class<? extends By> locatorClass = locator.getClass();
return getLocatorToXPathTemplateMap().containsKey(locator.getClass())
? String.format(getLocatorToXPathTemplateMap().get(locatorClass), locValuableString)
: super.extractXPathFromLocator(locator);
}
}
113 changes: 113 additions & 0 deletions src/main/java/aquality/selenium/elements/interfaces/IElement.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
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;
import aquality.selenium.elements.actions.MouseActions;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;

import java.util.List;

public interface IElement extends aquality.selenium.core.elements.interfaces.IElement {

/**
Expand Down Expand Up @@ -154,4 +157,114 @@ default <T extends IElement> T findChildElement(By childLoc, ElementType element
default <T extends IElement> 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 <T> 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 <T extends IElement> List<T> findChildElements(By childLoc, ElementType elementType) {
return findChildElements(childLoc, elementType, ElementsCount.ANY);
}

/**
* Finds displayed child elements by their locator relative to parent element.
*
* @param <T> 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 <T extends IElement> List<T> 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 <T> 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 <T extends IElement> List<T> 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 <T> 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 <T extends IElement> List<T> 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 <T> 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 <T extends IElement> List<T> 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 <T> 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 <T extends IElement> List<T> 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 <T> 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 <T extends IElement> List<T> 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 <T> 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 <T extends IElement> List<T> findChildElements(By childLoc, String name, ElementType elementType,
ElementState state, ElementsCount count) {
return findChildElements(childLoc, name, elementType.getClazz(), state, count);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ default <T extends IElement> T findChildElement(IElement parentElement, By child
/**
* Find list of elements
*
* @param <T> Type of the target elements.
* @param locator Elements selector
* @param name elements' name.
* @param type Type of elements to be obtained
Expand Down Expand Up @@ -339,4 +340,128 @@ default <T extends IElement> List<T> findElements(By locator, String name, Eleme
default <T extends IElement> List<T> 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 <T> 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 <T extends IElement> List<T> 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 <T> 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 <T extends IElement> List<T> 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 <T> 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 <T extends IElement> List<T> 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 <T> 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 <T extends IElement> List<T> 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 <T> 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 <T extends IElement> List<T> 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 <T> 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 <T extends IElement> List<T> 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 <T> 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 <T extends IElement> List<T> 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 <T> Type of the target elements.
* @return List of child elements.
*/
default <T extends IElement> List<T> findChildElements(IElement parentElement, By childLoc, String name,
ElementType type, ElementsCount count, ElementState state) {
return findChildElements(parentElement, childLoc, name, type.getClazz(), count, state);
}
}
Loading

0 comments on commit 143fcd3

Please sign in to comment.