Подтвердить что ты не робот

Временно обходя скрытые ожидания с помощью WebDriver

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

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

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

// 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() возвращает только после того, как неявное время ожидания прошло, т.е. оно не делает то, что я хотел.

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

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

... где, например, turnOffImplicitWaits() является вспомогательным в общем суперэлементе селена:

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

Но это не очень элегантно, я думаю. Есть ли какой-нибудь более чистый способ обхода неявного ожидания иногда?

4b9b3361

Ответ 1

Учитывая, что 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().

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

Ответ 2

Я также предлагаю изменить параметр на локатор "By" для большей гибкости при поиске элемента.

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

'Конечно, ваш локатор, вероятно, должен быть сконструирован так, чтобы возвращать только один элемент (в отличие от примера "By", который я быстро схватил, который возвращает все ссылки частей в таблице css строк...) Итак, пример "id" будет выглядеть как

By usernameLocator = By.id("inputEmail");
myResult = isElementHiddenNow(usernameLocator);

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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

Ответ 6

В существующем коде, который много полагается на неявный подход к выживанию, и без 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")