package com.codeborne.selenide.impl;
import com.codeborne.selenide.Condition;
import com.codeborne.selenide.SelenideElement;
import com.codeborne.selenide.ex.ElementNotFound;
import com.codeborne.selenide.ex.ElementShould;
import com.codeborne.selenide.ex.ElementShouldNot;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.util.List;
import static com.codeborne.selenide.Condition.not;
import static com.codeborne.selenide.Condition.visible;
import static java.util.Collections.singletonList;
public abstract class WebElementSource {
public abstract WebElement getWebElement();
public abstract String getSearchCriteria();
public SelenideElement find(SelenideElement proxy, Object arg, int index) {
return ElementFinder.wrap(proxy, getSelector(arg), index);
}
public List<WebElement> findAll() throws IndexOutOfBoundsException {
return singletonList(getWebElement());
}
public ElementNotFound createElementNotFoundError(Condition condition, Throwable lastError) {
return new ElementNotFound(getSearchCriteria(), condition, lastError);
}
public static By getSelector(Object arg) {
return arg instanceof By ? (By) arg : By.cssSelector((String) arg);
}
public WebElement checkCondition(String prefix, String message, Condition condition, boolean invert) {
Condition check = invert ? not(condition) : condition;
Throwable lastError = null;
WebElement element = null;
try {
element = getWebElement();
if (element != null && check.apply(element)) {
return element;
}
}
catch (Throwable e) {
lastError = e;
}
if (Cleanup.of.isInvalidSelectorError(lastError)) {
throw Cleanup.of.wrap(lastError);
}
if (element == null) {
if (!check.applyNull()) {
throw createElementNotFoundError(check, lastError);
}
}
else if (invert) {
throw new ElementShouldNot(getSearchCriteria(), prefix, message, condition, element, lastError);
}
else {
throw new ElementShould(getSearchCriteria(), prefix, message, condition, element, lastError);
}
return null;
}
public WebElement findAndAssertElementIsVisible() {
return checkCondition("be ", null, visible, false);
}
}