Як змусити Selenium WebDriver натиснути на елемент, який наразі не видно?


99

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

Я б хотів імітувати клацання цих прапорців за допомогою Selenium. Елемент є видимим і корисним у звичайному браузері, але селен запевняє, що елементи не видно.

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

Чи можу я змусити селен ігнорувати невидимий стан елементів? Як я можу змусити Селен взаємодіяти з невидимим елементом?


Який браузер ви використовуєте? Ви не можете взаємодіяти з елементами, які вимкнено або не видно, оскільки кінцевий користувач не зможе взаємодіяти з ними. Вам потрібно буде надати свій тестовий код та джерело сторінки, якщо ви хочете, щоб я спробував і діагностував проблему.
Ардеско

Відповіді:


102

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

  • видимість! = приховано
  • display! = none (перевіряється також проти кожного батьківського елемента)
  • непрозорість! = 0 (це не перевірено для клацання елемента)
  • висота і ширина -> 0
  • для вводу, тип атрибута! = приховано

Ваш елемент відповідає одному з цих критеріїв. Якщо у вас немає можливості змінити стильовий елемент, ось як це можна насильно робити за допомогою JavaScript (збирається припустити WebDriver з тих пір, як ви сказали API Selenium2):

((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


1
Чи є у вас джерело (або канонічне посилання) для переліку умов?
міс

2
Поки ви можете читати Javascript, метод bot.dom.isShown визначає видимість: code.google.com/p/selenium/source/browse/trunk/javascript/atoms/…
lukeis

що тут введенняЕлементу. Я запускаю наведений нижче код WebElement inputElement = driver.findElement (By.xpath (PASSWORD_PATH)); ((JavascriptExecutor) драйвер) .executeScript ("аргументи [0]. Перевірений = вірно;", inputElement); Але немає довідки inputElement.sendKeys (пароль);
Діпак Гоел

2
@NIleshSharma python має метод Execute_script безпосередньо на самому об'єкті драйвера: driver.execute_script (...)
lukeis

1
Посилання на джерело, розміщене @TunaBum, змінилося на code.google.com/p/selenium/source/browse/javascript/atoms/…
Shepmaster

27

Іноді це означає, що на сторінці є кілька елементів, які мають однакову властивість, яку ви намагаєтеся шукати, і ви "розмовляєте з невірним".

Якщо ваш елемент не може бути однозначно ідентифікований за допомогою: 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

Сподіваюся, це допомагає.


додавання id до елемента dom виправило його для мене
naoru

У мене була така ж проблема і коригування XPath, щоб він міг розрізнити унікальний елемент, який зробив свою справу.
JohnL

У мене була така ж проблема. Змінено виклик на findElements () для підрахунку збігів, і був ще один елемент, що відповідає. Дякую!
Овен

Стільки це для мене. ЗАВЖДИ переконайтесь, що критерії вибору є достатньо конкретними для елемента, з яким ви думаєте, що взаємодієте. Багато разів у мене було два елементи в грі, а один прихований і дає мені цю помилку.
Кріс

14

У мене була схожа проблема, але вона стосувалася того, що елемент не був видно у вікні перегляду. Я зробив скріншот і зрозумів, що вікно браузера занадто вузьке, і елемент не було видно. Я зробив один із них, і це спрацювало:

driver.maximize_window()

Дивіться: WebDriver.maximize_window ()


7

Або ви можете використовувати клас 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();

7

Існує також інший випадок, коли видимий елемент буде розпізнаний як невидимий:

  • Коли Елемент перетворюється CSS
  • Коли батьківський елемент елемента перетворюється CSS

Для того, щоб перевірити, чи перетворений елемент, з яким ви не хочете взаємодіяти, на CHROME зробіть це:

  1. відкритий інспектор
  2. Знайдіть цікавий елемент (або, швидше за все, його батьківський елемент, елемент нібито div)
  3. Виберіть вкладку "Обчислені"
  4. якщо є параметр: webkit-transform: matrix (...), це означає, що елемент перетворений CSS і може не розпізнаватися селеном 2 як видимий елемент


2

У мене була така ж проблема із селеном 2 в Internet Explorer 9, але моє виправлення справді дивне. Мені не вдалося натиснути на вхідні дані всередині моєї форми -> селен повторюється, їх не видно.

Це сталося, коли в моїй формі були вигнуті тіні -> http://www.paulund.co.uk/creating-different-css3-box-shadows-effects : у конкретному "Ефект №2"

Я не маю поняття, чому і як це рішення псевдоелементів зупинило тести на селен, але це працює для мене.


2

Ви не можете примушувати доступ / зміна елемента, до якого користувач зазвичай не має доступу, оскільки Selenium створений для імітації взаємодії з користувачем.

Якщо ця помилка трапиться, перевірте, чи:

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

1
Я не уявляв, що Селен призначений бути таким суворим. Здається, це насправді не інструмент автоматизації в загальному сенсі, а більше автоматизований інструмент взаємодії з користувачем. Має певного сенсу, я думаю. Дякуємо за уточнення!
Даніель Лідстрем

1

Я просто вирішую цю помилку під час використання capybara в проекті ror, додавши:

Capybara.ignore_elements = true

до features/support/env.rb.


1

Я просто вирішую цю помилку, очікуючи властивість відображення елемента

waitFor() { element.displayed }

З усіх відповідей на цій сторінці саме це вирішило мою проблему за допомогою діалогового вікна Bootstrap Modal. Дякую @Suat Keskin!
вранці

1

Я потрапляю у виняток 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>

1

На цій сторінці є багато хороших відповідей.

  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);
    }

див. Елемент прокрутки до View with Selenium для отримання додаткових прикладів


0

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


0

Щоб додати сюди моє пісочне зерно: якщо елемент знаходиться за фіксованим ділом, він вважатиметься невидимим, і ви не зможете натиснути його; це сталося зі мною недавно, і я вирішив його, виконуючи сценарій, як було рекомендовано вище, що:

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

Який тут локатор?
Аняна
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.