Created
September 23, 2016 23:51
-
-
Save mt1729/fd1e020dede2c18d845151f853a703a6 to your computer and use it in GitHub Desktop.
Some Selenium/Appium helpers to use with PageFactory
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
}; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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