webdriver implicitWait не работает должным образом

В коде веб-драйвера, если я использую thread.sleep(20000). Он ждет 20 секунд, и мой код тоже работает нормально. Чтобы заархивировать то же самое, если я использую неявное ожидание, например

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

Он не ждет принудительно 20 секунд и переходит к следующим шагам всего за 3-4 секунды. и страница все еще загружается.

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

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(50, TimeUnit.SECONDS)
  .pollingEvery(5, TimeUnit.SECONDS)
  .ignoring(NoSuchElementException.class);

WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
  public WebElement apply(WebDriver driver) {
    return driver.findElement(By.id("jxxx"));
  }
});

Но если я скажу неправильный идентификатор, он будет ждать 50 секунд, но другой тест будет пройден без щелчка ... он не показывает никакой ошибки.

Мой вопрос заключается в том, как мне следует избегать Thread.sleep(), поскольку другие методы селена мне не помогают.


person user2254173    schedule 15.04.2013    source источник
comment
спасибо, что заглянули в этот @JimEvans, я отредактировал свой код и теперь использую только свободное ожидание, но это не дает никаких ошибок и ничего не делает.   -  person user2254173    schedule 15.04.2013


Ответы (2)


arrow_upward
3
arrow_downward

Используйте метод ниже, чтобы дождаться элемента:

public boolean waitForElementToBePresent(By by, int waitInMilliSeconds) throws Exception
{

    int wait = waitInMilliSeconds;
    int iterations  = (wait/250);
    long startmilliSec = System.currentTimeMillis();
    for (int i = 0; i < iterations; i++)
    {
        if((System.currentTimeMillis()-startmilliSec)>wait)
            return false;
        List<WebElement> elements = driver.findElements(by);
        if (elements != null && elements.size() > 0)
            return true;
        Thread.sleep(250);
    }
    return false;
}

И ниже метод ожидания загрузки страницы:

public void waitForPageLoadingToComplete() throws Exception {
    ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver driver) {
            return ((JavascriptExecutor) driver).executeScript(
                    "return      document.readyState").equals("complete");
        }
    };
    Wait<WebDriver> wait = new WebDriverWait(driver, 30);
    wait.until(expectation);
}

Предположим, вы ожидаете загрузки страницы. Затем вызовите 1-й метод с временем ожидания и любым элементом, который появляется после загрузки страницы, тогда он вернет true, иначе false. Используйте это как,

waitForElementToBePresent(By.id("Something"), 20000)

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

Попробуйте любой из приведенных ниже кодов после вышеуказанного метода

WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));

or

wait.until(ExpectedConditions.elementToBeClickable(By.id<locator>));

Обновлять:

public boolean waitForTextFiled(By by, int waitInMilliSeconds, WebDriver wdriver) throws Exception
    {
        WebDriver driver = wdriver;
        int wait = waitInMilliSeconds;
        int iterations  = (wait/250);
        long startmilliSec = System.currentTimeMillis();
        for (int i = 0; i < iterations; i++)
        {
            if((System.currentTimeMillis()-startmilliSec)>wait)
                return false;
            driver.findElement(By.id("txt")).sendKeys("Something");
            String name =  driver.findElement(by).getAttribute("value");

            if (name != null && !name.equals("")){
                return true;
            }
            Thread.sleep(250);
        }
        return false;
    }

Это попытается ввести текст в текстовое поле до заданного времени в миллисекундах. Если getAttribute() в вашем случае не подходит, используйте getText(). Если текст введен, он возвращает true. Поставьте максимальное время, до которого вы можете ждать.

