package com.algocrafts.forms; import com.algocrafts.algorithm.Retry; import com.algocrafts.conditions.Equals; import com.algocrafts.conditions.StringContains; import com.algocrafts.converters.FirstMatch; import com.algocrafts.locators.Locators; import com.algocrafts.selenium.Element; import com.algocrafts.selenium.Locating; import com.algocrafts.selenium.Locator; import com.algocrafts.selenium.SearchScope; import org.openqa.selenium.By; import org.openqa.selenium.support.ui.FluentWait; import org.slf4j.Logger; import java.util.Optional; import java.util.function.Supplier; import java.util.stream.Stream; import static com.algocrafts.converters.GetText.TEXT; import static com.algocrafts.converters.GetText.VALUE; import static com.algocrafts.converters.OptionalGetter.GET; import static java.util.concurrent.TimeUnit.SECONDS; import static org.slf4j.LoggerFactory.getLogger; public class Input<T extends SearchScope<T>> extends Locating<T, Optional<Element>> { public static final Logger log = getLogger(Input.class); /** * Constructor of the input field. * * @param where where * @param selector selector */ public Input(T where, Supplier<By> selector) { super(where, Locators.<T>optionalElement(selector)); } /** * the value of input field, for example, "good" will be return * <p> * String value = page.get(() -> By.name("status")) * <p> * <input name="status" value="good"/> * * @return the value of the input */ public String getValue() { final Retry retry = new Retry(5, 1, SECONDS); try { return retry.attempt(() -> locate(GET.andThen(VALUE))); } catch (Exception e) { log.info("Failed to read text", e); } return null; } /** * set the value of input field, for example, * <p> * after, * page.set(() -> By.name("status"), "good"); * <p> * it will be, * <input name="status" value="good"/> * * @param value the value to set */ public void put(final Object value) { String string = value.toString(); final Retry retry = new Retry(5, 1, SECONDS); try { retry.attempt(() -> { Element element = locate(GET); element.clear(); element.sendKeys(string); if (VALUE.and(new Equals(string)).test(element)) { retry.off(); } return null; }); } catch (Exception e) { log.info("Failed to set text {}", string); } } /** * Test the autocomplete function for the input by given value, click the element * on the suggestion list which matches value parameter. * <p> * Please refer "http://seleniumcapsules.blogspot.com/2014/05/by-xpath.html" * * @param value value * @param locator locator */ public void autocomplete(Object value, Locator<T, Stream<Element>> locator) { Element element = locate(GET); element.clear(); Locator<T, Optional<Element>> optionalLocator = locator.andThen(new FirstMatch<>(TEXT.and(new StringContains(value.toString())))); for (char c : value.toString().toCharArray()) { element.sendKeys(String.valueOf(c)); Optional<Element> locate = use(optionalLocator); if (locate.isPresent()) { locate.get().click(); } } new FluentWait<>(this).ignoring(Exception.class).until((Input i) -> use(optionalLocator).get()).click(); } }