Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8b2fb31
#15 extracted IElement
knysh Feb 10, 2020
34e185b
Merge branch 'master' into Feature/15-element
knysh Feb 11, 2020
eb6f9bf
#14 merged with master and fixed issues
knysh Feb 11, 2020
e5355fd
#14 inherited Custom element from Element
knysh Feb 11, 2020
6a53ed1
#14 updated IElement and added tests for this
knysh Feb 12, 2020
e0f53c3
#14 removed last 's' in applications
knysh Feb 12, 2020
0571868
#14 small fix for docs
knysh Feb 12, 2020
f3c13a6
#14 fix comments
knysh Feb 12, 2020
03fc0ac
#14 remove using logger from testRetrierShouldWorkOnceIfMethodSucceeded
knysh Feb 12, 2020
dd24d54
#14 reverted getElementState() for Element
knysh Feb 12, 2020
c8f3992
#14 fix localization
knysh Feb 13, 2020
02ab897
Merge branch 'master' into Feature/15-element
knysh Feb 13, 2020
a7c1814
#14 increased accuracy of conditional wait tests
knysh Feb 14, 2020
fb0c5d3
Merge branch 'master' into Feature/15-element
knysh Feb 14, 2020
3ba1d5e
#14 added taskkill chromedriver
knysh Feb 14, 2020
da4b6ff
#14 removed taskkill chromedriver
knysh Feb 14, 2020
9a4538b
#14 hot fix for WaitForObjectTests
knysh Feb 14, 2020
701bce9
#14 removed redundant ,
knysh Feb 14, 2020
a60d9c5
#14 added debug info
knysh Feb 14, 2020
6264ee6
#14 added catching of InterruptedException
knysh Feb 14, 2020
da2f07a
#14 removed parallel = true for data driven
knysh Feb 14, 2020
53fe0d1
#14 reverted for element action retrier tests
knysh Feb 14, 2020
55d49ee
#14 added accuracy for checkRetrierShouldWaitPollingTimeBetweenMethod…
knysh Feb 14, 2020
be548c2
#14 removed unused import
knysh Feb 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions src/main/java/aquality/selenium/core/elements/Element.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package aquality.selenium.core.elements;

import aquality.selenium.core.applications.IApplication;
import aquality.selenium.core.configurations.IElementCacheConfiguration;
import aquality.selenium.core.elements.interfaces.*;
import aquality.selenium.core.localization.ILocalizedLogger;
import aquality.selenium.core.logging.Logger;
import aquality.selenium.core.utilities.IElementActionRetrier;
import aquality.selenium.core.waitings.IConditionalWait;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.remote.RemoteWebElement;

import java.util.function.Supplier;

