Selenium - выберите вход из компонента angularjs - PullRequest
0 голосов
/ 29 октября 2018

<md-datepicker ng-model="mc.date.from" required="" md-val="">
  <span class="input-group date" style="width:144px">
    <input size="16" type="text"
           class="form-control"
           autocomplete="off">
    <span class="input-group-btn">
    <button class="btn btn-default" tabindex="-1" >
      <i class="glyphicon glyphicon-calendar"></i>
    </button>
    </span>
  </span>
</md-datepicker>

У меня есть компонент AngularJs, который содержит input типа text. Я использовал следующий код для ввода date. В большинстве случаев это не помогает, когда я запускаю тест без головы.

WebElement fromDate = driver.findElement(
    By.tagName("md-datepicker"))
    .findElement(By.tagName("input"));

if (fromDate.getAttribute("value").length() > 0) {
    fromDate.clear();
}
fromDate.sendKeys(startDate);

Есть несколько других inputs перед datepicker, которые я заполняю. Но когда тест достигает datepciker, он не проходит, потому что не может его найти.

Как можно решить эту проблему?

Обновление

Я использовал этот метод прямо перед кодом выше.

public static void waitUntilVisible(By locator) {
    final long startTime = System.currentTimeMillis();
    final Duration duration = Duration.ofSeconds(2);
    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
        .pollingEvery(duration)
        .ignoring(StaleElementReferenceException.class);

    while ((System.currentTimeMillis() - startTime) < 91000) {
        try {
            wait.until(ExpectedConditions.presenceOfElementLocated(locator));
            break;
        } catch (StaleElementReferenceException e) {
            log.info("", e);
        }
    }
}

Ответы [ 4 ]

0 голосов
/ 06 ноября 2018

Я мог решить эту проблему только с помощью блока catch, где я ловил StaleElementReferenceException.

   WebElement input;
    try {
        input = driver.findElement(
            By.tagName("md-datepicker"))
            .findElement(By.tagName("input"));

    } catch(StaleElementReferenceException e) {
        input = driver.findElement(By.xpath("//md-datepicker/span/input"));
    }

    if (input.getAttribute("value").length() > 0) {
        input.clear();
    }

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


Я задавал этот вопрос 29 октября 2018 года. В то время я использовал версию селена 3.14.0. Но этот подход выбирает входные данные, также вы не должны использовать селеновую версию 3.141.0.

0 голосов
/ 29 октября 2018

Вы можете попробовать дождаться видимости элемента:

WebElement fromDate =
                new WebDriverWait(driver, 10)
                .until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("md-datepicker input")));
0 голосов
/ 29 октября 2018

Вы можете попробовать использовать cssSelector, использование xpath не рекомендуется для headless выполнения

WebElement fromDate = driver.findElement(
    By.cssSelector(".input-group.date"))
    .findElement(By.cssSelector(".form-control"));
if (fromDate.getAttribute("value").length() > 0) {
    fromDate.clear();
}
fromDate.sendKeys(startDate);
0 голосов
/ 29 октября 2018

Поскольку элемент <input> является элементом Angular , вы должны заставить WebDriverWait , чтобы желаемый элемент был кликабельным , и вы можете использовать любой из следующие решения:

  • cssSelector:

    WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("md-datepicker[ng-model$='from']>span.input-group.date>input.form-control")));
    elem.click();
    elem.clear();
    elem.sendKeys(startDate);
    
  • xpath

    WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//md-datepicker[contains(@ng-model,'from')]/span[@class='input-group date']/input[@class='form-control']")));
    elem.click();
    elem.clear();
    elem.sendKeys(startDate);
    

Обновление

В соответствии с вашим вопросом об обновлении функция waitUntilVisible() выглядит для меня просто накладными расходами, когда вы реализуете FluentWait для presenceOfElementLocated(), игнорирующим StaleElementReferenceException , который мог бы быть легко реализован через индивидуальный заказ WebDriverWait с Ожидаемые условия как elementToBeClickable().

...