Как заставить Selenium WebDriver щелкнуть элемент, который в настоящее время не отображается?

Я использую Java-интерфейс Selenium 2 с FirefoxDriver. Когда я заполняю форму, флажки добавляются на страницу в зависимости от ввода форм.

Я хотел бы имитировать щелчок на этих флажках с помощью Selenium. Элемент отображается и доступен в обычном браузере, но селен утверждает, что элементы не видны.

"Element is not currently visible and so may not be interacted with"

Могу ли я заставить селен игнорировать невидимое состояние элементов? Как заставить Selenium взаимодействовать с невидимым элементом?

Ответ 1

Selenium определяет, что элемент виден или нет по следующим критериям (используйте инспектор DOM для определения того, что css относится к вашему элементу, убедитесь, что вы смотрите на вычисленный стиль):

  • видимость!= скрытый
  • display!= none (также проверяется на каждый родительский элемент)
  • opacity!= 0 (это не проверено для щелчка элемента)
  • высота и ширина: > 0
  • для ввода, тип атрибута!= hidden

Ваш элемент соответствует одному из этих критериев. Если у вас нет возможности изменить стиль элемента, вот как вы можете сделать это с помощью javascript (предполагая WebDriver, так как вы сказали Selenium2 API):

((JavascriptExecutor)driver).executeScript("arguments[0].checked = true;", inputElement);

Но это не приведет к срабатыванию javascript-события, если вы зависите от события изменения для этого ввода, вам придется его также запускать (многие способы сделать это проще всего использовать любую библиотеку 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#widl-WebElement-isDisplayed-boolean

Ответ 2

Иногда это означает, что на странице есть несколько элементов, которые имеют то же свойство, что и вы, и вы "разговариваете с неправильным".

Если ваш элемент не может быть однозначно идентифицирован с помощью: 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

Надеюсь, что это поможет.

Ответ 3

У меня была аналогичная проблема, но она была связана с тем, что элемент не отображается в окне просмотра. Я сделал снимок экрана и понял, что окно браузера слишком узкое, и элемент не видно. Я сделал один из них, и он работал:

driver.maximize_window()

Смотрите: WebDriver.maximize_window()

Ответ 4

Или вы можете использовать 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();

Ответ 5

Существует также другой случай, когда видимый элемент будет распознан как невидимый:

  • Когда элемент преобразуется в CSS
  • Когда родительский элемент элемента преобразуется в CSS

Чтобы проверить, не будет ли элемент, с которым вы не взаимодействуете, преобразован CSS, на CHROME выполните следующее:

  • открытый инспектор
  • Найти интересный элемент (или, скорее, его родительский элемент, предположительно элемент div)
  • Выберите вкладку "Вычислить"
  • если есть параметр: webkit-transform: matrix (...), это означает, что элемент CSS преобразован и не может быть распознан селеном 2 как видимый элемент

Ответ 6

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

См., например, вопрос о том, чтобы WebDriver подождать, пока не появится элемент.

Ответ 7

У меня была такая же проблема с селеном 2 в Internet Explorer 9, но мое исправление действительно странно. Мне не удалось щелкнуть входы внутри моей формы → повторы селена, их не видно.

Это произошло, когда у моей формы были изогнутые тени → http://www.paulund.co.uk/creating-different-css3-box-shadows-effects: в конкретном "Эффекте № 2"

Я понятия не имею, почему & как это решение псевдоэлемента остановило тесты селена, но оно работает для меня.

Ответ 8

Вы не можете заставить доступ к/изменять элемент, к которому пользователь обычно не имеет доступа, поскольку Selenium предназначен для имитации взаимодействия с пользователем.

Если эта ошибка возникает, проверьте, есть ли:

  • Элемент
  • отображается в вашем окне просмотра, попытайтесь максимизировать текущее окно, которое использует веб-редактор (например, maximize() в node.js, maximize_window() в Python),
  • ваш элемент не появляется дважды (под тем же селектором), и вы выбираете неправильный,
  • если ваш элемент скрыт, а затем подумайте о том, чтобы сделать его видимым,
  • если вы хотите получить доступ/изменить значение скрытого элемента, несмотря на ограничение, а затем использовать Javascript для этого (например, executeScript() в node. js, execute_script() в Python).

Ответ 9

Я просто решаю эту ошибку при использовании capybara в проекте ror, добавляя:

Capybara.ignore_elements = true

до features/support/env.rb.

Ответ 10

Я просто решаю эту ошибку, ожидая свойства отображения элемента

waitFor() { element.displayed }

Ответ 11

Я получаю исключение 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">&nbsp;</span></a>

Ответ 12

Принятый ответ сработал у меня. Ниже приведен некоторый код, чтобы найти родительский элемент, который заставляет 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'));

Ответ 13

Чтобы добавить здесь мою песчинку: если элемент находится за фиксированным тегом div, он будет считаться невидимым, и вы не сможете щелкнуть по нему; это случилось со мной недавно, и я решил это, выполнив скрипт, как рекомендовано выше, который делает:

document.evaluate("<xpath locator for element to be clicked>", document, null, XPathResult.ANY_TYPE, null).iterateNext().click()", locator);

Ответ 14

На этой странице есть много хороших ответов.

  1. Обычно я начинаю с maximize.window(), на самом деле я делаю это на фабрике драйверов или везде, где вы инициализируете драйвер. Это то, что сделано по умолчанию - всегда.
  2. Обычно это ожидание элемента из-за некоторой задержки 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);
    }

см. Scroll Element to View с Selenium для большего количества примеров