package com.abmash.api.browser;
import com.abmash.REMOVE.api.HtmlQuery;
import com.abmash.api.Browser;
import com.abmash.api.HtmlElement;
import com.abmash.api.query.Query;
import com.abmash.api.query.QueryFactory;
import com.abmash.core.browser.waitcondition.ElementHasTextWaitCondition;
import com.abmash.core.browser.waitcondition.ElementWaitCondition;
import com.abmash.core.browser.waitcondition.JavaScriptEvaluatedWaitCondition;
import com.thoughtworks.selenium.Wait;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.WebDriverWait;
/**
* Waits for the browser, used by calling {@link Browser#waitFor()}.
* <p>
* Sometimes it is necessary to wait for the web page, which needs to complete loading page elements.
* This is usually the case when JavaScript gets executed, mostly AJAX calls. Wait conditions can be
* customized by specifying own JavaScript code.
*
* @author Alper Ortac
*/
public class WaitFor {
public static final int DEFAULT_TIMEOUT_ON_WAIT = 20;
private Browser browser;
private int timeout;
/**
* Constructs new BrowserWait instance to be able to define wait conditions.
* <p>
* The default timeout length is {@value #DEFAULT_TIMEOUT_ON_WAIT} seconds.
*
* @param browser <code>Browser</code> instance to work with
*/
public WaitFor(Browser browser) {
this(browser, DEFAULT_TIMEOUT_ON_WAIT);
}
/**
* Constructs new BrowserWait instance to be able to define wait conditions.
*
* @param browser <code>Browser</code> instance to work with
* @param timeout wait for this amount of seconds until a timeout exception is thrown
*/
public WaitFor(Browser browser, int timeout) {
this.browser = browser;
this.timeout = timeout;
}
/**
* Waits until element is found. Useful for waiting for an AJAX call to complete.
*
* @param query the element query
* @throws TimeoutException
*/
public void query(Query query) throws TimeoutException {
// WebDriverWait wait = new WebDriverWait(browser.getWebDriver(), timeout);
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(browser.getWebDriver())
.withTimeout(timeout, TimeUnit.SECONDS)
.pollingEvery(500, TimeUnit.MILLISECONDS);
// start waiting for given element
wait.until(new ElementWaitCondition(browser, query));
}
/**
* Waits until element is found. Useful for waiting for an AJAX call to complete.
*
* @param query the element which needs to be found, identified by the visible text or attribute values
* @throws TimeoutException
*/
public void element(String query) throws TimeoutException {
query(browser.query(QueryFactory.contains(query)));
}
/**
* Waits until element contains the specified text. Useful for waiting for an AJAX call to complete.
*
* @param element the element to observe
* @param text when the element contains this text the execution of the program will be continued
* @throws TimeoutException
*/
public void elementText(HtmlElement element, String text) throws TimeoutException {
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(browser.getWebDriver())
.withTimeout(timeout, TimeUnit.SECONDS)
.pollingEvery(500, TimeUnit.MILLISECONDS);
// start waiting for given text of element
wait.until(new ElementHasTextWaitCondition(element, text));
}
/**
* Waits until element contains the specified text. Useful for waiting for an AJAX call to complete.
*
* @param query the found element should contain the text or attribute value specified here
* @param text when the element contains this text the execution of the program will be continued
* @throws TimeoutException
*/
public void elementText(String query, String text) throws TimeoutException {
// wait until element is found
element(text);
// wait until element text is detected
elementText(browser.query(QueryFactory.contains(query)).findFirst(), text);
}
/**
* Waits until the specified JavaScript returns a non-false value.
*
* @param expression the JavaScript expression to evaluate
* @param timeout time in seconds to wait until a TimeoutException is thrown
* @throws TimeoutException
*/
public void evaluatedJavaScriptExpression(String expression, int timeout) throws TimeoutException {
WebDriverWait wait = new WebDriverWait(browser.getWebDriver(), timeout);
// start waiting for adequate evaluation of expression
wait.until(new JavaScriptEvaluatedWaitCondition(browser, expression));
}
/**
* Waits until the specified JavaScript returns a non-false value.
*
* @param expression the JavaScript expression to evaluate
* @throws TimeoutException
*/
public void evaluatedJavaScriptExpression(String expression) throws TimeoutException {
evaluatedJavaScriptExpression(expression, DEFAULT_TIMEOUT_ON_WAIT);
}
}