Взаимодействие Selenium с DOM кажется чрезвычайно медленным при выполнении нескольких действий при каждом создании экземпляра страницы. На всем сайте у нас есть видимый счетчик, который указывает на любые ожидающие вызовы API, разрешенные или нет. Таким образом, у меня есть три метода, которые обеспечивают стабильность страницы перед выполнением каких-либо действий.
- Проверить состояние готовности DOM
- Проверьте наличие невыполненных вызовов JQuery.
- Проверить загрузку спиннеров
Все эти три выполняются как часть создания экземпляра объекта страницы с помощью следующих методов.
public static void waitForLoadingAllSpinnersAnywhere(final WebDriver driver){
final WebDriverWait wait = new WebDriverWait(driver, timeout);
wait.until(waitForDomReadyState());
wait.until(waitForjQueryToBeInactive());
List<WebElement> elements = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(spinnersLoacator));
for(WebElement element: elements){
wait.until(invisibilityOfElementLocated(element));
}
}
private static ExpectedCondition<Boolean> waitForDomReadyState(){
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver d){
return ( ((JavascriptExecutor) d).executeScript("return document.readyState;").equals("complete"));
}
};
}
private static ExpectedCondition<Boolean> waitForjQueryToBeInactive(){
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver d){
return (Boolean) ( ((JavascriptExecutor) d).executeScript("return jQuery.active == 0;"));
}
};
}
public static ExpectedCondition<Boolean> invisibilityOfElementLocated(final WebElement element){
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver){
try{
return !element.isDisplayed();
} catch (NoSuchElementException | StaleElementReferenceException e){
// Returns true because the element is not present in DOM.
// The
// try block checks if the element is present but is
// invisible or stale
return true;
}
}
};
}
Возьмем пример страницы (скажем, страницы пациента), которая имеет большое количество вызовов API и извлекает много данных. Для создания начального класса требуется около 17 секунд (журнал ниже). Мои знания Selenium говорят, что последующее создание экземпляра страницы не должно занимать столько же или больше времени, чтобы проверить состояние готовности DOM, или вызов JQuery или ожидание счетчика, поскольку вообще ничего не меняется. Однако каждый раз, когда создается экземпляр новой страницы, я вижу, что проверка всех этих трех занимает одинаковое количество времени. Что там происходит? Действительно ли Selenium пытается взаимодействовать с сервером каждый раз, когда я это делаю, или просто взаимодействие с клиентом по какой-то причине происходит медленно? Если да, то каким может быть возможный ответ?
Журнал консоли
==== [[Завершено ожидание 8 элементов счетчика, найденных в виджете [Пациент] после [17] с]]
==== [[Начать ожидание 8 элементов счетчика, найденных в виджете [Пациент] ]]
==== [[Завершено ожидание 8 элементов счетчика, найденных в виджете [Пациент] после [17] с]]
==== Браузер на [[[Patient]]]
==== [[Начать ожидание 8 элементов счетчика, найденных в виджете [Пациент] ]]
==== [[Завершено ожидание 8 элементов счетчика, найденных в виджете [Пациент] после [17] с]]
Окружающая среда:
- Селен 2.48
- Фаерфокс 38
Я также пробовал с Selenium 2.52 и Firefox 44 с тем же результатом.