WebDriver не надежно нажимает на ссылки или кнопки - PullRequest
2 голосов
/ 05 июля 2011

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

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

Кто-нибудь знает другой способ нажатия кнопки или ссылки в браузере? Или я должен использовать Selenium 1, а не WebDriver, поскольку он слишком новый для надежного использования.

public void waitAndClick(WebDriver driver, By by) {
    WebDriverWait wait = new WebDriverWait(driver, 10000, 2000);
    Function<WebDriver, Boolean> waitForElement = new waitForElement(by);
    wait.until(waitForElement);

    Actions builder = new Actions(driver);
    builder.click(driver.findElement(by))
            .perform();
}

private class waitForElement implements Function<WebDriver, Boolean> {
    private final By by;

    private String text = null;

    public waitForElement(By by) {
        this.by = by;
    }

    public waitForElement(By by, String text) {
        this.by = by;
        this.text = text;
    }

    @Override
    public Boolean apply(WebDriver from) {
        if (this.text != null) {
            for (WebElement e : from.findElements(this.by)) {
                if (e.getText().equals(this.text)) {
                    return Boolean.TRUE;
                }
            }

            return Boolean.FALSE;
        } else {
            try {
                driver.switchTo().defaultContent().switchTo().frame("top");
                from.findElement(this.by);
            } catch (Exception e) {
                logger.error("Unable to find \"" + this.by.toString() + "\". Retrying....");
                return Boolean.FALSE;
            }
            logger.info("Found \"" + this.by.toString() + "\".");
            return Boolean.TRUE;
        }
    }
}

Консоль в режиме отладки Eclipse:

16:07:08,109 INFO  WebDriverUtility: apply Found "By.linkText: Classes".
16:07:10,514 INFO  WebDriverUtility: apply Found "By.linkText: Reports".
16:07:17,028 ERROR WebDriverUtility: apply Unable to find "By.linkText: Users". Retrying....
16:07:26,369 INFO  WebDriverUtility: apply Found "By.linkText: Users".
16:07:38,272 ERROR WebDriverUtility: apply Unable to find "By.linkText: System". Retrying....
16:07:41,334 INFO  WebDriverUtility: apply Found "By.linkText: System".
16:07:47,722 ERROR WebDriverUtility: apply Unable to find "By.linkText: Schools". Retrying....
16:07:50,565 INFO  WebDriverUtility: apply Found "By.linkText: Schools".

Консоль при запуске из Eclipse:

16:14:04,179 INFO  WebDriverUtility: apply Found "By.linkText: Classes".
16:14:04,726 INFO  WebDriverUtility: apply Found "By.linkText: Reports".
16:14:09,771 INFO  PageAPITesting: login org.openqa.selenium.NoSuchElementException: Unable to find element with link text == Reports (WARNING: The server did not provide any stacktrace information)
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.0rc3', revision: '12536', time: '2011-06-20 18:19:52'
System info: os.name: 'Windows XP', os.arch: 'x86', os.version: '5.1', java.version: '1.6.0_24'
Driver info: driver.version: RemoteWebDriver
16:14:09,865 INFO  PageAPITesting: login current tabs is Classes
16:14:09,958 INFO  WebDriverUtility: apply Found "By.linkText: Schools".
16:14:10,240 INFO  PageAPITesting: login java.lang.IllegalStateException: Unable to navigate to the ca.schoolspecialty.qa.api.pages.schools.MenuSchoolPage page

1 Ответ

1 голос
/ 08 июля 2011

странного поведения не вижу,

Метод wait.until, который он вызывает, вызывает метод apply для функции, пока она не вернет что-то или пока не истечет время ожидания.

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

 while (clock.isNowBefore(end)) {
  try {
    T value = isTrue.apply(driver);

    if (value != null && Boolean.class.equals(value.getClass())) {
      if (Boolean.TRUE.equals(value)) {
        return value;
      }
    } else if (value != null) {
      return value;
    }
  } catch (NotFoundException e) {
    // Common case in many conditions, so swallow here, but be ready to
    // rethrow if it the element never appears.
    lastException = e;
  }
  sleep();

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

Я сам использую этот код для генератора функций:

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

Это намного проще, и вы можете использовать для любого локатора

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...