Дождитесь загрузки страницы в Selenium

Как вы делаете Selenium 2.0 подождите, пока страница загрузится?

Ответ 1

Вы также можете проверить pageloaded с помощью следующего кода

IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));

 wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));

Ответ 2

Использовать класс WebDriverWait

Также см. Здесь

Вы можете ожидать показать какой-то элемент. что-то вроде С#:

WebDriver _driver = new WebDriver();
WebDriverWait _wait = new WebDriverWait(_driver, new TimeSpan(0, 1, 0));

_wait.Until(d => d.FindElement(By.Id("Id_Your_UIElement"));

Ответ 3

В целом, при использовании Selenium 2.0 веб-драйвер должен возвращать управление вызывающему коду только после того, как он определил, что страница загружена. Если это не так, вы можете вызвать waitforelemement, который циклически вызывает вызов findelement до тех пор, пока он не будет найден или не истечет время ожидания (время может быть установлено).

Ответ 4

Если вы установите неявное ожидание драйвера, вызовите метод findElement для элемента, который вы ожидаете находиться на загруженной странице, WebDriver проведет опрос для этого элемента, пока не найдет элемент или не достигнет значения тайм-аута.

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

источник: implicit-waits

Ответ 5

Реализация Ruby:

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until {
    @driver.execute_script("return document.readyState;") == "complete" 
}

Ответ 6

Вы можете удалить строку System.out. Он добавляется для целей отладки.

WebDriver driver_;

public void waitForPageLoad() {

    Wait<WebDriver> wait = new WebDriverWait(driver_, 30);
    wait.until(new Function<WebDriver, Boolean>() {
        public Boolean apply(WebDriver driver) {
            System.out.println("Current Window State       : "
                + String.valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState")));
            return String
                .valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState"))
                .equals("complete");
        }
    });
}

Ответ 7

Все эти решения в порядке для конкретных случаев, но они страдают, по крайней мере, от одной из нескольких возможных проблем:

  • Они не являются достаточно обобщенными - они хотят, чтобы вы заранее знали, что какое-то конкретное условие будет верно для страницы, на которую вы собираетесь (например, будет отображаться какой-то элемент)

  • Они открыты для условия гонки, в котором вы используете элемент, который действительно присутствует на старой странице, а также на новой странице.

Здесь моя попытка создания общего решения, которое позволяет избежать этой проблемы (в Python):

Во-первых, общая функция "wait" (используйте WebDriverWait, если хотите, я нахожу их уродливыми):

def wait_for(condition_function):
    start_time = time.time()
    while time.time() < start_time + 3:
        if condition_function():
            return True
        else:
            time.sleep(0.1)
    raise Exception('Timeout waiting for {}'.format(condition_function.__name__))

Далее, решение основывается на том факте, что селен записывает (внутренний) id-номер для всех элементов на странице, включая элемент верхнего уровня <html>. Когда страница обновляется или загружается, она получает новый элемент html с новым идентификатором.

Итак, если вы хотите щелкнуть ссылку с текстом "моя ссылка", например:

old_page = browser.find_element_by_tag_name('html')

browser.find_element_by_link_text('my link').click()

def page_has_loaded():
    new_page = browser.find_element_by_tag_name('html')
    return new_page.id != old_page.id

wait_for(page_has_loaded)

Для более Pythonic, многоразового, общего помощника вы можете создать менеджер контекста:

from contextlib import contextmanager

@contextmanager
def wait_for_page_load(browser):
    old_page = browser.find_element_by_tag_name('html')

    yield

    def page_has_loaded():
        new_page = browser.find_element_by_tag_name('html')
        return new_page.id != old_page.id

    wait_for(page_has_loaded)

И тогда вы можете использовать его практически для любого взаимодействия селена:

with wait_for_page_load(browser):
    browser.find_element_by_link_text('my link').click()

Я считаю, что пуленепробиваемый! Как вы думаете?

Дополнительная информация в сообщение в блоге об этом здесь

Ответ 8

Вы также можете использовать класс: ExpectedConditions, чтобы явно дождаться появления элемента на веб-странице, прежде чем вы сможете предпринять какие-либо действия.

Вы можете использовать класс ExpectedConditions для определения видимости элемента:

WebElement element = (new WebDriverWait(getDriver(), 10)).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input#houseName")));

См. ExpectedConditions class Javadoc для списка всех условий, которые вы можете проверить.

Ответ 9

Если вы хотите дождаться загрузки определенного элемента, вы можете использовать метод isDisplayed() на RenderedWebElement:

// Sleep until the div we want is visible or 5 seconds is over
long end = System.currentTimeMillis() + 5000;
while (System.currentTimeMillis() < end) {
    // Browsers which render content (such as Firefox and IE) return "RenderedWebElements"
    RenderedWebElement resultsDiv = (RenderedWebElement) driver.findElement(By.className("gac_m"));

    // If results have been returned, the results are displayed in a drop down.
    if (resultsDiv.isDisplayed()) {
      break;
    }
}

(Пример из Руководство по началу работы за 5 минут)

Ответ 10

Это кажется серьезным ограничением WebDriver. Очевидно, что ожидание элемента не будет означать загрузку страницы, в частности DOM может быть полностью построена (состояние onready), когда JS все еще выполняется, а CSS и изображения по-прежнему загружаются.

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

Ответ 11

Ответ на Imran rehashed для Java 7:

    WebDriverWait wait = new WebDriverWait(driver, 30);

    wait.until(new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver wdriver) {
            return ((JavascriptExecutor) driver).executeScript(
                "return document.readyState"
            ).equals("complete");
        }
    });

