Skip to content

Instantly share code, notes, and snippets.

@mt1729
Created September 23, 2016 23:51
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mt1729/fd1e020dede2c18d845151f853a703a6 to your computer and use it in GitHub Desktop.
Save mt1729/fd1e020dede2c18d845151f853a703a6 to your computer and use it in GitHub Desktop.
Some Selenium/Appium helpers to use with PageFactory
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
/**
* Define custom ExpectedConditions here.
*/
public final class CustomExpectedConditions {
private CustomExpectedConditions() {}
/**
* Helper methods to return the element if its tag name is available (all found elements have a tag name)
* @return The element if found, else null to avoid exception propagation
*/
private static WebElement proxyFind(WebElement element) {
try {
element.getTagName();
return element;
}
catch(NoSuchElementException e) {
return null;
}
}
/**
* Intended to be used with explicit waits within 'page objects' so that elements can be found within
* other customized explicit waits.
*/
public static ExpectedCondition<WebElement> proxyElementLocated(final WebElement element) {
return new ExpectedCondition<WebElement>() {
@Override
public WebElement apply( WebDriver driver) {
return proxyFind(element);
}
@Override
public String toString() {
return "proxy presence of " + element;
}
};
}
/**
* First ensure presence of the element, then check for visibility
* @param element The element to evaluate
* @return The element if the condition is met, else null
*/
public static ExpectedCondition<WebElement> presenceAndVisibility(final WebElement element) {
return new ExpectedCondition<WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
WebElement proxy = proxyFind(element);
if(proxy != null && proxy.isDisplayed()) {
return proxy;
}
else {
return null;
}
}
@Override
public String toString() {
return "proxy presence and visibility of " + element;
}
};
}
/**
* First ensure presence of the element, then check whether or not it's enabled (clickable)
* @param element The element to evaluate
* @return The element if the condition is met, else null
*/
public static ExpectedCondition<WebElement> presenceAndClickability(final WebElement element) {
return new ExpectedCondition<WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
WebElement proxy = proxyFind(element);
try {
if (proxy != null && proxy.isEnabled()) {
return proxy;
} else {
return null;
}
}
catch(StaleElementReferenceException e) {
return null;
}
}
@Override
public String toString() {
return "proxy presence and clickability of " + element;
}
};
}
/**
* First ensure presence of the element, then check whether or not it's enabled (clickable)
* @param element The element to evaluate
* @return The element if the condition is met, else null
*/
public static ExpectedCondition<Boolean> isAbsent(final WebElement element) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
element.getTagName();
return false;
}
catch(NoSuchElementException e) {
return true;
}
}
@Override
public String toString() {
return "proxy absence of " + element;
}
};
}
}
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.util.concurrent.*;
public class DriverHelper {
public static final int NETWORK_TIMEOUT = 60;
/**
* Attempt to find an element on the page using a given locator
* @param driver The driver currently in use
* @param by The locating method to find the element
* @return Element if found, else null
*/
public static WebElement findElement(WebDriver driver, By by) {
try {
return driver.findElement(by);
}
catch(NoSuchElementException e) {
return null;
}
}
/**
* Check if an element currently exists by reading its tag
* @param element The element to find
* @return True if present, else false
*/
public static boolean elementExists(WebElement element) {
try {
return element.getTagName() != null;
}
catch(NoSuchElementException e) {
return false;
}
}
/**
* Shorthand for waiting for presence and visibility of an element
* @param driver The driver currently in use
* @param element The element to wait for
*/
public static void presenceAndVisibilityWait(WebDriver driver, WebElement element, int timeout) {
(new WebDriverWait(driver, timeout)).until(CustomExpectedConditions.presenceAndVisibility(element));
}
/**
* Shorthand for waiting for presence and clickability of an element
* @param driver The driver currently in use
* @param element The element to wait for
*/
public static void presenceAndClickabilityWait(WebDriver driver, WebElement element, int timeout) {
(new WebDriverWait(driver, timeout)).until(CustomExpectedConditions.presenceAndClickability(element));
}
/**
* Shorthand for waiting for an element to not be present
* @param driver The driver currently in use
* @param element The element to wait for
*/
public static void isAbsentWait(WebDriver driver, WebElement element, int timeout) {
(new WebDriverWait(driver, timeout)).until(CustomExpectedConditions.isAbsent(element));
}
/**
* Creates a new {@link WebElementCallable} for each proxy element. The first element found will be returned.
* @param timeout The number of seconds to wait up to on the main thread and in each callable
* @param elements Any number of elements to search for
* @return The first element if one found within timeout
*/
public static WebElement waitForAnyElementVisible(WebDriver driver, int timeout, WebElement... elements) {
ExecutorService service = Executors.newFixedThreadPool(elements.length);
ExecutorCompletionService<WebElement> complete = new ExecutorCompletionService<>(service);
// Start callables in the order passed in
for(final WebElement element : elements) {
complete.submit(new WebElementCallable(driver, timeout, element));
}
try {
// Wait for the first callable to be done
Future<WebElement> firstDone = complete.poll(timeout, TimeUnit.SECONDS);
// Cancel all remaining callables
service.shutdownNow();
try {
return firstDone.get();
}
catch(NullPointerException e) {
return null;
}
}
catch(InterruptedException | ExecutionException e) {
e.printStackTrace();
return null;
}
}
/**
* Represents a new thread to run that will wait for an element to appear
*/
private static class WebElementCallable implements Callable<WebElement> {
private WebDriver driver;
private int timeout;
private WebElement element;
public WebElementCallable(WebDriver driver, int timeout, WebElement element) {
this.driver = driver;
this.timeout = timeout;
this.element = element;
}
public WebElement call() {
return (new WebDriverWait(driver, timeout)).until(CustomExpectedConditions
.presenceAndVisibility(element));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment