Как заставить Selenium WebDriver нажать на элемент, который в данный момент не виден?
Я использую Selenium 2 Java API с FirefoxDriver. Когда я заполняю форму, флажки добавляются на страницу в зависимости от формы ввода.
Я хотел бы смоделировать нажатие на эти флажки с помощью Selenium. Элемент видим и может использоваться в обычном браузере, но Селен утверждает, что элементы не видны.
"Element is not currently visible and so may not be interacted with"
Можно ли заставить селен игнорировать невидимое состояние элементов? Как я могу заставить Selenium взаимодействовать с невидимым элементом?
13 ответов
Selenium определяет, является ли элемент видимым или нет по следующим критериям (используйте инспектор DOM, чтобы определить, что CSS применяет к вашему элементу, убедитесь, что вы смотрите на вычисленный стиль):
- видимость!= скрыто
- display!= none (также проверяется для каждого родительского элемента)
- opacity!= 0 (это не проверяется при нажатии на элемент)
- высота и ширина оба> 0
- для ввода тип атрибута!= скрытый
Ваш элемент соответствует одному из этих критериев. Если у вас нет возможности изменить стиль элемента, вот как вы можете принудительно сделать это с помощью javascript (предполагается, что WebDriver, так как вы сказали Selenium2 API):
((JavascriptExecutor)driver).executeScript("arguments[0].checked = true;", inputElement);
Но это не вызовет событие javascript, если вы зависите от события change для этого ввода, вам придется его также запускать (существует много способов сделать это, проще всего использовать любую библиотеку javascript, загруженную на этой странице).
Источник для проверки видимости -
https://github.com/SeleniumHQ/selenium/blob/master/javascript/atoms/dom.js#L577
Спецификация WebDriver, которая определяет это -
https://dvcs.w3.org/hg/webdriver/raw-file/tip/webdriver-spec.html
Иногда это означает, что на странице есть несколько элементов с тем же свойством, по которому вы пытаетесь выполнить поиск, и вы "говорите не с тем".
Если ваш элемент не может быть однозначно идентифицирован с помощью:id или:name (или:class), это может быть сложно.
Иногда поиск элемента с помощью:xpath поможет, а в некоторых случаях даже это нецелесообразно.
В этих случаях вам может потребоваться получить все элементы, которые соответствуют вашим критериям, и ссылаться на правильный элемент по индексу. Это грязно, но это работает.
Я использую Selenium / Watir из приложения Ruby on Rails, поэтому в моем случае пример будет:
browser = Watir::Browser.new(:firefox, :profile => "default")
browser.goto("http://www.google.com/analytics")
# login
browser.divs(:text, "+ New Property").last.click
Надеюсь это поможет.
У меня была похожая проблема, но она была связана с тем, что элемент не был виден в окне просмотра. Я сделал скриншот и понял, что окно браузера слишком узкое, и элемент не виден. Я сделал один из них, и это сработало:
driver.maximize_window()
Смотрите: WebDriver.maximize_window ()
Или вы можете использовать Selenium Action Class для симуляции взаимодействия с пользователем - например,
WebDriver = new FirefoxDriver();
WebElement menu = driver.findElement(By.xpath("")); // the triger event element
Actions build = new Actions(driver); // heare you state ActionBuider
build.moveToElement(menu).build().perform(); // Here you perform hover mouse over the needed elemnt to triger the visibility of the hidden
WebElement m2m= driver.findElement(By.xpath(""));//the previous non visible element
m2m.click();
Существует также еще один случай, когда видимый элемент будет распознан как невидимый:
- Когда Элемент CSS преобразуется
- Когда родительский элемент элемента CSS преобразуется
Чтобы проверить, является ли элемент, с которым вы не хотите взаимодействовать, преобразованным CSS, в CHROME сделайте следующее:
- открытый инспектор
- Найти интересный элемент (или, скорее, его родительский элемент, предположительно, элемент div)
- Выберите вкладку "Вычислено"
- если есть параметр: webkit-transform: matrix( ...), это означает, что элемент преобразован в CSS и может быть не распознан селеном 2 как видимый элемент
Невидимость также может быть вызвана временем, когда элемент должен медленно появляться. В этом случае может помочь принудительное ожидание браузера.
См., Например, вопрос о том, как позволить WebDriver дождаться появления элемента.
На этой странице есть много хороших ответов.
- Обычно я начинаю с maximize.window(), на самом деле я делаю это в Driver Factory или там, где вы инициализируете свой драйвер. Это делается по умолчанию - всегда.
- Обычно это ожидание элемента из-за некоторой задержки javascript.
Оба обсуждаются в различных деталях выше. Ответ, который я не видел, был ScrollToElement. Похоже, вы обрабатываете список элементов, а во время обработки вы создаете больше элементов, флажков. Это может привести к тому, что элементы в вашем списке переместятся с видимой страницы. Иногда элемент можно увидеть невооруженным глазом, но щелкнуть по нему просто невозможно. При обработке списков иногда приходится вставлять прокрутку.
- Установите точку останова и проверьте, находится ли используемый вами элемент на краю окна, вверху / внизу справа / слева. Иногда, когда это так, вы не можете добраться до него через селен, но вы можете вручную щелкнуть мышью.
Поскольку я наткнулся на это, я создал PageScroll.java и поместил туда свои сценарии прокрутки. Вот несколько методов из этого класса:
public static void scrollToTop(WebDriver driver) {
((JavascriptExecutor) driver)
.executeScript("window.scrollTo(0,0)");
}
public static void scrollToBottom(WebDriver driver) {
((JavascriptExecutor) driver)
.executeScript("window.scrollTo(0, document.body.scrollHeight)");
}
public static void scrollToElementTop(WebDriver driver, WebElement element) {
((JavascriptExecutor) driver).executeScript(
"arguments[0].scrollIntoView(true);", element);
}
public static void scrollToElementBottom(WebDriver driver, WebElement element) {
((JavascriptExecutor) driver).executeScript(
"arguments[0].scrollIntoView(false);", element);
}
см. " Прокрутить элемент в представление с помощью Selenium" для получения дополнительных примеров
Я просто решаю эту ошибку, ожидая свойства отображения элемента
waitFor() { element.displayed }
Вы не можете принудительно получить доступ / изменить элемент, к которому пользователь обычно не имеет доступа, так как Selenium предназначен для имитации взаимодействия с пользователем.
Если эта ошибка произошла, проверьте:
- элемент виден в вашем окне просмотра, попробуйте развернуть текущее окно, которое использует веб-драйвер (например,
maximize()
в node.js,maximize_window()
в Python), - ваш элемент не появляется дважды (под одним и тем же селектором), и вы выбираете неправильный,
- если ваш элемент скрыт, то рассмотрите возможность сделать его видимым,
- если вы хотите получить доступ / изменить значение скрытого элемента, несмотря на ограничения, используйте для этого Javascript (например,
executeScript()
в node.js,execute_script()
в Python).
У меня была такая же проблема с селеном 2 в Internet Explorer 9, но мое исправление действительно странное. Я не смог нажать на входы внутри моей формы -> повторения селена, их не видно.
Это произошло, когда моя форма имела изогнутые тени -> http://www.paulund.co.uk/creating-different-css3-box-shadows-effects: в конкретном "Эффекте № 2"
Я понятия не имею, почему и как это решение с псевдоэлементом остановило тесты на селен, но оно работает для меня.
Чтобы добавить здесь мою песчинку: если элемент находится за фиксированным тегом div, он будет считаться невидимым, и вы не сможете щелкнуть по нему; это случилось со мной недавно, и я решил это, выполнив скрипт, как рекомендовано выше, который делает:
document.evaluate("<xpath locator for element to be clicked>", document, null, XPathResult.ANY_TYPE, null).iterateNext().click()", locator);
Я получаю исключение ElementNotVisibleException, используя селен для функциональных тестов на сайте django с начальными глификонами в качестве ссылок в шаблонах:
<a href="{% url 'item-add' %}"><span class="glyphicon glyphicon-plus text-danger"></span></a>
Во время моих функциональных тестов стиль начальной загрузки не загружается, поэтому попытка щелкнуть по таким ссылкам вызовет исключение ElementNotVisibleException. Мне удается сделать их кликабельными, просто добавив пробел в теге, вот так:
<a href="{% url 'item-add' %}"><span class="glyphicon glyphicon-plus text-danger"> </span></a>
Я просто решаю эту ошибку при использовании капибары в проекте ror, добавив:
Capybara.ignore_elements = true
в features/support/env.rb
,
Принятый ответ сработал для меня. Ниже приведен код для поиска родительского элемента, который заставляет Selenium думать, что его не видно.
function getStyles(element){
computedStyle = window.getComputedStyle(element);
if(computedStyle.opacity === 0
|| computedStyle.display === "none"
|| computedStyle.visibility === "hidden"
|| (computedStyle.height < 0 && computedStyle.height < 0)
|| element.type === "hidden") {
console.log("Found an element that Selenium will consider to not be visible")
console.log(element);
console.log("opacity: " + computedStyle.opacity);
console.log("display: " + computedStyle.display);
console.log("visibility: " + computedStyle.visibility);
console.log("height: " + computedStyle.height);
console.log("width: " + computedStyle.width);
}
if(element.parentElement){
getStyles(element.parentElement);
}
}
getStyles(document.getElementById('REPLACE WITH THE ID OF THE ELEMENT YOU THINK IS VISIBLE BUT SELENIUM CAN NOT FIND'));