Селен: Проверьте наличие элемента
В автоматизации в реальном времени, проверяем ли мы наличие каждого элемента (в тесте) перед выполнением каких-либо действий с ними?
Везде, где есть findElement
Заявление, есть вероятность NoSuchElementException. Мой вопрос заключается в том, проверяем ли мы наличие элемента каждый раз?
Делает каждый findElement
Заявление должно быть окружено try-catch
блок?
4 ответа
Вы можете найти применение класса AbstractWebDriverEventListener особенно полезным. Этот класс реализует интерфейс WebDriverEventListener, который определяет before
а также after
хуки для событий, запускаемых WebDriver.
Один из таких перед хуков beforeFindBy может быть реализован для проверки наличия элемента. Например:
public void beforeFindBy(By by, WebElement element, WebDriver driver) {
// Explicit wait to check for the presence of the element using the "by" locator
}
Точно так же можно было бы использовать ловушку beforeClickOn before, чтобы проверить, что элемент активен до того, как событие click будет выполнено для этого элемента.
Есть два случая для учета:
- Элемент присутствует; смысл существует ли он в DOM.
- Элемент виден; это означает, что он находится в DOM и не имеет скрытого или эквивалентного флага.
Для первого случая я использую следующий вспомогательный метод:
this.waitForElement = function(locator) {
browser.wait(function() {
return browser.isElementPresent(locator);
}, testData.Timeout.TWO_MINUTES);
};
Это будет ожидать произвольного количества времени, пока элемент, соответствующий предоставленному локатору, станет присутствующим (он существует в DOM).
Во втором случае я использую этот вспомогательный метод:
this.waitForElementIsVisible = function(el){
let EC = protractor.ExpectedConditions;
browser.wait(EC.visibilityOf(el), testData.Timeout.TWO_MINUTES, "Element did not become visible after 2 minutes");
};
Это занимает WebElement
в качестве единственного параметра и ожидает, пока элемент не станет видимым (он существует в DOM и не скрыт через стиль CSS или что-то еще)
В качестве бонуса я также нашел этот вспомогательный метод полезным для тестирования состояний ошибок в форме:
this.waitForElementIsClickable = function(el){
let EC = protractor.ExpectedConditions;
browser.wait(EC.elementToBeClickable(el), testData.Timeout.TWO_MINUTES, "Element did not become clickable after 2 minutes");
};
Принимает WebElement
в качестве первого параметра и ожидает, пока этот WebElement не будет нажат.
Обратите внимание, я использую транспортир, и ссылочный транспортир в этих фрагментах. Поэтому, если вы не используете Protractor, скорее всего, они не будут работать на 100% через прямое копирование + вставка. Должно быть достаточно легко настроить их под ваши настройки.
Позвольте мне попытаться ответить на ваши вопросы один за другим:
In real-time automation, do we check for the presence of every element(in test) before performing some action on them
: Да, в соответствии с рекомендациями, когда пользователь перенаправляется на новую страницу, вам необходимо обеспечить состояние элемента в соответствии с желаемым действием.
Существует 3 наиболее широко используемых ExpectedConditions, которые могут использоваться совместно с WebDriverWait для проверки состояния элемента следующим образом:
presenceOfElementLocated
Наличие OfElementLocated(By locator) определяется следующим образом:
public static ExpectedCondition<WebElement> presenceOfElementLocated(By locator)
Description : An expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible.
visibilityOfElementLocated
visibilityOfElementLocated(By locator) определяется следующим образом:
public static ExpectedCondition<WebElement> visibilityOfElementLocated(By locator)
Description : An expectation for checking that an element is present on the DOM of a page and visible. Visibility means that the element is not only displayed but also has a height and width that is greater than 0.
elementToBeClickable
elementToBeClickable (By locator) определяется следующим образом:
public static ExpectedCondition<WebElement> elementToBeClickable(By locator)
Description : An expectation for checking an element is visible and enabled such that you can click it.
Wherever there is a findElement statement, there is a chance of NoSuchElementException
Нет, совсем нет. Если вы построите правильную стратегию локатора, вы не столкнетесьNoSuchElementException
,Здесь вы найдете подробное обсуждение NoSuchElementExeption, селен не может найти элемент
Does every findElement statement need to be surrounded by try-catch block
Нет, не всегда. Если ваш сценарий использования предполагает обработку как позитивных, так и негативных сценариев, тогдаtry-catch {}
блок идеально.
Самый прямой и простой способ проверить наличие веб-элемента - использовать findElements() (обратите внимание на множественное число), который возвращает массив, т.е.
if (driver.findElements(By.xpath("//a")).isEmpty())
// no links exist
Тот же метод можно использовать для проверки одного элемента, он не обязательно должен быть массивом. Возвращенное значение.size() с нулем означает, что совпадений не было, и, следовательно, искомый элемент отсутствует в DOM.
Некоторые утверждают, что лучший метод - это обернуть.findElement в метод, который делает try/catch и регистрирует / отвечает соответственно различным результатам, таким как элемент не найден, устаревший элемент и т. Д.
Я использую оба метода в своих тестах и использую собственную функцию существующие с логикой.findElements, но использую обертку для других сценариев.
Краткий ответ: Нет. Более длинный ответ: один из подходов - дождаться индикатора "страница завершена", чтобы использовать явное ожидание. Это будет означать, что вы можете безопасно найти элементы по мере необходимости. Если один из этих элементов недоступен, тест завершится неудачно, что означает, что он не может найти элемент. Использование явных ожиданий по мере необходимости (когда вы ожидаете изменения страницы /DOM) в тесте.
Но опять же, на этот вопрос есть свое мнение и есть ответы. Проверка / ожидание присутствия элемента на каждом этапе на этом пути требует затрат времени на выполнение и может просто продлить тест, который может быстрее закончиться неудачей.