Ответ 12

Явное ожидание или условное ожидание в этом ожидании, пока не будет дано это условие.

WebDriverWait wait = new WebDriverWait(wb, 60);
wait.until(ExpectedConditions.elementToBeClickable(By.name("value")));

Это будет ждать каждого веб-элемента в течение 60 секунд.

Используйте неявное ожидание ожидания каждого элемента на странице до указанного времени.

driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

Это будет ждать каждого веб-элемента в течение 60 секунд.

Ответ 13

Используйте неявно ожидание ожидания каждого элемента на странице до заданного времени.

driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

это ожидание для каждого элемента на странице в течение 30 секунд.

Еще одно ожидание - Явное ожидание или условное ожидание в этом ожидании до заданного условия.

WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

В id указывается идентификатор статического элемента, который неуверенно отображается на странице, как только загружается страница.

Ответ 14

Я удивлен, что предикаты не были первым выбором, поскольку вы, как правило, знаете, какие элементы вы будете взаимодействовать друг с другом на странице, которую вы ожидаете загрузить. Мой подход всегда заключался в построении предикатов/функций типа waitForElementByID(String id) и waitForElemetVisibleByClass(String className) и т.д., А затем использовать и повторно использовать их везде, где они мне нужны, будь то для загрузки страницы или изменения содержимого страницы, которую я жду.

Например,

В моем тестовом классе:

driverWait.until(textIsPresent("expectedText");

В родительском классе test:

protected Predicate<WebDriver> textIsPresent(String text){
    final String t = text;
    return new Predicate<WebDriver>(){
        public boolean apply(WebDriver driver){
            return isTextPresent(t);
        }
    };
}

protected boolean isTextPresent(String text){
    return driver.getPageSource().contains(text);
}

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

В этом примере родительский класс определил и инициировал WebDriver driver и WebDriverWait driverWait.

Надеюсь, это поможет.

Ответ 15

Решение NodeJS:

В Nodejs вы можете получить его через promises...

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

driver.get('www.sidanmor.com').then(()=> {
    // here the page is fully loaded!!!
    // do your stuff...
}).catch(console.log.bind(console));

Если вы напишете этот код, вы будете перемещаться, а селен будет ждать 3 секунды...

driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...

Из документации Selenium:

this.get(url) → Thenable

Задает команду для перехода к указанному URL.

Возвращает обещание, которое будет разрешено, если документ имеет завершенную загрузку.

Документация селена (Nodejs)

Ответ 16

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

public static boolean isloadComplete(WebDriver driver)
{
    return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
            || ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}

Ответ 17

SeleniumWaiter

import com.google.common.base.Function;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

public class SeleniumWaiter {

      private WebDriver driver;

      public SeleniumWaiter(WebDriver driver) {
           this.driver = driver;
      }

      public WebElement waitForMe(By locatorname, int timeout){
           WebDriverWait wait = new WebDriverWait(driver, timeout);
           return wait.until(SeleniumWaiter.presenceOfElementLocated(locatorname));
      }

      public static Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) {
            // TODO Auto-generated method stub
            return new Function<WebDriver, WebElement>() {
                 @Override
                 public WebElement apply(WebDriver driver) {
                      return driver.findElement(locator);
                 }
            };
      }
 }

И вам используйте его:

_waiter = new SeleniumWaiter(_driver);

try {
   _waiter.waitForMe(By.xpath("//..."), 10);
} 
catch (Exception e) {
   // Error
}

Ответ 18

/**
 * Call this method before an event that will change the page.
 */
private void beforePageLoad() {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript("document.mpPageReloaded='notYet';");
}

/**
 * Call this method after an event that will change the page.
 * 
 * @see #beforePageLoad
 * 
 *      Waits for the previous page to disappear.
 */
private void afterPageLoad() throws Exception {
    (new WebDriverWait(driver, 10)).until(new Predicate<WebDriver>() {

        @Override
        public boolean apply(WebDriver driver) {
            JavascriptExecutor js = (JavascriptExecutor) driver;
            Object obj = js.executeScript("return document.mpPageReloaded;");
            if (obj == null) {
                return true;
            }
            String str = (String) obj;
            if (!str.equals("notYet")) {
                return true;
            }
            return false;
        }
    });
}

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

