WebDriver Selenium API: ElementNotFoundErrorException, когда Element явно присутствует! - PullRequest
9 голосов
/ 06 ноября 2010

иногда при запуске тестов на WebDriver с отключенным Javascript WebDriver падает из-за ошибки ElementNotFound, когда он находит элемент и пытается щелкнуть по нему.

Тем не менее, элемент явно там!

Прочитав это: http://code.google.com/p/selenium/wiki/FrequentlyAskedQuestions#Q:_My_XPath_finds_elements_in_one_browser,_but_not_in_others._Wh

Я пришел к выводу, что webdriver не должен ждать завершения загрузки веб-страницы. Как я могу использовать класс ожидания Webdriver? Может кто-нибудь привести пример?

Ответы [ 3 ]

18 голосов
/ 11 ноября 2010

Этот пример был опубликован в группах Google . По словам разработчиков Google:

1 Использовать неявные ожидания. Здесь водитель будет ждать до назначенного время ожидания, пока элемент не будет найден. Не забудьте прочитать Javadoc для предостережения. Использование:

driver.get("http://www.google.com"); 
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); 
WebElement element = driver.findElement(By.name("q")); 
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); 
// continue with test... 

2 Используйте класс org.openqa.selenium.support.ui.WebDriverWait. Это будет опросить, пока ожидаемое условие не станет истинным, и вернуть результат этого условия (если он ищет элемент). Это гораздо более гибкий, чем неявный ждет, так как вы можете определить любое пользовательское поведение. Использование:

Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) { 
  return new Function<WebDriver, WebElement>() { 
    public WebElement apply(WebDriver driver) { 
      return driver.findElement(locator); 
    }
  };
}

// ... 
driver.get("http://www.google.com"); 
WebDriverWait wait = new WebDriverWait(driver, /*seconds=*/3); 
WebElement element = wait.until(presenceOfElementLocated(By.name("q"));
3 голосов
/ 30 июня 2011

Продолжая ответ nilesh, вы также можете разрешить более точный поиск (например, в контексте WebElement) с помощью интерфейса SearchContext:

Function<SearchContext, WebElement> elementLocated(final By by) {
    return new Function<SearchContext, WebElement>() {
        public WebElement apply(SearchContext context) {
            return context.findElement(by);
        }
    };
}

Выполнение выполняется FluentWait экземпляр (вместо WebDriverWait).Создайте красивый интерфейс программирования, обернув его выполнение и необходимую обработку исключений в служебный метод (корень иерархии типов PageObject является хорошим местом):

/**
 * @return The element if found before timeout, otherwise null
 */
protected WebElement findElement(SearchContext context, By by,
        long timeoutSeconds, long sleepMilliseconds) {
    @SuppressWarnings("unchecked")
    FluentWait<SearchContext> wait = new FluentWait<SearchContext>(context)
            .withTimeout(timeoutSeconds, TimeUnit.SECONDS)
            .pollingEvery(sleepMilliseconds, TimeUnit.MILLISECONDS)
            .ignoring(NotFoundException.class);
    WebElement element = null;
    try {
        element = wait.until(elementLocated(by));
    }
    catch (TimeoutException te) {
        element = null;
    }
    return element;
}

/**
 * overloaded with defaults for convenience
 */
protected WebElement findElement(SearchContext context, By by) {
    return findElement(context, by, DEFAULT_TIMEOUT, DEFAULT_POLL_SLEEP);
}

static long DEFAULT_TIMEOUT = 3;       // seconds
static long DEFAULT_POLL_SLEEP = 500;  // milliseconds

Пример использования:

WebElement div = this.findElement(driver, By.id("resultsContainer"));
if (div != null) {
    asyncSubmit.click();
    WebElement results = this.findElement(div, By.id("results"), 30, 500);
    if (results == null) {
        // handle timeout
    }
}
0 голосов
/ 20 ноября 2016

Свободное ожидание - Лучший подход, так как он наиболее гибкий и настраиваемый на лету (опция игнорирования исключений, опрос каждые, тайм-аут):

public Wait<WebDriver> getFluentWait() {
    return new FluentWait<>(this.driver)
            .withTimeout(driverTimeoutSeconds, TimeUnit.SECONDS)
            .pollingEvery(500, TimeUnit.MILLISECONDS)
            .ignoring(StaleElementReferenceException.class)
            .ignoring(NoSuchElementException.class)
            .ignoring(ElementNotVisibleException.class)
}

Используйте так:

WebElement webElement = getFluentWait().until(x -> { return driver.findElement(elementBy); } );

Явное ожидание - Ну, это то же самое, что и FluentWait, но с предварительно настроенным pollingEvery и типом ожидания, например FluentWait<WebDriver> (быстрее использовать):

WebDriverWait wait = new WebDriverWait(driver, 30000);
WebElement item = wait.until(ExpectedConditions.visibilityOfElementLocated(yourBy));

ImplicitWait - Не рекомендуется, поскольку он настраивается один раз для всего сеанса.Это также используется для каждого элемента поиска и ожидает только присутствия (нет ExpectedConditions и т. Д.):

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...