package org.syftkog.web.test.framework;
import org.syftkog.web.test.framework.ExpectedConditionsAdditional;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.openqa.selenium.By;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.InvalidSelectorException;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;
/**
*
* @author BenjaminLimb
*/
public class SeleniumHelperUtil {
/**
* convertToBy: is a method that follows the general guidlines of Selenium
* Element Locators as defined at:
* http://release.seleniumhq.org/selenium-remote-control/0.9.2/doc/dotnet/Selenium.ISelenium.html
* We use this method to simplify the "find element by" commands:
* waitForElementPresent("#ID .CLASS div a[ATTRIBUTE=\"something\"]) or
* waitForElementPresent("//div/") or waitForElementPresent("id=happy") or
* just about any other combination... see comments in-line.
*
* @param selectorString
* @return the By
*/
public static By convertToBy(String selectorString) {
if (selectorString == null || selectorString.isEmpty()) {
throw new InvalidSelectorException("Invalid parameter: " + selectorString);
}
String[] parts = selectorString.split("=");
By findBy;
if (parts.length > 1) {
String getType = parts[0];
String key = selectorString.substring(getType.length() + 1); //Separate the type and the key on the '=' character
if (getType.equalsIgnoreCase("css")) { //Check to see if it is CSS
findBy = By.cssSelector(key); //"css=#something.somethingElse" should findBy By.cssSelector <id="something" class="somethingElse">
} else if (getType.equalsIgnoreCase("identifier") || getType.equalsIgnoreCase("id")) { //Check to see if it is an ID
findBy = By.id(key); //"identifier=something" should findBy By.id <id="something">
} else if (getType.equalsIgnoreCase("link")) { //Check to see if it is a LINK
findBy = By.linkText(key); //"link=something" should findBy By.linkText <a href="http://www.google.com/search?q=something">something</a>
} else if (getType.equalsIgnoreCase("name")) { //Check to see if it is a NAME
findBy = By.name(key); //"name=something" should findBy By.name <id="dude" name="something">
} else if (getType.equalsIgnoreCase("tag")) { //Check to see if it is a TAG
findBy = By.tagName(key); //"tag=a" should findBy By.tagName <a href="http://www.google.com/search?q=something">something</a>
} else if (getType.equalsIgnoreCase("xpath")) { //Check to see if it is an XPATH
findBy = By.xpath(key); //"xpath=//div/article/div[4]/div[3]" should findBy By.xpath first div, first article in first div, 4 divs down inside article, 3 divs down inside the 4th div down
} else {
findBy = null; //If it is neither identified as CSS, an ID, a LINK, a NAME, a TAG, or an XPATH, then make it NULL
}
} else {
findBy = null; //If it is empty, make it NULL
}
// if findBy is NULL, check to see if it is XPATH with a single "/" (more generic search), or check if it is an ID,
// Class, Attribute, Tag, etc... and if not, assume it is CSS, try anyway... or run it as ID and fail.
if (findBy == null) { //CHeck to see if findBy is a NULL, which means the string isn't identified, or it was empty.
if (selectorString.startsWith("/")) { //Check to see if it is a default XPATH
findBy = By.xpath(selectorString); //If it starts with "//" or "/" it is an XPATH (// = more specific, / = less specific)
} else if (selectorString.startsWith("#") || selectorString.startsWith(".") || selectorString.startsWith("[")) { //Check to see if it is an ID (#), a CLASS (.) or an ATTRIBUTE ([)
findBy = By.cssSelector(selectorString); //If any of these (CLASS, ID, ATTRIBUTE) then treat it like CSS
} else if (!selectorString.isEmpty()) { //If it is NOT XPATH and NOT an ID, CLASS or ATTRIBUTE, then treat it like CSS, it may be a tag or other element
findBy = By.cssSelector(selectorString);
} else { //FAILSAFE: if it is not any of the above, use this to fail the selection.
findBy = By.id(selectorString);
}
}
return findBy;
}
/**
*
* @param desiredCapabilities
* @param availableCapabilities
* @return
*/
public static boolean capabilitiesOfDesiredMatchAvailable(Capabilities desiredCapabilities, Capabilities availableCapabilities) {
// if(!desiredCapabilities.getBrowserName().equalsIgnoreCase(availableCapabilities.getBrowserName())){
// return false;
// }
// if(!desiredCapabilities.getVersion().equalsIgnoreCase(availableCapabilities.getVersion())){
// return false;
// }
// this check to for all capabilities , not just browser and version
for (Map.Entry<String, ?> entry : desiredCapabilities.asMap().entrySet()) {
String key = entry.getKey();
Object value = (Object) entry.getValue();
if (value != null && !value.toString().toLowerCase().equals("") && !value.toString().toLowerCase().equals("any")) {
Object availableCapability = availableCapabilities.getCapability(key);
if (availableCapability == null || !availableCapability.toString().equalsIgnoreCase(value.toString())) {
return false;
}
}
}
return true;
}
/**
*
* @param dimension
* @return
*/
public static Dimension toDimension(String dimension) {
String[] sizes = dimension.toLowerCase().split("x");
return new Dimension(Integer.parseInt(sizes[0]), Integer.parseInt(sizes[1]));
}
/**
*
* @param driver
* @param urlPart
* @param secondsToWait
*/
public static void waitForUrlToContain(WebDriver driver, String urlPart, Integer secondsToWait) {
Wait<WebDriver> wait = new WebDriverWait(driver, secondsToWait);
wait.until(ExpectedConditionsAdditional.urlToContain(urlPart));
}
/**
*
* @param driver
* @param secondsToWait
*/
public static void waitForJQueryExists(WebDriver driver, Integer secondsToWait) {
Wait<WebDriver> wait = new WebDriverWait(driver, secondsToWait);
wait.until(ExpectedConditionsAdditional.jQueryExists());
}
/**
*
* @param driver
* @param secondsToWait
*/
public static void waitForJQueryNotActive(WebDriver driver, Integer secondsToWait) {
Wait<WebDriver> wait = new WebDriverWait(driver, secondsToWait);
wait.until(ExpectedConditionsAdditional.jQueryNotActive());
}
/**
*
* @param driver
* @param secondsToWait
*/
public static void waitForJQueryExistsAndNotActive(WebDriver driver, Integer secondsToWait) {
Wait<WebDriver> wait = new WebDriverWait(driver, secondsToWait);
wait.until(ExpectedConditionsAdditional.jQueryExists());
wait.until(ExpectedConditionsAdditional.jQueryNotActive());
}
/**
* It may take half a second for this action to complete.
*
* @param driver
* @param el
*/
public static void scrollIntoViewThenClick(WebDriver driver, WebElement el) {
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", el);
//TODO: This may need a wait time for stability.
el.click();
}
/**
*
* @param sc
* @param by
* @return
*/
public static List<WebElement> findVisibleElements(SearchContext sc, By by) {
List<WebElement> elements = sc.findElements(by);
Iterator<WebElement> it = elements.iterator();
while (it.hasNext()) {
WebElement el = it.next();
if (!el.isDisplayed()) {
it.remove();
}
}
return elements;
}
}