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

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

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

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

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

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

Ответы [ 5 ]

0 голосов
/ 03 апреля 2019

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

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

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

0 голосов
/ 14 мая 2018
    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");
    }
}

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

0 голосов
/ 14 мая 2018

Реализуйте это, это работает для многих из нас, включая меня.Он включает ожидание веб-страницы на 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);
            }
          }

Нажмите здесь для ссылки Ссылка

Дайте мне знать, если вы застряли где-нибудь путем реализации.

Это преодолевает использование Thread или Explicit Wait.

0 голосов
/ 14 мая 2018

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

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

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

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

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


Теперь, когда ваш сценарий использования относится к полностью загруженной странице, вы можете использовать pageLoadStrategy () установлен на normal [поддерживаемые значения: none , eager или 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 , и ваша пробная версия кода гарантирует, что Browser Client (т. е. Web Browser ) достиг 'document.readyState', равного "complete".Как только это условие выполнено, Selenium выполняет следующую строку кода.

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

Но Клиент браузера , набравший 'document.readyState', равный "complete", по-прежнему не гарантирует завершения всех вызовов Ajax 1079 * и .


Чтобы дождаться завершения всех вызовов 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 несоответствие с ExpectedConditions , установленным на titleContains () метод, который будет гарантировать, что Page Title (то есть веб-страница ) видима и предполагает, что все элементы также видны следующим образом:

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

Теперь иногда это возможно, хотя PageЗаголовок будет соответствовать вашему Заголовку приложения , однако желаемый элемент, с которым вы хотите взаимодействовать, еще не загружен.Таким образом, более детальный подход заключается в том, чтобы вызвать WebDriverWait несоответствие с ExpectedConditions , установленным в visibilityOfElementLocated () метод, который заставит вашу программу ждать требуемый элемент быть видимым следующим образом:

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();
0 голосов
/ 14 мая 2018

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...