Вопрос-ответ

Do we have any generic function to check if page has completely loaded in Selenium

Есть ли у нас какая-либо универсальная функция для проверки полной загрузки страницы в Selenium

Я пытаюсь проверить, завершена ли загрузка веб-страницы или нет (т. Е. Проверяю, загружен ли весь элемент управления) в selenium.

Я попробовал приведенный ниже код:

new WebDriverWait(firefoxDriver, pageLoadTimeout).until(
webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));

но даже если страница загружается, приведенный выше код не ожидает.

Я знаю, что могу проверить конкретный элемент, чтобы проверить, виден ли он / кликабелен и т.д., Но я ищу какое-то универсальное решение

Переведено автоматически
Ответ 1

Как вы упомянули, если есть какая-либо универсальная функция для проверки полной загрузки страницы через Selenium, ответ - Нет.

Сначала давайте посмотрим на вашу пробную версию кода, которая выглядит следующим образом :

new WebDriverWait(firefoxDriver, pageLoadTimeout).until(webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));

Параметр pageLoadTimeout в приведенной выше строке кода на самом деле не выполняет повторную выборку в фактический pageLoadTimeout().

Здесь вы можете найти подробное обсуждение того, что pageLoadTimeout в Selenium не работает


Теперь, поскольку ваш usecase относится к полной загрузке страницы, вы можете использовать pageLoadStrategy(), для которогоnormal установлено значение [ поддерживаемые значения - none, eagleed или normal ], используя либо через экземпляр класса DesiredCapabilities, либо через класс ChromeOptions, как указано ниже :


  • Использование класса DesiredCapabilities :


     import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.firefox.FirefoxOptions;
    import org.openqa.selenium.remote.DesiredCapabilities;

    public class myDemo
    {
    public static void main(String[] args) throws Exception
    {
    System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
    DesiredCapabilities dcap = new DesiredCapabilities();
    dcap.setCapability("pageLoadStrategy", "normal");
    FirefoxOptions opt = new FirefoxOptions();
    opt.merge(dcap);
    WebDriver driver = new FirefoxDriver(opt);
    driver.get("https://www.google.com/");
    System.out.println(driver.getTitle());
    driver.quit();
    }
    }

  • Использование класса ChromeOptions :


    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.firefox.FirefoxOptions;
    import org.openqa.selenium.PageLoadStrategy;

    public class myDemo
    {
    public static void main(String[] args) throws Exception
    {
    System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
    FirefoxOptions opt = new FirefoxOptions();
    opt.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new FirefoxDriver(opt);
    driver.get("https://www.google.com/");
    System.out.println(driver.getTitle());
    driver.quit();
    }
    }

Подробное обсуждение вы можете найти в Стратегия загрузки страницы для драйвера Chrome (обновлена до версии Selenium v3.12.0)


Теперь, установив для pageLoadStrategy значение NORMAL, и ваша пробная версия кода гарантируют, что браузерный клиент (т. Е. веб-браузер) достиг 'document.readyState' значения"complete". Как только это условие выполнено, Selenium выполняет следующую строку кода.

Подробное обсуждение вы можете найти в Selenium IE WebDriver работает только во время отладки

Но достижение клиентом браузера 'document.readyState' значения"complete" по-прежнему не гарантирует, что все JavaScript и Ajax вызовы завершены.


Чтобы дождаться завершения всех вызовов JavaScript и Ajax, вы можете написать функцию следующим образом :

public void WaitForAjax2Complete() throws InterruptedException
{
while (true)
{
if ((Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")){
break;
}
Thread.sleep(100);
}
}

You can find a detailed discussion in Wait for ajax request to complete - selenium webdriver


Now, the above two approaches through PageLoadStrategy and "return jQuery.active == 0" looks to be waiting for indefinite events. So for a definite wait you can induce WebDriverWait inconjunction with ExpectedConditions set to titleContains() method which will ensure that the Page Title (i.e. the Web Page) is visible and assume the all the elements are also visible as follows :

driver.get("https://www.google.com/");
new WebDriverWait(driver, 10).until(ExpectedConditions.titleContains("partial_title_of_application_under_test"));
System.out.println(driver.getTitle());
driver.quit();

Now, at times it is possible though the Page Title will match your Application Title still the desired element you want to interact haven't completed loading. So a more granular approach would be to induce WebDriverWait inconjunction with ExpectedConditions set to visibilityOfElementLocated() method which will make your program wait for the desired element to be visible as follows :

driver.get("https://www.google.com/");
WebElement ele = new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("xpath_of_the_desired_element")));
System.out.println(ele.getText());
driver.quit();

References

You can find a couple of relevant detailed discussions in:

Ответ 2

I use selenium too and I had the same problem, to fix that I just wait also for the jQuery to load.

So if you have the same issue try this also

((Long) ((JavascriptExecutor) browser).executeScript("return jQuery.active") == 0);

You can wrap both function in a method and check until both page and jQuery is loaded

Ответ 3

Implement this, Its working for many of us including me. It includes Web Page wait on JavaScript, Angular, JQuery if its there.

If your Application is containing Javascript & JQuery you can write code for only those,

By define it in single method and you can Call it anywhere:

          // Wait for jQuery to load
{
ExpectedCondition<Boolean> jQueryLoad = driver -> ((Long) ((JavascriptExecutor) driver).executeScript("return jQuery.active") == 0);

boolean jqueryReady = (Boolean) js.executeScript("return jQuery.active==0");

if (!jqueryReady) {
// System.out.println("JQuery is NOT Ready!");
wait.until(jQueryLoad);
}
wait.until(jQueryLoad);
}

// Wait for ANGULAR to load
{
String angularReadyScript = "return angular.element(document).injector().get('$http').pendingRequests.length === 0";

ExpectedCondition<Boolean> angularLoad = driver -> Boolean.valueOf(((JavascriptExecutor) driver).executeScript(angularReadyScript).toString());

boolean angularReady = Boolean.valueOf(js.executeScript(angularReadyScript).toString());

if (!angularReady) {
// System.out.println("ANGULAR is NOT Ready!");
wait.until(angularLoad);
}
}

// Wait for Javascript to load
{
ExpectedCondition<Boolean> jsLoad = driver -> ((JavascriptExecutor) driver).executeScript("return document.readyState").toString()
.equals("complete");

boolean jsReady = (Boolean) js.executeScript("return document.readyState").toString().equals("complete");

// Wait Javascript until it is Ready!
if (!jsReady) {
// System.out.println("JS in NOT Ready!");
wait.until(jsLoad);
}
}

Click here for Reference Link

Let me know if you stuck anywhere by implementing.

It overcomes the use of Thread or Explicit Wait.

Ответ 4
    public static void waitForPageToLoad(long timeOutInSeconds) {
ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}
};
try {
System.out.println("Waiting for page to load...");
WebDriverWait wait = new WebDriverWait(Driver.getDriver(), timeOutInSeconds);
wait.until(expectation);
} catch (Throwable error) {
System.out.println(
"Timeout waiting for Page Load Request to complete after " + timeOutInSeconds + " seconds");
}
}

Try this method

java selenium selenium-webdriver