Ответ 1
Ты не хочешь. Селекторы JQuery предлагают большую часть селекторов CSS 2 и CSS 3, плюс что-то большее, но вы, вероятно, можете жить без него. Если вы знаете селекторы JQuery, вы уже знаете селектор CSS.
Используйте селектор CSS, где вы можете использовать выражения XPath, где это недостаточно (они сильнее). Я сомневаюсь, что вы найдете много реальных обычаев, где этих двух недостаточно (и тогда обычный подход заключается в том, чтобы получить то, что вы можете, и перебрать по коллекции, отфильтровывая результаты вручную).
Тем не менее, вы можете заставить WebDriver также принимать селектора JQuery:
Если вы хотите поддерживать только один или два браузера, самым простым способом может быть создание простого аддона для этого браузера, который будет вводить JQuery на каждую страницу, если он еще не присутствует. Затем вы будете использовать этот аддон для использования браузером, который вы используете.
Если вы хотите поддерживать все браузеры, это решение быстро становится бременем, и лучше всего вы можете написать декоратор для WebDriver, который попытается вставить JQuery на страницу перед любым findElements()
и/или executeScript()
вызов, если он еще не присутствует.
См. этот вопрос, чтобы получить представление о введении JQuery.
После того, как вы ввели его, вы можете использовать его снова, только через JavaScript:
// earlier
if (driver instanceof JavascriptExecutor) {
js = (JavascriptExecutor)driver;
} else {
throw new IllegalStateException("This driver cannot run JavaScript.");
}
WebElement element = (WebElement)js.executeScript("$('div.account').get(0)");
// or
List<WebElement> elements = (List<WebElement>)js.executeScript("$('div.account').get()");
Вы можете легко обернуть эти строки в новый объект By
или новый findElement(String jQuerySelector)
метод для вашего украшенного WebDriver, если хотите, но это для вашего удобства и лень, мы получили его работу...
Лучшим подходом, я думаю, было бы создание новой реализации By
под названием ByJQuery
. См. этот ответ о том, как сделать ByJavaScript
- это небольшой шаг оттуда, чтобы повторно использовать его, вставить JQuery на страницу и запустить фактический запрос.
class ByJQuery extends By implements Serializable {
private final String query;
public ByJQuery(String query) {
checkNotNull(query, "Cannot find elements with a null JQuery expression.");
this.query = query;
}
@Override
public List<WebElement> findElements(SearchContext context) {
WebDriver driver = getWebDriverFromSearchContext(context);
if (!isJQueryInThisPage(driver)) {
injectJQuery(driver);
}
return new ByJavaScript("return $(" + query + ")").findElements(context);
}
private static WebDriver getWebDriverFromSearchContext(SearchContext context) {
if (context instanceof WebDriver) {
return (WebDriver)context;
}
if (context instanceof WrapsDriver) {
return ((WrapsDriver)context).getWrappedDriver();
}
throw new IllegalStateException("Can't access a WebDriver instance from the current search context.");
}
private static boolean isJQueryInThisPage(WebDriver driver) {
// TODO Some JavaScript test for a JQuery object.
}
private static void injectJQuery(WebDriver driver) {
// TODO Load JQuery from a file, inject it into the page via JS.
}
@Override
public String toString() {
return "By.jQuery: \"$(" + query + ")\"";
}
}