Есть ли у нас какая-либо общая функция, чтобы проверить, полностью ли загружена страница в Selenium?

avatar
Ankit Singh
14 мая 2018 в 09:31
5675
7
5

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

Я попробовал следующий код:

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

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

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

Источник
Sneha Shinde
14 мая 2018 в 09:58
0

Вы можете проверить страницу URL, чтобы увидеть, загружена ли страница или нет?

Ответы (7)

avatar
David Lemon
9 марта 2021 в 08:01
0

Есть простой способ сделать это. Когда вы впервые запрашиваете состояние через javascript, он говорит вам, что страница complete, но после этого переходит в состояние loading. Первым состоянием complete была начальная страница!

Итак, я предлагаю проверить состояние complete после состояния loading. Проверьте этот код на PHP, его легко перевести на другой язык.

        $prevStatus  = '';
        $checkStatus = function ($driver) use (&$prevStatus){

          $status = $driver->executeScript("return document.readyState"); 

          if ($prevStatus=='' && $status=='loading'){
            //save the previous status and continue waiting
            $prevStatus = $status; 
            return false;
          }

          if ($prevStatus=='loading' && $status=='complete'){
            //loading -> complete, stop waiting, it is finish!
            return true;
          }
          //continue waiting 
          return false;

        };
        $this->driver->wait(20, 150)->until($checkStatus);

Проверка присутствия элемента также работает хорошо, но вы должны убедиться, что этот элемент присутствует только на целевой странице.

avatar
Prajwal Shashi Dharan
2 марта 2021 в 06:26
0

Для меня это хорошо работает с динамически отображаемыми веб-сайтами:

  1. Дождитесь полной загрузки страницы

WebDriverWait wait = new WebDriverWait(driver, 50); 
wait.until((ExpectedCondition<Boolean>) wd -> ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
  1. Выполнить еще одно неявное ожидание с фиктивным условием, которое всегда будет завершаться ошибкой

  try {          
 wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(text(),'" + "This text will always fail :)" + "')]"))); // condition you are certain won't be true 
  } 
  catch (TimeoutException te) {
  }
  1. Наконец, вместо получения исходного HTML-кода, который в большинстве одностраничных приложений дал бы вам другой результат, извлеките внешний HTML-код первого тега HTML

String script = "return document.getElementsByTagName(\"html\")[0].outerHTML;"; 
content = ((JavascriptExecutor) driver).executeScript(script).toString();
avatar
pguardiario
3 апреля 2019 в 00:12
-1

Что-то вроде этого должно работать (пожалуйста, извините за питон в ответе java):

idle = driver.execute_async_script("""
  window.requestIdleCallback(() => {
    arguments[0](true)
  })
""")

Это должно быть заблокировано до тех пор, пока цикл событий не будет бездействовать, что означает, что все активы должны быть загружены.

avatar
mbn217
14 мая 2018 в 14:37
0
    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");
    }
}

Попробуйте этот метод

avatar
undetected Selenium
14 мая 2018 в 11:20
4

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

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

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

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

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


Теперь, как ваш UseCase относится к странице будучи полностью загруженной вы можете использовать pageLoadStrategy () установлен в положение 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 и пробного кода оба гарантирует, что Браузер клиента есть (т.е. Web Browser ) есть достигнуто '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);
    }
}

Вы можете найти подробное обсуждение в Дождитесь завершения запроса ajax - selenium webdriver


Теперь два описанных выше подхода через PageLoadStrategy и "return jQuery.active == 0" выглядят ожидающими неопределенных событий. Так что для определенного ожидания вы можете вызвать WebDriverWait inconjunction с ExpectedConditions установлен на titleContains () метод, который будет гарантировать, что Название страницы ( т.е. Веб-страница) видна и предполагается, что все элементы также видны следующим образом:

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();

Теперь иногда возможно, что хотя название страницы будет соответствовать вашему заголовку приложения, но нужный элемент, с которым вы хотите взаимодействовать, не завершил загрузку. Так что более зернистый подход будет индуцировать WebDriverwait Некорозна с Представленные капитальные возможности Набор для видимости быть видимым следующим образом:

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();

Ссылки

Вы можете найти несколько соответствующих подробных обсуждений в:

avatar
Ishita Shah
14 мая 2018 в 10:56
0

Реализуйте это. Это работает для многих из нас, включая меня. Он включает в себя ожидание веб-страницы на JavaScript, Angular, JQuery, если они есть.

Если ваше Приложение содержит Javascript и JQuery, вы можете писать код только для них,

Определив его в одном методе, вы можете вызывать его где угодно:

          // 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);
            }
          }

Нажмите здесь, чтобы перейти по ссылке

Сообщите мне, если вы где-то застряли при реализации.

Это позволяет избежать использования потока или явного ожидания.

Zabuzard
14 мая 2018 в 12:57
1

Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится. - Из обзора

Ishita Shah
14 мая 2018 в 13:18
0

@Zabuza: добавлен код. Спасибо.

avatar
Margon
14 мая 2018 в 10:06
0

Я тоже использую селен, и у меня была та же проблема, чтобы исправить это, я просто жду загрузки jQuery.

Если у вас возникла та же проблема, попробуйте и это

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

Вы можете обернуть обе функции в метод и проверять, пока не загрузятся и страница, и jQuery

Ardesco
13 марта 2019 в 14:24
0

Вы делаете предположение, что веб-сайт, управляемый Selenium, использует JQuery...