Skip to content

Commit c7f728e

Browse files
authored
Feature/15 element (#34)
* #15 extracted IElement * #14 merged with master and fixed issues * #14 inherited Custom element from Element * #14 updated IElement and added tests for this * #14 removed last 's' in applications * #14 small fix for docs * #14 fix comments * #14 remove using logger from testRetrierShouldWorkOnceIfMethodSucceeded * #14 reverted getElementState() for Element * #14 fix localization * #14 increased accuracy of conditional wait tests * #14 added taskkill chromedriver * #14 removed taskkill chromedriver * #14 hot fix for WaitForObjectTests * #14 removed redundant , * #14 added debug info * #14 added catching of InterruptedException * #14 removed parallel = true for data driven * #14 reverted for element action retrier tests * #14 added accuracy for checkRetrierShouldWaitPollingTimeBetweenMethodsCall * #14 removed unused import
1 parent 5e72f7d commit c7f728e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+831
-200
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package aquality.selenium.core.elements;
2+
3+
import aquality.selenium.core.applications.IApplication;
4+
import aquality.selenium.core.configurations.IElementCacheConfiguration;
5+
import aquality.selenium.core.elements.interfaces.*;
6+
import aquality.selenium.core.localization.ILocalizedLogger;
7+
import aquality.selenium.core.logging.Logger;
8+
import aquality.selenium.core.utilities.IElementActionRetrier;
9+
import aquality.selenium.core.waitings.IConditionalWait;
10+
import org.openqa.selenium.By;
11+
import org.openqa.selenium.NoSuchElementException;
12+
import org.openqa.selenium.WebDriverException;
13+
import org.openqa.selenium.remote.RemoteWebElement;
14+
15+
import java.util.function.Supplier;
16+
17+
public abstract class Element implements IElement {
18+
19+
private final String name;
20+
private final ElementState elementState;
21+
private final By locator;
22+
private IElementCacheHandler elementCacheHandler;
23+
24+
protected Element(final By loc, final String name, final ElementState state) {
25+
locator = loc;
26+
this.name = name;
27+
elementState = state;
28+
}
29+
30+
protected abstract IApplication getApplication();
31+
32+
protected abstract IElementFactory getElementFactory();
33+
34+
protected abstract IElementFinder getElementFinder();
35+
36+
protected abstract IElementCacheConfiguration getElementCacheConfiguration();
37+
38+
protected abstract IElementActionRetrier getElementActionRetrier();
39+
40+
protected abstract ILocalizedLogger getLocalizedLogger();
41+
42+
protected abstract IConditionalWait getConditionalWait();
43+
44+
protected abstract String getElementType();
45+
46+
protected IElementCacheHandler getCache() {
47+
if (elementCacheHandler == null) {
48+
elementCacheHandler = new ElementCacheHandler(locator, elementState, getElementFinder());
49+
}
50+
51+
return elementCacheHandler;
52+
}
53+
54+
protected Logger getLogger() {
55+
return Logger.getInstance();
56+
}
57+
58+
@Override
59+
public By getLocator() {
60+
return locator;
61+
}
62+
63+
@Override
64+
public String getName() {
65+
return name;
66+
}
67+
68+
@Override
69+
public IElementStateProvider state() {
70+
return getElementCacheConfiguration().isEnabled()
71+
? new CachedElementStateProvider(locator, getConditionalWait(), getCache(), getLocalizedLogger())
72+
: new DefaultElementStateProvider(locator, getConditionalWait(), getElementFinder());
73+
}
74+
75+
@Override
76+
public RemoteWebElement getElement(Long timeout) {
77+
try {
78+
return getElementCacheConfiguration().isEnabled()
79+
? getCache().getElement(timeout)
80+
: (RemoteWebElement) getElementFinder().findElement(locator, elementState, timeout);
81+
} catch (NoSuchElementException e) {
82+
logPageSource(e);
83+
throw e;
84+
}
85+
}
86+
87+
protected void logPageSource(WebDriverException exception) {
88+
try {
89+
getLogger().debug("Page source:".concat(System.lineSeparator()).concat(getApplication().getDriver().getPageSource()), exception);
90+
} catch (WebDriverException e) {
91+
getLogger().error(exception.getMessage());
92+
getLocalizedLogger().fatal("loc.get.page.source.failed", e);
93+
}
94+
}
95+
96+
@Override
97+
public String getText() {
98+
logElementAction("loc.get.text");
99+
return doWithRetry(() -> getElement().getText());
100+
}
101+
102+
@Override
103+
public String getAttribute(String attr) {
104+
logElementAction("loc.el.getattr", attr);
105+
return doWithRetry(() -> getElement().getAttribute(attr));
106+
}
107+
108+
@Override
109+
public void sendKeys(String keys) {
110+
logElementAction("loc.text.sending.keys", keys);
111+
doWithRetry(() -> getElement().sendKeys(keys));
112+
}
113+
114+
@Override
115+
public void click() {
116+
logElementAction("loc.clicking");
117+
doWithRetry(() -> getElement().click());
118+
}
119+
120+
@Override
121+
public <T extends IElement> T findChildElement(By childLoc, String name, Class<T> clazz, ElementState state) {
122+
return getElementFactory().findChildElement(this, childLoc, name, clazz, state);
123+
}
124+
125+
@Override
126+
public <T extends IElement> T findChildElement(By childLoc, String name, IElementSupplier<T> supplier, ElementState state) {
127+
return getElementFactory().findChildElement(this, childLoc, name, supplier, state);
128+
}
129+
130+
protected <T> T doWithRetry(Supplier<T> action) {
131+
return getElementActionRetrier().doWithRetry(action);
132+
}
133+
134+
protected void doWithRetry(Runnable action) {
135+
getElementActionRetrier().doWithRetry(action);
136+
}
137+
138+
protected void logElementAction(String messageKey, Object... args) {
139+
getLocalizedLogger().infoElementAction(getElementType(), name, messageKey, args);
140+
}
141+
142+
protected ElementState getElementState() {
143+
return elementState;
144+
}
145+
}

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

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,75 @@
33
import org.openqa.selenium.By;
44
import org.openqa.selenium.remote.RemoteWebElement;
55

6+
/**
7+
* Describes behavior of any UI element.
8+
*/
69
public interface IElement extends IParent {
10+
/**
11+
* Gets unique locator of element.
12+
*
13+
* @return Element locator
14+
*/
15+
By getLocator();
16+
17+
/**
18+
* Gets unique name of element
19+
*
20+
* @return name
21+
*/
22+
String getName();
23+
24+
/**
25+
* Provides ability to define of element's state (whether it is displayed, exists or not) and respective waiting functions
26+
*
27+
* @return provider to define element's state
28+
*/
29+
IElementStateProvider state();
730

831
/**
9-
* Gets clear WebElement.
32+
* Gets current element by specified {@link #getLocator()}
33+
* Default timeout is provided in {@link aquality.selenium.core.configurations.ITimeoutConfiguration}/>
34+
* {@link org.openqa.selenium.NoSuchElementException} throws if element not found
1035
*
11-
* @return WebElement
36+
* @return instance of {@link RemoteWebElement} if found.
1237
*/
1338
default RemoteWebElement getElement() {
1439
return getElement(null);
1540
}
1641

1742
/**
18-
* Gets clear WebElement.
43+
* Gets current element by specified {@link #getLocator()}
44+
* {@link org.openqa.selenium.NoSuchElementException} throws if element not found
1945
*
2046
* @param timeout Timeout for waiting
21-
* @return WebElement
47+
* @return instance of {@link RemoteWebElement} if found.
2248
*/
2349
RemoteWebElement getElement(Long timeout);
2450

2551
/**
26-
* Gets element name.
52+
* Gets the item text (inner text).
2753
*
28-
* @return name
54+
* @return text of element
2955
*/
30-
String getName();
56+
String getText();
3157

3258
/**
33-
* Gets element locator.
59+
* Gets attribute value of the element.
3460
*
35-
* @return locator
61+
* @param attr Attribute name
62+
* @return Attribute value
3663
*/
37-
By getLocator();
64+
String getAttribute(String attr);
65+
66+
/**
67+
* Sends keys
68+
*
69+
* @param keys keys for sending
70+
*/
71+
void sendKeys(String keys);
72+
73+
/**
74+
* Clicks on the item.
75+
*/
76+
void click();
3877
}

src/main/java/aquality/selenium/core/elements/interfaces/IParent.java

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,100 @@ public interface IParent {
88
/**
99
* Find an element in the parent element
1010
*
11-
* @param childLoc Child element locator
12-
* @param clazz class or interface of the element to be obtained
11+
* @param childLoc child element locator
12+
* @param name output name in logs
13+
* @param clazz class or interface of the element to be obtained
14+
* @param state visibility state of target element
15+
* @param <T> the type of the element to be obtained
1316
* @return found child element
1417
*/
15-
default <T extends IElement> T findChildElement(By childLoc, Class<? extends IElement> clazz){
16-
return findChildElement(childLoc, clazz, ElementState.DISPLAYED);
18+
<T extends IElement> T findChildElement(By childLoc, String name, Class<T> clazz, ElementState state);
19+
20+
/**
21+
* Find an element in the parent element with DISPLAYED state
22+
*
23+
* @param childLoc child element locator
24+
* @param name output name in logs
25+
* @param clazz class or interface of the element to be obtained
26+
* @param <T> the type of the element to be obtained
27+
* @return found child element
28+
*/
29+
default <T extends IElement> T findChildElement(By childLoc, String name, Class<T> clazz) {
30+
return findChildElement(childLoc, name, clazz, ElementState.DISPLAYED);
1731
}
1832

1933
/**
2034
* Find an element in the parent element
2135
*
22-
* @param childLoc Child element locator
23-
* @param clazz class or interface of the element to be obtained
24-
* @param state visibility state of target element
36+
* @param childLoc child element locator
37+
* @param clazz class or interface of the element to be obtained
38+
* @param state visibility state of target element
39+
* @param <T> the type of the element to be obtained
2540
* @return found child element
2641
*/
27-
<T extends IElement> T findChildElement(By childLoc, Class<? extends IElement> clazz, ElementState state);
42+
default <T extends IElement> T findChildElement(By childLoc, Class<T> clazz, ElementState state) {
43+
return findChildElement(childLoc, null, clazz, state);
44+
}
2845

2946
/**
30-
* Find an element in the parent element
47+
* Find an element in the parent element with DISPLAYED state
48+
*
49+
* @param childLoc child element locator
50+
* @param clazz class or interface of the element to be obtained
51+
* @param <T> the type of the element to be obtained
52+
* @return found child element
53+
*/
54+
default <T extends IElement> T findChildElement(By childLoc, Class<T> clazz) {
55+
return findChildElement(childLoc, null, clazz, ElementState.DISPLAYED);
56+
}
57+
58+
/**
59+
* Finds an element in the parent element
3160
*
3261
* @param childLoc Child element locator
62+
* @param name output name in logs
63+
* @param supplier required element's supplier
64+
* @param state visibility state of target element
65+
* @param <T> the type of the element to be obtained
66+
* @return found child element
67+
*/
68+
<T extends IElement> T findChildElement(By childLoc, String name, IElementSupplier<T> supplier, ElementState state);
69+
70+
/**
71+
* Find an element in the parent element with DISPLAYED state
72+
*
73+
* @param childLoc child element locator
74+
* @param name output name in logs
75+
* @param supplier required element's supplier
76+
* @param <T> the type of the element to be obtained
77+
* @return found child element
78+
*/
79+
default <T extends IElement> T findChildElement(By childLoc, String name, IElementSupplier<T> supplier) {
80+
return findChildElement(childLoc, name, supplier, ElementState.DISPLAYED);
81+
}
82+
83+
/**
84+
* Finds an element in the parent element
85+
*
86+
* @param childLoc child element locator
3387
* @param supplier required element's supplier
34-
* @param state visibility state of target element
88+
* @param state visibility state of target element
89+
* @param <T> the type of the element to be obtained
3590
* @return found child element
3691
*/
37-
<T extends IElement> T findChildElement(By childLoc, IElementSupplier<T> supplier, ElementState state);
92+
default <T extends IElement> T findChildElement(By childLoc, IElementSupplier<T> supplier, ElementState state) {
93+
return findChildElement(childLoc, null, supplier, state);
94+
}
95+
96+
/**
97+
* Find an element in the parent element with DISPLAYED state
98+
*
99+
* @param childLoc child element locator
100+
* @param supplier required element's supplier
101+
* @param <T> the type of the element to be obtained
102+
* @return found child element
103+
*/
104+
default <T extends IElement> T findChildElement(By childLoc, IElementSupplier<T> supplier) {
105+
return findChildElement(childLoc, null, supplier, ElementState.DISPLAYED);
106+
}
38107
}

src/main/resources/localization/be.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
"loc.elements.were.found.but.not.in.state": "Знайшлі элементы па лакатару '%1$s', але яны не ў жаданым стане %2$s",
99
"loc.elements.found.but.should.not": "Не павінна быць знойдзена элементаў па лакатару '%1$s' у %2$s стане",
1010
"loc.search.of.elements.failed": "Пошук элемента па лакатару '%1$s' прайшоў няўдала",
11-
"loc.element.not.in.state": "Элемент %1$s ня стаў %2$s пасля таймаўта %3$s"
11+
"loc.element.not.in.state": "Элемент %1$s не стаў %2$s пасля таймаўта %3$s",
12+
"loc.get.page.source.failed": "Адбылася памылка ў час атрымання разметкі старонкі"
1213
}

src/main/resources/localization/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
"loc.elements.were.found.but.not.in.state": "Elements were found by locator '%1$s' but not in desired state %2$s",
99
"loc.elements.found.but.should.not": "No elements should be found by locator '%1$s' in %2$s state",
1010
"loc.search.of.elements.failed": "Search of element by locator '%1$s' failed",
11-
"loc.element.not.in.state": "Element %1$s has not become %2$s after timeout %3$s"
11+
"loc.element.not.in.state": "Element %1$s has not become %2$s after timeout %3$s",
12+
"loc.get.page.source.failed": "An exception occurred while tried to save the page source"
1213
}

src/main/resources/localization/ru.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
"loc.elements.were.found.but.not.in.state": "Удалось найти элементы по локатору '%1$s', но они не в желаемом состоянии %2$s",
99
"loc.elements.found.but.should.not": "Не должно быть найдено элементов по локатору '%1$s' в %2$s состоянии",
1010
"loc.search.of.elements.failed": "Поиск элемента по локатору '%1$s' прошел неудачно",
11-
"loc.element.not.in.state": "Элемент %1$s не стал %2$s после таймаута %3$s"
11+
"loc.element.not.in.state": "Элемент %1$s не стал %2$s после таймаута %3$s",
12+
"loc.get.page.source.failed": "Произошла ошибка во время получения разметки страницы"
1213
}

0 commit comments

Comments
 (0)