Эта техника была вдохновлена ​​ответом из-за этого.

Ответ 19

Лучший способ дождаться загрузки страницы при использовании привязок Java для WebDriver - использовать шаблон структуры объекта страницы с помощью PageFactory. Это позволяет использовать AjaxElementLocatorFactory, который, по его словам, просто действует как глобальное ожидание для всех ваших элементов. Он имеет ограничения на такие элементы, как drop-boxes или сложные javascript-переходы, но он значительно сократит количество необходимого кода и ускорит время тестирования. Хороший пример можно найти в этом блоге. Предполагается базовое понимание Core Java.

http://startingwithseleniumwebdriver.blogspot.ro/2015/02/wait-in-page-factory.html

Ответ 20

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

 WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS)

Ответ 21

Вы можете явно ожидать появления элемента на веб-странице, прежде чем вы сможете предпринять какие-либо действия (например, element.click())

driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
  .until(new ExpectedCondition<WebElement>(){
        @Override
        public WebElement apply(WebDriver d) {
        return d.findElement(By.id("myDynamicElement"));
}});

Это то, что я использовал для аналогичного сценария, и он отлично работает.

Ответ 22

Мой простой способ:

long timeOut = 5000;
    long end = System.currentTimeMillis() + timeOut;

        while (System.currentTimeMillis() < end) {

            if (String.valueOf(
                    ((JavascriptExecutor) driver)
                            .executeScript("return document.readyState"))
                    .equals("complete")) {
                break;
            }
        }

Ответ 23

Вы можете использовать wait. есть в основном 2 типа ожидания в селене

  • Неявное ожидание
  • Явное ожидание

- Неявное ожидание

Это очень просто, см. синтаксис ниже:

driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);

- Явное ожидание

Явное ожидание или условное ожидание в этом ожидании до тех пор, пока не будет выполнено заданное условие.

WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

Вы можете использовать другие свойства, такие как visblityOf(), visblityOfElement()

Ответ 25

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

public static void processing(){ 
    WebDriverWait wait = new WebDriverWait(driver, 30);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
    wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
}

Где xpath находит gif в HTML DOM. После этого Вы также можете реализовать свои методы действий. Нажмите.

public static void click(WebElement elementToBeClicked){
    WebDriverWait wait = new WebDriverWait(driver, 45);
    wait.until(ExpectedConditions.visibilityOf(element));
    wait.until(ExpectedConditions.elementToBeClickable(element)); 
    wait.ignoring(NoSuchElementException.class).ignoring(StaleElementReferenceException.class); elementToBeClicked.click(); 
 }

Ответ 26

Вы можете использовать этот фрагмент кода для загрузки страницы:

    IWait wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver,TimeSpan.FromSeconds(30.00));
    wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));

Или вы можете использовать официанта для загрузки любого элемента и стать видимым/кликабельным на этой странице, скорее всего, это будет загрузка в конце загрузки, например:

    Wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath(xpathOfElement));
    var element = GlobalDriver.FindElement(By.XPath(xpathOfElement));
    var isSucceededed = element != null;

Ответ 27

Лучшим способом, который я видел, является использование stalenessOf ExpectedCondition, чтобы ждать, пока старая страница станет устаревшей.

Пример:

WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);

WebElement oldHtml = driver.findElement(By.tagName("html"));
wait.until(ExpectedConditions.stalenessOf(oldHtml));

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

Ответ 28

Вот версия наиболее популярного в настоящее время ответа на Java 8:

WebDriverWait wait = new WebDriverWait(myDriver, 15);
wait.until(webDriver -> ((JavascriptExecutor) myDriver).executeScript("return document.readyState").toString().equals("complete"));

Где myDriver - это объект WebDriver (объявленный ранее).

Примечание: имейте в виду, что этот метод (document.readyState) проверяет только DOM.

Ответ 29

driver.asserts().assertElementFound("Page was not loaded",
By.xpath("//div[@id='actionsContainer']"),Constants.LOOKUP_TIMEOUT);

Ответ 30

Как получить Selenium для ожидания загрузки страницы после клика предоставляет следующий интересный подход:

  • Сохраните ссылку на WebElement со старой страницы.
  • Нажмите ссылку.
  • Продолжайте вызывать операции с WebElement до тех пор, пока не будет StaleElementReferenceException.

Пример кода:

WebElement link = ...;
link.click();
new WebDriverWait(webDriver, timeout).until((org.openqa.selenium.WebDriver input) ->
{
    try
    {
        link.isDisplayed();
        return false;
    }
    catch (StaleElementReferenceException unused)
    {
        return true;
    }
});