package my.webdriver.helper;
import java.lang.reflect.Method;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.InvalidElementStateException;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.internal.FindsByCssSelector;
import org.openqa.selenium.remote.RemoteWebElement;
public abstract class ByExtended extends By {
public static By cssSelector(final String selector) {
if (selector == null)
throw new IllegalArgumentException(
"Cannot find elements when the selector is null");
return new ByCssSelectorExtended(selector);
}
public static class ByCssSelectorExtended extends ByCssSelector {
private String ownSelector;
public ByCssSelectorExtended(String selector) {
super(selector);
ownSelector = selector;
}
@Override
public WebElement findElement(SearchContext context) {
try {
if (context instanceof FindsByCssSelector) {
return ((FindsByCssSelector) context)
.findElementByCssSelector(ownSelector);
}
} catch (InvalidElementStateException e) {
return findElementBySizzleCss(context, ownSelector);
} catch (WebDriverException e) {
if (e.getMessage().startsWith(
"An invalid or illegal string was specified")) {
return findElementBySizzleCss(context, ownSelector);
}
throw e;
}
throw new WebDriverException("Driver does not support finding an element by selector: " + ownSelector);
}
@Override
public List<WebElement> findElements(SearchContext context) {
try {
if (context instanceof FindsByCssSelector) {
return ((FindsByCssSelector) context)
.findElementsByCssSelector(ownSelector);
}
} catch (InvalidElementStateException e) {
return findElementsBySizzleCss(context, ownSelector);
} catch (WebDriverException e) {
if (e.getMessage().startsWith(
"An invalid or illegal string was specified")) {
return findElementsBySizzleCss(context, ownSelector);
}
throw e;
}
throw new WebDriverException("Driver does not support finding an element by selector: " + ownSelector);
}
@Override
public String toString() {
return "ByExtended.selector: " + ownSelector;
}
* Find element by sizzle css.
* @param context
*
* @param cssLocator
* the cssLocator
* @return the web element
*/
@SuppressWarnings("unchecked")
public WebElement findElementBySizzleCss(SearchContext context, String cssLocator) {
List<WebElement> elements = findElementsBySizzleCss(context, cssLocator);
if (elements != null && elements.size() > 0 ) {
return elements.get(0);
}
return null;
}
private void fixLocator(SearchContext context, String cssLocator,
WebElement element) {
if (element instanceof RemoteWebElement) {
try {
Class[] parameterTypes = new Class[] { SearchContext.class,
String.class, String.class };
Method m = element.getClass().getDeclaredMethod(
"setFoundBy", parameterTypes);
m.setAccessible(true);
Object[] parameters = new Object[] { context,
"css selector", cssLocator };
m.invoke(element, parameters);
} catch (Exception fail) {
}
}
}
* Find elements by sizzle css.
*
* @param cssLocator
* the cssLocator
* @return the list of the web elements that match this locator
*/
@SuppressWarnings("unchecked")
public List<WebElement> findElementsBySizzleCss(SearchContext context, String cssLocator) {
injectSizzleIfNeeded();
String javascriptExpression = createSizzleSelectorExpression(cssLocator);
List<WebElement> elements = (List<WebElement>) ((JavascriptExecutor) getDriver())
.executeScript(javascriptExpression);
if (elements.size() > 0) {
for (WebElement el : elements) {
fixLocator(context, cssLocator, el);
}
}
return elements;
}
private JavascriptExecutor getDriver() {
return null;
}
* Creates the sizzle selector expression.
*
* @param cssLocator
* the cssLocator
* @return string that represents the sizzle selector expression.
*/
private String createSizzleSelectorExpression(String cssLocator) {
return "return Sizzle(\"" + cssLocator + "\")";
}
* Inject sizzle if needed.
*/
private void injectSizzleIfNeeded() {
if (!sizzleLoaded())
injectSizzle();
}
* Check if the Sizzle library is loaded.
*
* @return the true if Sizzle is loaded in the web page
*/
public Boolean sizzleLoaded() {
Boolean loaded;
try {
loaded = (Boolean) ((JavascriptExecutor) getDriver())
.executeScript("return Sizzle()!=null");
} catch (WebDriverException e) {
loaded = false;
}
return loaded;
}
* Inject sizzle 1.8.2
*/
public void injectSizzle() {
((JavascriptExecutor) getDriver())
.executeScript(" var headID = document.getElementsByTagName(\"head\")[0];"
+ "var newScript = document.createElement('script');"
+ "newScript.type = 'text/javascript';"
+ "newScript.src = 'https://raw.github.com/jquery/sizzle/1.8.2/sizzle.js';"
+ "headID.appendChild(newScript);");
}
* ******************** SIZZLE SUPPORT CODE
*/
}
}