person user2087450    schedule 15.04.2013
comment
Спасибо за ответ. но проблема в том, что если страница все еще загружается, я не знаю, как драйвер находит все локаторы. и пройти тест. Но на самом деле он не вводит и не щелкает никакие элементы. Но если я поставлю Thread.sleep, он будет ждать, заполнять и щелкать элементы. страница загружается отлично, только я поставил thread.sleep()  - person user2254173; 16.04.2013
comment
Драйвер находит локатор только тогда, когда видны соответствующие элементы. Вам нужно дождаться, пока страница загрузится успешно и полностью. Тогда только все элементы видны и могут быть идентифицированы драйвером с помощью соответствующих локаторов элементов. см. мою правку. - person user2087450; 16.04.2013
comment
Я использовал код. И он ожидает представления элемента, но только и только в том случае, если я поместил thread.sleep() его текст для записи в поле ввода (в этом элементе). так как элемент уже загружен, почему не пишет??? ждатьForElementToBePresent(By.id(txt), 20000);driver.manage().window().maximize(); Thread.sleep(10000); driver.findElement (By.id (txt)). sendKeys (текст); - person user2254173; 16.04.2013
comment
просто хочу добавить, что driver.manage.implicitWait(....) тоже не работает, только thread.sleep помогает мне писать. Пожалуйста, помогите :) - person user2254173; 16.04.2013
comment
Теперь я понимаю, что ваш элемент идентифицируется с помощью waitForElementToBePresent(By.id(txt), 20000); метод, но дело в том, что когда элемент идентифицирован, текстовое поле по-прежнему не редактируется. он в отключенном режиме. Через несколько секунд он становится включенным. Сделайте одно, после этого метода проверьте, доступен ли он для редактирования или нет. если не редактируется, то нужно подождать, чтобы он стал редактируемым - person user2087450; 16.04.2013
comment
Спасибо за понимание моей боли. позвольте мне использовать isEnable, сообщу вам об обновлении, tnx - person user2254173; 16.04.2013
comment
общественное статическое логическое значение waitForElementToEnable (локатор строк, int waitInMilliSeconds) выдает исключение {int wait = waitInMilliSeconds; int iterations = (wait/250);long startmilliSec = System.currentTimeMillis(); for (int i = 0; i ‹ iterations; i++) {if((System.currentTimeMillis()-startmilliSec)›wait)return false; логическое значение enable = driver.findElement(By.id(locator)).isEnabled(); если (включить) вернуть true; Thread.sleep(200); } вернуть ложь; } отредактировали код ur, чтобы включить проверку, но не повезло - person user2254173; 16.04.2013
comment
Не выбирайте isEnabled. Вы должны проверить, кликабельно ли текстовое поле. Например: когда вы хотите ввести какой-либо текст вручную в ваше текстовое поле, вы сначала щелкните в текстовом поле и введите строку. Итак, мое предложение ставит условие ожидания для кликабельности, как я предложил - person user2087450; 16.04.2013
comment
Бро, я использовал --- WebDriverWait wait = new WebDriverWait(driver, 15);wait.until(ExpectedConditions.elementToBeClickable(By.id(txt)));driver.findElement(By.id(txt)).sendKeys( текст); не повезло, какие-либо предположения, почему это происходит, он нигде не дает сбоев, но также ничего не пишет и заставляет меня использовать Thead.sleep(); что обычно не рекомендуется. - person user2254173; 17.04.2013
comment
Смотрите мое обновление. Если это не сработает, вы можете придерживаться своего thread.sleep. - person user2087450; 17.04.2013

arrow_upward
0
arrow_downward

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

new WebDriverWait(10, driver).until(ExpectedConditions.visibilityOfElementLocated(By.id("jxxx")).

В этом случае время ожидания составляет максимум 10 секунд.

person Sridevi Yedidha    schedule 16.04.2013
comment
Спасибо за ответ. но проблема в том, что если страница все еще загружается, я не знаю, как драйвер находит все локаторы. и пройти тест. Но на самом деле он не вводит и не щелкает никакие элементы. Но если я поставлю Thread.sleep, он будет ждать, заполнять и щелкать элементы. страница загружается отлично, только я поставил thread.sleep()  - person user2254173; 16.04.2013
comment
Я вижу, что вы ждете, пока элемент не появится. При проверке присутствия элемента проверяется, загружен ли элемент в DOM, видим ли он еще или нет. Ожидание, пока элемент станет видимым, является правильным решением. - person Sridevi Yedidha; 17.04.2013