public abstract class Element implements IElement {

private final String name;
private final ElementState elementState;
private final By locator;
private IElementCacheHandler elementCacheHandler;

protected Element(final By loc, final String name, final ElementState state) {
locator = loc;
this.name = name;
elementState = state;
}

protected abstract IApplication getApplication();

protected abstract IElementFactory getElementFactory();

protected abstract IElementFinder getElementFinder();

protected abstract IElementCacheConfiguration getElementCacheConfiguration();

protected abstract IElementActionRetrier getElementActionRetrier();

protected abstract ILocalizedLogger getLocalizedLogger();

protected abstract IConditionalWait getConditionalWait();

protected abstract String getElementType();

protected IElementCacheHandler getCache() {
if (elementCacheHandler == null) {
elementCacheHandler = new ElementCacheHandler(locator, elementState, getElementFinder());
}

return elementCacheHandler;
}

protected Logger getLogger() {
return Logger.getInstance();
}

@Override
public By getLocator() {
return locator;
}

@Override
public String getName() {
return name;
}

@Override
public IElementStateProvider state() {
return getElementCacheConfiguration().isEnabled()
? new CachedElementStateProvider(locator, getConditionalWait(), getCache(), getLocalizedLogger())
: new DefaultElementStateProvider(locator, getConditionalWait(), getElementFinder());
}

@Override
public RemoteWebElement getElement(Long timeout) {
try {
return getElementCacheConfiguration().isEnabled()
? getCache().getElement(timeout)
: (RemoteWebElement) getElementFinder().findElement(locator, elementState, timeout);
} catch (NoSuchElementException e) {
logPageSource(e);
throw e;
}
}

protected void logPageSource(WebDriverException exception) {
try {
getLogger().debug("Page source:".concat(System.lineSeparator()).concat(getApplication().getDriver().getPageSource()), exception);
} catch (WebDriverException e) {
getLogger().error(exception.getMessage());
getLocalizedLogger().fatal("loc.get.page.source.failed", e);
}
}

@Override
public String getText() {
logElementAction("loc.get.text");
return doWithRetry(() -> getElement().getText());
}

@Override
public String getAttribute(String attr) {
logElementAction("loc.el.getattr", attr);
return doWithRetry(() -> getElement().getAttribute(attr));
}

@Override
public void sendKeys(String keys) {
logElementAction("loc.text.sending.keys", keys);
doWithRetry(() -> getElement().sendKeys(keys));
}

@Override
public void click() {
logElementAction("loc.clicking");
doWithRetry(() -> getElement().click());
}

@Override
public <T extends IElement> T findChildElement(By childLoc, String name, Class<T> clazz, ElementState state) {
return getElementFactory().findChildElement(this, childLoc, name, clazz, state);
}

@Override
public <T extends IElement> T findChildElement(By childLoc, String name, IElementSupplier<T> supplier, ElementState state) {
return getElementFactory().findChildElement(this, childLoc, name, supplier, state);
}

protected <T> T doWithRetry(Supplier<T> action) {
return getElementActionRetrier().doWithRetry(action);
}

protected void doWithRetry(Runnable action) {
getElementActionRetrier().doWithRetry(action);
}

protected void logElementAction(String messageKey, Object... args) {
getLocalizedLogger().infoElementAction(getElementType(), name, messageKey, args);
}

protected ElementState getElementState() {
return elementState;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,75 @@
import org.openqa.selenium.By;
import org.openqa.selenium.remote.RemoteWebElement;

/**
* Describes behavior of any UI element.
*/
public interface IElement extends IParent {
/**
* Gets unique locator of element.
*
* @return Element locator
*/
By getLocator();

/**
* Gets unique name of element
*
* @return name
*/
String getName();

/**
* Provides ability to define of element's state (whether it is displayed, exists or not) and respective waiting functions
*
* @return provider to define element's state
*/
IElementStateProvider state();

/**
* Gets clear WebElement.
* Gets current element by specified {@link #getLocator()}
* Default timeout is provided in {@link aquality.selenium.core.configurations.ITimeoutConfiguration}/>
* {@link org.openqa.selenium.NoSuchElementException} throws if element not found
*
* @return WebElement
* @return instance of {@link RemoteWebElement} if found.
*/
default RemoteWebElement getElement() {
return getElement(null);
}

/**
* Gets clear WebElement.
* Gets current element by specified {@link #getLocator()}
* {@link org.openqa.selenium.NoSuchElementException} throws if element not found
*
* @param timeout Timeout for waiting
* @return WebElement
* @return instance of {@link RemoteWebElement} if found.
*/
RemoteWebElement getElement(Long timeout);

/**
* Gets element name.
* Gets the item text (inner text).
*
* @return name
* @return text of element
*/
String getName();
String getText();

/**
* Gets element locator.
* Gets attribute value of the element.
*
* @return locator
* @param attr Attribute name
* @return Attribute value
*/
By getLocator();
String getAttribute(String attr);

/**
* Sends keys
*
* @param keys keys for sending
*/
void sendKeys(String keys);

/**
* Clicks on the item.
*/
void click();
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,100 @@ public interface IParent {
/**
* Find an element in the parent element
*
* @param childLoc Child element locator
* @param clazz class or interface of the element to be obtained
* @param childLoc child element locator
* @param name output name in logs
* @param clazz class or interface of the element to be obtained
* @param state visibility state of target element
* @param <T> the type of the element to be obtained
* @return found child element
*/
default <T extends IElement> T findChildElement(By childLoc, Class<? extends IElement> clazz){
return findChildElement(childLoc, clazz, ElementState.DISPLAYED);
<T extends IElement> T findChildElement(By childLoc, String name, Class<T> clazz, ElementState state);

/**
* Find an element in the parent element with DISPLAYED state
*
* @param childLoc child element locator
* @param name output name in logs
* @param clazz class or interface of the element to be obtained
* @param <T> the type of the element to be obtained
* @return found child element
*/
default <T extends IElement> T findChildElement(By childLoc, String name, Class<T> clazz) {
return findChildElement(childLoc, name, clazz, ElementState.DISPLAYED);
}

/**
* Find an element in the parent element
*
* @param childLoc Child element locator
* @param clazz class or interface of the element to be obtained
* @param state visibility state of target element
* @param childLoc child element locator
* @param clazz class or interface of the element to be obtained
* @param state visibility state of target element
* @param <T> the type of the element to be obtained
* @return found child element
*/
<T extends IElement> T findChildElement(By childLoc, Class<? extends IElement> clazz, ElementState state);
default <T extends IElement> T findChildElement(By childLoc, Class<T> clazz, ElementState state) {
return findChildElement(childLoc, null, clazz, state);
}

/**
* Find an element in the parent element
* Find an element in the parent element with DISPLAYED state
*
* @param childLoc child element locator
* @param clazz class or interface of the element to be obtained
* @param <T> the type of the element to be obtained
* @return found child element
*/
default <T extends IElement> T findChildElement(By childLoc, Class<T> clazz) {
return findChildElement(childLoc, null, clazz, ElementState.DISPLAYED);
}

/**
* Finds an element in the parent element
*
* @param childLoc Child element locator
* @param name output name in logs
* @param supplier required element's supplier
* @param state visibility state of target element
* @param <T> the type of the element to be obtained
* @return found child element
*/
<T extends IElement> T findChildElement(By childLoc, String name, IElementSupplier<T> supplier, ElementState state);

/**
* Find an element in the parent element with DISPLAYED state
*
* @param childLoc child element locator
* @param name output name in logs
* @param supplier required element's supplier
* @param <T> the type of the element to be obtained
* @return found child element
*/
default <T extends IElement> T findChildElement(By childLoc, String name, IElementSupplier<T> supplier) {
return findChildElement(childLoc, name, supplier, ElementState.DISPLAYED);
}

/**
* Finds an element in the parent element
*
* @param childLoc child element locator
* @param supplier required element's supplier
* @param state visibility state of target element
* @param state visibility state of target element
* @param <T> the type of the element to be obtained
* @return found child element
*/
<T extends IElement> T findChildElement(By childLoc, IElementSupplier<T> supplier, ElementState state);
default <T extends IElement> T findChildElement(By childLoc, IElementSupplier<T> supplier, ElementState state) {
return findChildElement(childLoc, null, supplier, state);
}

/**
* Find an element in the parent element with DISPLAYED state
*
* @param childLoc child element locator
* @param supplier required element's supplier
* @param <T> the type of the element to be obtained
* @return found child element
*/
default <T extends IElement> T findChildElement(By childLoc, IElementSupplier<T> supplier) {
return findChildElement(childLoc, null, supplier, ElementState.DISPLAYED);
}
}
3 changes: 2 additions & 1 deletion src/main/resources/localization/be.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"loc.elements.were.found.but.not.in.state": "Знайшлі элементы па лакатару '%1$s', але яны не ў жаданым стане %2$s",
"loc.elements.found.but.should.not": "Не павінна быць знойдзена элементаў па лакатару '%1$s' у %2$s стане",
"loc.search.of.elements.failed": "Пошук элемента па лакатару '%1$s' прайшоў няўдала",
"loc.element.not.in.state": "Элемент %1$s ня стаў %2$s пасля таймаўта %3$s"
"loc.element.not.in.state": "Элемент %1$s не стаў %2$s пасля таймаўта %3$s",
"loc.get.page.source.failed": "Адбылася памылка ў час атрымання разметкі старонкі"
}
3 changes: 2 additions & 1 deletion src/main/resources/localization/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"loc.elements.were.found.but.not.in.state": "Elements were found by locator '%1$s' but not in desired state %2$s",
"loc.elements.found.but.should.not": "No elements should be found by locator '%1$s' in %2$s state",
"loc.search.of.elements.failed": "Search of element by locator '%1$s' failed",
"loc.element.not.in.state": "Element %1$s has not become %2$s after timeout %3$s"
"loc.element.not.in.state": "Element %1$s has not become %2$s after timeout %3$s",
"loc.get.page.source.failed": "An exception occurred while tried to save the page source"
}
3 changes: 2 additions & 1 deletion src/main/resources/localization/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"loc.elements.were.found.but.not.in.state": "Удалось найти элементы по локатору '%1$s', но они не в желаемом состоянии %2$s",
"loc.elements.found.but.should.not": "Не должно быть найдено элементов по локатору '%1$s' в %2$s состоянии",
"loc.search.of.elements.failed": "Поиск элемента по локатору '%1$s' прошел неудачно",
"loc.element.not.in.state": "Элемент %1$s не стал %2$s после таймаута %3$s"
"loc.element.not.in.state": "Элемент %1$s не стал %2$s после таймаута %3$s",
"loc.get.page.source.failed": "Произошла ошибка во время получения разметки страницы"
}
Loading