Selenium 2 (WebDriver): проверьте, существует ли текст перед вызовом Alert.getText () - PullRequest
2 голосов
/ 19 июля 2011

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

Мое текущее решение использует ожидание, которое захватывает NPE. Код клиента просто должен вызвать waitForAlert(driver, TIMEOUT):

/**
 * If no alert is popped-up within <tt>seconds</tt>, this method will throw
 * a non-specified <tt>Throwable</tt>.
 * 
 * @return alert handler
 * @see org.openqa.selenium.support.ui.Wait.until(com.​google.​common.​base.Function)
 */
public static Alert waitForAlert(WebDriver driver, int seconds) {
    Wait<WebDriver> wait = new WebDriverWait(driver, seconds);
    return wait.until(new AlertAvailable());
}

private static class AlertAvailable implements ExpectedCondition<Alert> {
    private Alert alert = null;
    @Override
    public Alert apply(WebDriver driver) {
        Alert result = null;
        if (null == alert) {
            alert = driver.switchTo().alert();
        }

        try {
            alert.getText();
            result = alert;
        } catch (NullPointerException npe) {
            // Getting around https://groups.google.com/d/topic/selenium-users/-X2XEQU7hl4/discussion
        }
        return result;
    }
}

Ответы [ 2 ]

2 голосов
/ 27 июля 2011

Исходя из @Joe Coder ответ , упрощенная версия этого ожидания будет:

/**
 * If no alert is popped-up within <tt>seconds</tt>, this method will throw
 * a non-specified <tt>Throwable</tt>.
 * 
 * @return alert handler
 * @see org.openqa.selenium.support.ui.Wait.until(com.​google.​common.​base.Function)
 */
public static Alert waitForAlert(WebDriver driver, int seconds) {
    Wait<WebDriver> wait = new WebDriverWait(driver, seconds)
        .ignore(NullPointerException.class);
    return wait.until(new AlertAvailable());
}

private static class AlertAvailable implements ExpectedCondition<Alert> {
    @Override
    public Alert apply(WebDriver driver) {
        Alert alert = driver.switchTo().alert();
        alert.getText();
        return alert;
    }
}

Я написал короткий тест для проверки концепции:

import com.google.common.base.Function;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestUntil {
    private static Logger log = LoggerFactory.getLogger(TestUntil.class);

    @Test
    public void testUnit() {
        Wait<MyObject> w = new FluentWait<MyObject>(new MyObject())
                .withTimeout(30, TimeUnit.SECONDS)
                .ignoring(NullPointerException.class);
        log.debug("Waiting until...");
        w.until(new Function<MyObject, Object>() {
            @Override
            public Object apply(MyObject input) {
                return input.get();
            }
        });
        log.debug("Returned from wait");
    }

    private static class MyObject {
        Iterator<Object> results = new ArrayList<Object>() {
            {
                this.add(null);
                this.add(null);
                this.add(new NullPointerException("NPE ignored"));
                this.add(new RuntimeException("RTE not ignored"));
            }
        }.iterator();
        int i = 0;
        public Object get() {
            log.debug("Invocation {}", ++i);
            Object n = results.next();
            if (n instanceof RuntimeException) {
                RuntimeException rte = (RuntimeException)n;
                log.debug("Throwing exception in {} invocation: {}", i, rte);
                throw rte;
            }
            log.debug("Result of invocation {}: '{}'", i, n);
            return n;
        }
    }
}

В этом коде в until MyObject.get() вызывается четыре раза.В третий раз генерируется игнорируемое исключение, но последнее генерирует не игнорируемое исключение, прерывая ожидание.

Вывод (упрощенный для удобства чтения):

Waiting until...
Invocation 1
Result of invocation 1: 'null'
Invocation 2
Result of invocation 2: 'null'
Invocation 3
Throwing exception in 3 invocation: java.lang.NullPointerException: NPE ignored
Invocation 4
Throwing exception in 4 invocation: java.lang.RuntimeException: RTE not ignored

------------- ---------------- ---------------
Testcase: testUnit(org.lila_project.selenium_tests.tmp.TestUntil):  Caused an ERROR
RTE not ignored
java.lang.RuntimeException: RTE not ignored
    at org.lila_project.selenium_tests.tmp.TestUntil$MyObject$1.<init>(TestUntil.java:42)
    at org.lila_project.selenium_tests.tmp.TestUntil$MyObject.<init>(TestUntil.java:37)
    at org.lila_project.selenium_tests.tmp.TestUntil$MyObject.<init>(TestUntil.java:36)
    at org.lila_project.selenium_tests.tmp.TestUntil.testUnit(TestUntil.java:22)

Обратите внимание, чтопоскольку RuntimeException не игнорируется, журнал «Возвращено из ожидания» не печатается.

2 голосов
/ 27 июля 2011

JavaDoc для FluentWait.until()

Повторно применяет входное значение этого экземпляра к данной функции, пока не произойдет одно из следующего:

  1. функция не возвращает ни ноль, ни ложь,
  2. функция выдает безымянное исключение,
  3. время ожидания истекло ....... (чик)

Поскольку NullPointerException обозначает ложное условие, а WebDriverWait игнорирует только NotFoundException, просто удалите блок try / catch. Непроверенный, игнорируемый Exception, добавленный в apply(), семантически эквивалентен возвращению null, как в существующем коде.

private static class AlertAvailable implements ExpectedCondition<Alert> {
    @Override
    public Alert apply(WebDriver driver) {
        Alert result = driver.switchTo().alert();
        result.getText();
        return result;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...