Skip to content

Commit 143fcd3

Browse files
authored
Feature/99 implement find child elements (#100)
* 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
1 parent 6617e08 commit 143fcd3

File tree

7 files changed

+400
-11
lines changed

7 files changed

+400
-11
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.github.aquality-automation</groupId>
88
<artifactId>aquality-selenium</artifactId>
9-
<version>2.3.1</version>
9+
<version>2.4.0</version>
1010
<packaging>jar</packaging>
1111
<name>Aquality Selenium</name>
1212
<description>Library around Selenium WebDriver</description>
@@ -73,7 +73,7 @@
7373
<dependency>
7474
<groupId>com.github.aquality-automation</groupId>
7575
<artifactId>aquality-selenium-core</artifactId>
76-
<version>1.0.2</version>
76+
<version>1.1.0</version>
7777
</dependency>
7878

7979
<dependency>

src/main/java/aquality/selenium/elements/ElementFactory.java

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88
import aquality.selenium.elements.interfaces.*;
99
import com.google.inject.Inject;
1010
import org.openqa.selenium.By;
11-
import org.openqa.selenium.By.ByXPath;
11+
import org.openqa.selenium.By.ByClassName;
12+
import org.openqa.selenium.By.ById;
13+
import org.openqa.selenium.By.ByName;
1214
import org.openqa.selenium.WebElement;
15+
import org.openqa.selenium.support.ByIdOrName;
1316

1417
import java.util.HashMap;
1518
import java.util.Map;
@@ -21,6 +24,15 @@ public ElementFactory(IConditionalWait conditionalWait, IElementFinder elementFi
2124
super(conditionalWait, elementFinder, localizationManager);
2225
}
2326

27+
private static Map<Class<? extends By>, String> getLocatorToXPathTemplateMap() {
28+
Map<Class<? extends By>, String> locatorToXPathTemplateMap = new HashMap<>();
29+
locatorToXPathTemplateMap.put(ByClassName.class, "//*[contains(@class,'%s')]");
30+
locatorToXPathTemplateMap.put(ByName.class, "//*[@name='%s']");
31+
locatorToXPathTemplateMap.put(ById.class, "//*[@id='%s']");
32+
locatorToXPathTemplateMap.put(ByIdOrName.class, "//*[@id='%1$s' or @name='%1$s']");
33+
return locatorToXPathTemplateMap;
34+
}
35+
2436
@Override
2537
protected Map<Class<? extends aquality.selenium.core.elements.interfaces.IElement>, Class<? extends aquality.selenium.core.elements.interfaces.IElement>> getElementTypesMap() {
2638
Map<Class<? extends aquality.selenium.core.elements.interfaces.IElement>, Class<? extends aquality.selenium.core.elements.interfaces.IElement>> typesMap = new HashMap<>();
@@ -44,8 +56,40 @@ protected Map<Class<? extends aquality.selenium.core.elements.interfaces.IElemen
4456
*/
4557
@Override
4658
protected By generateXpathLocator(By multipleElementsLocator, WebElement webElement, int elementIndex) {
47-
return multipleElementsLocator.getClass().equals(ByXPath.class)
59+
return isLocatorSupportedForXPathExtraction(multipleElementsLocator)
4860
? super.generateXpathLocator(multipleElementsLocator, webElement, elementIndex)
4961
: By.xpath((String) AqualityServices.getBrowser().executeScript(JavaScript.GET_ELEMENT_XPATH, webElement));
5062
}
63+
64+
/**
65+
* Defines is the locator can be transformed to xpath or not.
66+
*
67+
* @param locator locator to transform
68+
* @return true if the locator can be transformed to xpath, false otherwise.
69+
*/
70+
@Override
71+
protected boolean isLocatorSupportedForXPathExtraction(By locator) {
72+
return getLocatorToXPathTemplateMap().containsKey(locator.getClass())
73+
|| super.isLocatorSupportedForXPathExtraction(locator);
74+
}
75+
76+
/**
77+
* Extracts XPath from passed locator.
78+
*
79+
* @param locator locator to get xpath from.
80+
* @return extracted XPath.
81+
*/
82+
@Override
83+
protected String extractXPathFromLocator(By locator) {
84+
String locatorString = locator.toString();
85+
int indexOfDots = locatorString.indexOf(':');
86+
String locValuableString = indexOfDots == -1
87+
// case ByIdOrName:
88+
? locatorString.substring(locatorString.indexOf('"')).replace("\"", "")
89+
: locatorString.substring(indexOfDots + 1).trim();
90+
Class<? extends By> locatorClass = locator.getClass();
91+
return getLocatorToXPathTemplateMap().containsKey(locator.getClass())
92+
? String.format(getLocatorToXPathTemplateMap().get(locatorClass), locValuableString)
93+
: super.extractXPathFromLocator(locator);
94+
}
5195
}

src/main/java/aquality/selenium/elements/interfaces/IElement.java

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package aquality.selenium.elements.interfaces;
22

33
import aquality.selenium.core.elements.ElementState;
4+
import aquality.selenium.core.elements.ElementsCount;
45
import aquality.selenium.elements.ElementType;
56
import aquality.selenium.elements.HighlightState;
67
import aquality.selenium.elements.actions.JsActions;
78
import aquality.selenium.elements.actions.MouseActions;
89
import org.openqa.selenium.By;
910
import org.openqa.selenium.Keys;
1011

12+
import java.util.List;
13+
1114
public interface IElement extends aquality.selenium.core.elements.interfaces.IElement {
1215

1316
/**
@@ -154,4 +157,114 @@ default <T extends IElement> T findChildElement(By childLoc, ElementType element
154157
default <T extends IElement> T findChildElement(By childLoc, String name, ElementType elementType) {
155158
return findChildElement(childLoc, name, elementType, ElementState.DISPLAYED);
156159
}
160+
161+
/**
162+
* Finds displayed child elements by their locator relative to parent element.
163+
*
164+
* @param <T> Type of the target elements.
165+
* @param childLoc Locator of child elements relative to its parent.
166+
* @param elementType type of the element to be obtained
167+
* @return List of child elements.
168+
*/
169+
default <T extends IElement> List<T> findChildElements(By childLoc, ElementType elementType) {
170+
return findChildElements(childLoc, elementType, ElementsCount.ANY);
171+
}
172+
173+
/**
174+
* Finds displayed child elements by their locator relative to parent element.
175+
*
176+
* @param <T> Type of the target elements.
177+
* @param childLoc Locator of child elements relative to its parent.
178+
* @param elementType type of the element to be obtained
179+
* @param count Expected number of elements that have to be found (zero, more then zero, any).
180+
* @return List of child elements.
181+
*/
182+
default <T extends IElement> List<T> findChildElements(By childLoc, ElementType elementType, ElementsCount count) {
183+
return findChildElements(childLoc, elementType, ElementState.DISPLAYED, count);
184+
}
185+
186+
/**
187+
* Finds child elements by their locator relative to parent element.
188+
*
189+
* @param <T> Type of the target elements.
190+
* @param childLoc Locator of child elements relative to its parent.
191+
* @param elementType type of the element to be obtained
192+
* @param state Visibility state of child elements.
193+
* @return List of child elements.
194+
*/
195+
default <T extends IElement> List<T> findChildElements(By childLoc, ElementType elementType, ElementState state) {
196+
return findChildElements(childLoc, elementType, state, ElementsCount.ANY);
197+
}
198+
199+
/**
200+
* Finds child elements by their locator relative to parent element.
201+
*
202+
* @param <T> Type of the target elements.
203+
* @param childLoc Locator of child elements relative to its parent.
204+
* @param elementType type of the element to be obtained
205+
* @param state Visibility state of child elements.
206+
* @param count Expected number of elements that have to be found (zero, more then zero, any).
207+
* @return List of child elements.
208+
*/
209+
default <T extends IElement> List<T> findChildElements(By childLoc, ElementType elementType, ElementState state,
210+
ElementsCount count) {
211+
return findChildElements(childLoc, null, elementType, state, count);
212+
}
213+
214+
/**
215+
* Finds displayed child elements by their locator relative to parent element.
216+
*
217+
* @param <T> Type of the target elements.
218+
* @param childLoc Locator of child elements relative to its parent.
219+
* @param name Child elements name.
220+
* @param elementType type of the element to be obtained
221+
* @return List of child elements.
222+
*/
223+
default <T extends IElement> List<T> findChildElements(By childLoc, String name, ElementType elementType) {
224+
return findChildElements(childLoc, name, elementType, ElementsCount.ANY);
225+
}
226+
227+
/**
228+
* Finds displayed child elements by their locator relative to parent element.
229+
*
230+
* @param <T> Type of the target elements.
231+
* @param childLoc Locator of child elements relative to its parent.
232+
* @param name Child elements name.
233+
* @param elementType type of the element to be obtained
234+
* @param count Expected number of elements that have to be found (zero, more then zero, any).
235+
* @return List of child elements.
236+
*/
237+
default <T extends IElement> List<T> findChildElements(By childLoc, String name, ElementType elementType, ElementsCount count) {
238+
return findChildElements(childLoc, name, elementType, ElementState.DISPLAYED, count);
239+
}
240+
241+
/**
242+
* Finds child elements by their locator relative to parent element.
243+
*
244+
* @param <T> Type of the target elements.
245+
* @param childLoc Locator of child elements relative to its parent.
246+
* @param name Child elements name.
247+
* @param elementType type of the element to be obtained
248+
* @param state Visibility state of child elements.
249+
* @return List of child elements.
250+
*/
251+
default <T extends IElement> List<T> findChildElements(By childLoc, String name, ElementType elementType, ElementState state) {
252+
return findChildElements(childLoc, name, elementType, state, ElementsCount.ANY);
253+
}
254+
255+
/**
256+
* Finds child elements by their locator relative to parent element.
257+
*
258+
* @param <T> Type of the target elements.
259+
* @param childLoc Locator of child elements relative to its parent.
260+
* @param name Child elements name.
261+
* @param elementType type of the element to be obtained
262+
* @param state Visibility state of target elements.
263+
* @param count Expected number of elements that have to be found (zero, more then zero, any).
264+
* @return List of child elements.
265+
*/
266+
default <T extends IElement> List<T> findChildElements(By childLoc, String name, ElementType elementType,
267+
ElementState state, ElementsCount count) {
268+
return findChildElements(childLoc, name, elementType.getClazz(), state, count);
269+
}
157270
}

src/main/java/aquality/selenium/elements/interfaces/IElementFactory.java

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ default <T extends IElement> T findChildElement(IElement parentElement, By child
261261
/**
262262
* Find list of elements
263263
*
264+
* @param <T> Type of the target elements.
264265
* @param locator Elements selector
265266
* @param name elements' name.
266267
* @param type Type of elements to be obtained
@@ -339,4 +340,128 @@ default <T extends IElement> List<T> findElements(By locator, String name, Eleme
339340
default <T extends IElement> List<T> findElements(By locator, ElementType type, ElementsCount count) {
340341
return findElements(locator, type, count, ElementState.DISPLAYED);
341342
}
343+
344+
345+
/**
346+
* Finds displayed child elements by their locator relative to parent element.
347+
*
348+
* @param <T> Type of the target elements.
349+
* @param parentElement Parent element for relative search of child elements.
350+
* @param childLoc Locator of child elements relative to its parent.
351+
* @param type Type of elements to be obtained
352+
* @return List of child elements.
353+
*/
354+
default <T extends IElement> List<T> findChildElements(IElement parentElement, By childLoc, ElementType type) {
355+
return findChildElements(parentElement, childLoc, type, ElementsCount.ANY);
356+
}
357+
358+
/**
359+
* Finds displayed child elements by their locator relative to parent element.
360+
*
361+
* @param <T> Type of the target elements.
362+
* @param parentElement Parent element for relative search of child elements.
363+
* @param childLoc Locator of child elements relative to its parent.
364+
* @param type Type of elements to be obtained
365+
* @param count Expected number of elements that have to be found (zero, more then zero, any).
366+
* @return List of child elements.
367+
*/
368+
default <T extends IElement> List<T> findChildElements(IElement parentElement, By childLoc, ElementType type,
369+
ElementsCount count) {
370+
return findChildElements(parentElement, childLoc, type, count, ElementState.DISPLAYED);
371+
}
372+
373+
/**
374+
* Finds child elements by their locator relative to parent element.
375+
*
376+
* @param <T> Type of the target elements.
377+
* @param parentElement Parent element for relative search of child elements.
378+
* @param childLoc Locator of child elements relative to its parent.
379+
* @param type Type of elements to be obtained
380+
* @param state Visibility state of child elements.
381+
* @return List of child elements.
382+
*/
383+
default <T extends IElement> List<T> findChildElements(IElement parentElement, By childLoc,
384+
ElementType type, ElementState state) {
385+
return findChildElements(parentElement, childLoc, type, ElementsCount.ANY, state);
386+
}
387+
388+
/**
389+
* Finds child elements by their locator relative to parent element.
390+
*
391+
* @param <T> Type of the target elements.
392+
* @param parentElement Parent element for relative search of child elements.
393+
* @param childLoc Locator of child elements relative to its parent.
394+
* @param type Type of the element to be obtained
395+
* @param count Expected number of elements that have to be found (zero, more then zero, any).
396+
* @param state Visibility state of child elements.
397+
* @return List of child elements.
398+
*/
399+
default <T extends IElement> List<T> findChildElements(IElement parentElement, By childLoc, ElementType type,
400+
ElementsCount count, ElementState state) {
401+
return findChildElements(parentElement, childLoc, null, type, count, state);
402+
}
403+
404+
/**
405+
* Finds displayed child elements by their locator relative to parent element.
406+
*
407+
* @param <T> Type of the target elements.
408+
* @param parentElement Parent element for relative search of child elements.
409+
* @param childLoc Locator of child elements relative to its parent.
410+
* @param name Child elements name.
411+
* @param type Type of the element to be obtained
412+
* @return List of child elements.
413+
*/
414+
default <T extends IElement> List<T> findChildElements(IElement parentElement, By childLoc,
415+
String name, ElementType type) {
416+
return findChildElements(parentElement, childLoc, name, type, ElementsCount.ANY);
417+
}
418+
419+
/**
420+
* Finds displayed child elements by their locator relative to parent element.
421+
*
422+
* @param <T> Type of the target elements.
423+
* @param parentElement Parent element for relative search of child elements.
424+
* @param childLoc Locator of child elements relative to its parent.
425+
* @param name Child elements name.
426+
* @param type Type of the element to be obtained
427+
* @param count Expected number of elements that have to be found (zero, more then zero, any).
428+
* @return List of child elements.
429+
*/
430+
default <T extends IElement> List<T> findChildElements(IElement parentElement, By childLoc, String name,
431+
ElementType type, ElementsCount count) {
432+
return findChildElements(parentElement, childLoc, name, type, count, ElementState.DISPLAYED);
433+
}
434+
435+
/**
436+
* Finds child elements by their locator relative to parent element.
437+
*
438+
* @param <T> Type of the target elements.
439+
* @param parentElement Parent element for relative search of child elements.
440+
* @param childLoc Locator of child elements relative to its parent.
441+
* @param name Child elements name.
442+
* @param type Type of the element to be obtained
443+
* @param state Visibility state of child elements.
444+
* @return List of child elements.
445+
*/
446+
default <T extends IElement> List<T> findChildElements(IElement parentElement, By childLoc, String name,
447+
ElementType type, ElementState state) {
448+
return findChildElements(parentElement, childLoc, name, type, ElementsCount.ANY, state);
449+
}
450+
451+
/**
452+
* Finds child elements by their locator relative to parent element.
453+
*
454+
* @param childLoc Locator of child elements relative to its parent.
455+
* @param type Type of the element to be obtained
456+
* @param name Child elements name.
457+
* @param parentElement Parent element for relative search of child elements.
458+
* @param count Expected number of elements that have to be found (zero, more then zero, any).
459+
* @param state Visibility state of target elements.
460+
* @param <T> Type of the target elements.
461+
* @return List of child elements.
462+
*/
463+
default <T extends IElement> List<T> findChildElements(IElement parentElement, By childLoc, String name,
464+
ElementType type, ElementsCount count, ElementState state) {
465+
return findChildElements(parentElement, childLoc, name, type.getClazz(), count, state);
466+
}
342467
}

0 commit comments

Comments
 (0)