package org.fluentlenium.core.inject;
import lombok.experimental.Delegate;
import org.fluentlenium.core.label.FluentLabelImpl;
import org.fluentlenium.core.label.FluentLabelProvider;
import org.openqa.selenium.By;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.pagefactory.ElementLocator;
import java.util.List;
import java.util.function.Supplier;
/**
* The injection element locator, which will lazily locate an element or an element list on a page. This class is
* designed for use with the {@link org.openqa.selenium.support.PageFactory} and understands the
* annotations {@link org.openqa.selenium.support.FindBy} and {@link org.openqa.selenium.support.CacheLookup}.
*/
public class InjectionElementLocator implements ElementLocator, FluentLabelProvider {
private final SearchContext searchContext;
private final boolean shouldCache;
private final By by;
private final boolean isFirst;
private WebElement cachedElement;
private List<WebElement> cachedElementList;
private final FluentLabelImpl<InjectionElementLocator> label;
/**
* Use this constructor in order to process custom annotaions.
*
* @param searchContext The context to use when finding the element
* @param annotations InjectionAnnotations class implementation
* @param isFirst Is this locator used to retrieve list or single element.
*/
public InjectionElementLocator(SearchContext searchContext, InjectionAnnotations annotations, boolean isFirst) {
this.searchContext = searchContext;
shouldCache = annotations.isLookupCached();
by = annotations.buildBy();
this.isFirst = isFirst;
label = new FluentLabelImpl<>(this, new Supplier<String>() {
@Override
public String get() {
return by.toString() + (InjectionElementLocator.this.isFirst ? " (first)" : "");
}
});
label.withLabel(annotations.getLabel());
label.withLabelHint(annotations.getLabelHints());
}
@Delegate
private FluentLabelProvider getLabelProvider() { // NOPMD UnusedPrivateMethod
return label;
}
/**
* Find the element.
*
* @return then found element
*/
public WebElement findElement() {
if (cachedElement != null && shouldCache) {
return cachedElement;
}
WebElement element = searchContext.findElement(by);
if (shouldCache) {
cachedElement = element;
}
return element;
}
/**
* Find the element list.
*
* @return list of found elements
*/
public List<WebElement> findElements() {
if (cachedElementList != null && shouldCache) {
return cachedElementList;
}
List<WebElement> elements = searchContext.findElements(by);
if (shouldCache) {
cachedElementList = elements;
}
return elements;
}
@Override
public String toString() {
return label.toString();
}
}