Временно обходя неявные ожидания с WebDriver

При использовании неявных ожиданий,как советовали здесь, Я по-прежнемуsometimes хочу отстаиватьimmediate невидимость или несуществование элементов.

Другими словами, яknow некоторые элементы должны быть скрыты, и я хочу, чтобы мои тесты сделали это утверждениеfast, не тратя несколько секунд из-за (полезного) неявного ожидания.

Одна вещь, которую я попробовал, была вспомогательным методом, подобным этому:

// NB: doesn't seem to do what I want
private boolean isElementHiddenNow(String id) {
    WebDriverWait zeroWait = new WebDriverWait(driver, 0);
    ExpectedCondition<Boolean> c = invisibilityOfElementLocated(By.id(id));
    try {
        zeroWait.until(c);
        return true;
    } catch (TimeoutException e) {
        return false;
    }
}

Но в приведенном выше коде, вызовuntil() только возвращаетсяafter the implicit wait time has passedто есть он не выполняет то, что я хотел.

Это единственный способ, который я до сих пор нашел, который работает:

@Test
public void checkThatSomethingIsNotVisible()  {
    turnOffImplicitWaits();
    // ... the actual test
    turnOnImplicitWaits();
}

... где, например,turnOffImplicitWaits() вспомогательный суперкласс Selenium:

protected void turnOffImplicitWaits() {
    driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
}

Но это не очень элегантно, я думаю.Is there any cleaner way to bypass the implicit wait occasionally?

 Mike Kwan14 июн. 2012 г., 16:12
Я не верю, что интерфейсом определяется то, что вы хотите. Единственное, о чем я могу думать, это вызвать findElements вместо findElement. Но я не уверен, что это обойдёт и неявное ожидание.
 michaelsnowden12 авг. 2015 г., 01:05
Был бы хороший случай для лямбдpublic void bypassImplicitWaits(Bypass bypass) { turnOffImplicitWaits(); bypass.do(); turnOnImplicitWaits(); }
 Petr Janeček14 июн. 2012 г., 17:12
@MikeKwan Нет,findElements() также пытается ждать и вернуться после того, как хотя бы один элемент был найден.

Ответы на вопрос(6)

кости при поиске элемента.

protected boolean isElementHiddenNow(By locator) {
    turnOffImplicitWaits();
    boolean result = false;
    try {
       result = ExpectedConditions.invisibilityOfElementLocated(locator).apply(driver);
    }
    finally {
       turnOnImplicitWaits();
    }
    return result;
}

Таким образом, вы можете искать по CSS, если нужно, а не просто по id:

By PartLinkLocator = By.cssSelector("div.search-result div.row a");

«Конечно, ваш локатор, вероятно, должен быть спроектирован так, чтобы возвращать только один элемент (в отличие от примера« По », который я быстро взял, который возвращает все ссылки на детали в таблице строк css ...) Итак, & quot; id & quot; пример будет выглядеть

By usernameLocator = By.id("inputEmail");
myResult = isElementHiddenNow(usernameLocator);
 12 июн. 2017 г., 21:10
Определенно попытка / наконец - это путь.

Моя реализация:

using (driver.NoImplicitWait())
{
    ....
}

С методом расширения:

public static NoImplicitWait NoImplicitWait(this IWebDriver driver)
{
    return new NoImplicitWait(driver);
}

И класс:

public sealed class NoImplicitWait : IDisposable
{
    private readonly IWebDriver _driver;

    public NoImplicitWait(IWebDriver driver)
    {
        _driver = driver;
        _driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(0));
    }

    public void Dispose()
    {
        _driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
    }
}

чтобы полностью обойти неявное ожидание и переопределить его (с добавлением проверки видимости и т. Д.) В моем собственномfindElement() а такжеfindElements() методы, которые я сейчас использую по умолчанию. Таким образом, когда я хочу что-то проверить мгновенно, я могу вызвать оригинальный метод WebDriver, который, конечно, не ждет.

 14 июн. 2012 г., 17:26
Как вы будете ждать без использования опции implicitWait? Вы просто реализовали попытку / перехват в некотором цикле и опрашивали элемент каждые несколько секунд, пока не достигли некоторого порога?
 14 июн. 2012 г., 17:53
@AndyPerfect Да, обычный (try-catch, try again или timeout) подход с некоторыми основными дополнительными подвигами: видимость, отключенные элементы, выделение найденных элементов, обходные пути для страницы, которая не была загружена (запускается снова в StaleElementReference), временно также дляthis а такжеthis ошибка.

основанном на неявном мышлении ожидания и без помощи CSS, я нашел выход для такого рода вещей, дополняя его Jsoup и продолжая с Jsoup:

# this is straightforward Scala... put the types and it is Java.
val innerHtml = seleniumWebElementFatherInstance.getAttribute("innerHTML")
val jsoupElements = Jsoup.parse(innerHtml).select("div.your.css.selector")

@ Jonic's answer помог мне, однако я бы добавилtry { } finally { } и позвонитьturnOnImplicitWaits() вfinally блок, чтобы убедиться, что он всегда включается.

    turnOffImplicitWaits();
    boolean result = false;
    try {
       result = ExpectedConditions.invisibilityOfElementLocated(By.id(id)).apply(driver);
    }
    finally {
       turnOnImplicitWaits();
    }
    return result;
}
Решение Вопроса

что Selenium, кажется, не предлагает то, что я хочу напрямую (основываясь на том, что сказали Майк Кван и Slanec), этот простой вспомогательный метод - то, с чем я столкнулся на данный момент:

protected boolean isElementHiddenNow(String id) {
    turnOffImplicitWaits();
    boolean result = ExpectedConditions.invisibilityOfElementLocated(By.id(id)).apply(driver);
    turnOnImplicitWaits();
    return result;
}

private void turnOffImplicitWaits() {
    driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
}

private void turnOnImplicitWaits() {
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}

Если элемент скрыт или отсутствует вообще, метод возвращает true; если это видно, возвращает false. В любом случае, проверка выполняется мгновенно.

Использование вышесказанного, по крайней мере, намного чище, чем засорение самих тестовых случаев вызовамиturnOffImplicitWaits()  а такжеturnOnImplicitWaits().

Смотрите также эти ответы для отлаженных версий того же подхода:

Using try-finally to turn implicit waits back on Using By locator as the parameter
 05 февр. 2019 г., 19:24
Кто-нибудь знает, как повторить эту строку:driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS) в питоне? Я не могу найти это в документации
 05 февр. 2019 г., 19:37
Неважно, вы можете просто установить неявное время ожидания так же, как вы его изначально установили.
 Jonik29 окт. 2013 г., 21:55
@JeffMay: что-то вродеdriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);, Смотрите, напримерthis answer.
 20 окт. 2017 г., 18:19
Используйте By в качестве параметра в примере, так что это будет проще и может быть использовано для всех :)
 29 окт. 2013 г., 21:32
Как вы включаете неявные ожидания?

Ваш ответ на вопрос