Как проверить, если элемент виден с WebDriver
С WebDriver от Selenium 2. 0a2 у меня возникли проблемы с проверкой, если элемент виден.
WebDriver.findElement возвращает a WebElement, который, к сожалению, не предлагает isVisible метод. Я могу обойти это с помощью WebElement.clear или WebElement.click оба из которых бросить ElementNotVisibleException, но это кажется очень грязным.
идеи получше?
13 ответов:
хотя я несколько запоздал с ответом на вопрос:
теперь вы можете использовать
WebElement.isDisplayed()чтобы проверить, виден ли элемент.Примечание:
есть много причин, почему элемент может быть невидимым. Селен пытается охватить большинство из них, но есть крайние случаи, когда он не работает, как ожидалось.
например,
isDisplayed()тут возвращениеfalseесли элементdisplay: noneилиopacity: 0, но в по крайней мере, в моем тесте он не надежно обнаруживает, покрыт ли элемент другим из-за позиционирования CSS.
у меня есть следующие 2 предложенных способов:
можно использовать
isDisplayed()как показано ниже:driver.findElement(By.id("idOfElement")).isDisplayed();вы можете определить метод, как показано ниже и назовите его:
public boolean isElementPresent(By by) { try { driver.findElement(by); return true; } catch (org.openqa.selenium.NoSuchElementException e) { return false; } }теперь вы можете сделать утверждение, как показано ниже, чтобы проверить, присутствует ли элемент или нет:
assertTrue(isElementPresent(By.id("idOfElement")));
Если вы используете C#, это будет водитель.Отображается. Вот пример из моего собственного проекта:
if (!driver.FindElement(By.Name("newtagfield")).Displayed) //if the tag options is not displayed driver.FindElement(By.Id("expand-folder-tags")).Click(); //make sure the folder and tags options are visible
важно увидеть, если элемент виден или нет, как
Driver.FindElementбудет проверять только источник HTML. Но всплывающий код может быть в html-странице и не быть видимым. Таким образом,Driver.FindElementфункция возвращает ложное срабатывание (и ваш тест не пройдет)
проверка ele видна.
public static boolean isElementVisible(final By by) throws InterruptedException { boolean value = false; if (driver.findElements(by).size() > 0) { value = true; } return value; }
короткий ответ: используйте
#visibilityOfElementLocatedни один из ответов с помощью
isDisplayedили подобные правильные. Они только проверяют, еслиdisplayсобственность-это неnone, нет, если элемент действительно можно увидеть! Селена была куча статических методов, добавленных вExpectedConditionsкласса. Два из них могут быть использованы в данном случае:
- visibilityOfElementLocated (элемент не допускается существуют)
- visibilityOf (элемент должен существовать)
использование
@Test // visibilityOfElementLocated has been statically imported public demo(){ By searchButtonSelector = By.className("search_button"); WebDriverWait wait = new WebDriverWait(driver, 10); driver.get(homeUrl); WebElement searchButton = wait.until( visibilityOfElementLocated (searchButtonSelector)); //clicks the search button searchButton.click();выборочная проверка видимости выполняется на клиенте
это был мой ответ, прежде чем узнать о методах утилиту на
ExpectedConditions. Это все еще может быть актуально, поскольку я предполагаю, что он делает больше, чем упомянутый выше метод, который только проверяет, что элемент имеет высоту и ширину.в сущности: на это нельзя ответить с помощью Java и
findElementBy*методы и , так как они могут только сказать вам, если элемент , нет, если это на самом деле видимого. ОП не определил, что видимого означает, но это обычно влечет за собой
- он имеет
opacity> 0- он имеет
displayсвойство установлено на что-то другое, чемnone- the
visibilityprop имеет значениеvisible- других элементов нет скрывая его (это самый верхний элемент)
большинство людей также включили бы требование о том, что он находится на самом деле в окне просмотра (так что человек сможет его увидеть).
по какой-то причине эта вполне нормальная потребность не удовлетворяется чистым Java API, в то время как интерфейсы для Selenium, которые основаны на нем, часто реализуют некоторые вариации
isVisible, вот почему я знал, что это должно быть возможно. И после просмотра источника структуры узла WebDriver.IO я нашел источник наisVisible, который теперь переименован в более удачное имяisVisibleInViewportв 5.0-бета.в основном, они реализуют свою команду как назвать это делегирует javascript, который работает на клиенте и делает фактическую работу! Это "сервер" бит:
export default function isDisplayedInViewport () { return getBrowserObject(this).execute(isDisplayedInViewportScript, { [ELEMENT_KEY]: this.elementId, // w3c compatible ELEMENT: this.elementId // jsonwp compatible }) }Итак, интересный бит-это javascript, отправленный для запуска на клиенте:
/** * check if element is visible and within the viewport * @param {HTMLElement} elem element to check * @return {Boolean} true if element is within viewport */ export default function isDisplayedInViewport (elem) { const dde = document.documentElement let isWithinViewport = true while (elem.parentNode && elem.parentNode.getBoundingClientRect) { const elemDimension = elem.getBoundingClientRect() const elemComputedStyle = window.getComputedStyle(elem) const viewportDimension = { width: dde.clientWidth, height: dde.clientHeight } isWithinViewport = isWithinViewport && (elemComputedStyle.display !== 'none' && elemComputedStyle.visibility === 'visible' && parseFloat(elemComputedStyle.opacity, 10) > 0 && elemDimension.bottom > 0 && elemDimension.right > 0 && elemDimension.top < viewportDimension.height && elemDimension.left < viewportDimension.width) elem = elem.parentNode } return isWithinViewport }этот кусок JS фактически может быть скопирован (почти) дословно в вашу собственную кодовую базу (remove
export defaultи заменитьconstСvarв случае не вечнозеленых браузеров)! Чтобы использовать его, прочитайте его изFileнаStringэто может быть отправлено Selenium для запуска на клиенте.еще один интересный и связанный с ним скрипт, который, возможно, стоит изучить, это selectByVisibleText.
если вы не выполнили JS с использованием Селена, прежде чем вы могли бы небольшой загляни в это или просмотра JavaScriptExecutor API.
обычно, старайтесь всегда использовать неблокирующие асинхронные Скрипты (что означает #executeAsyncScript), но поскольку у нас уже есть синхронный блокирующий скрипт, мы можем также использовать обычный вызов синхронизации. Возвращаемый объект может быть много типов объектов, поэтому приведите соответственно. Это может быть один из способов сделать это:
/** * Demo of a java version of webdriverio's isDisplayedInViewport * https://github.com/webdriverio/webdriverio/blob/v5.0.0-beta.2/packages/webdriverio/src/commands/element/isDisplayedInViewport.js * The super class GuiTest just deals with setup of the driver and such */ class VisibleDemoTest extends GuiTest { public static String readScript(String name) { try { File f = new File("selenium-scripts/" + name + ".js"); BufferedReader reader = new BufferedReader( new FileReader( file ) ); return reader.lines().collect(Collectors.joining(System.lineSeparator())); } catch(IOError e){ throw new RuntimeError("No such Selenium script: " + f.getAbsolutePath()); } } public static Boolean isVisibleInViewport(RemoteElement e){ // according to the Webdriver spec a string that identifies an element // should be deserialized into the corresponding web element, // meaning the 'isDisplayedInViewport' function should receive the element, // not just the string we passed to it originally - how this is done is not our concern // // This is probably when ELEMENT and ELEMENT_KEY refers to in the wd.io implementation // // Ref https://w3c.github.io/webdriver/#dfn-json-deserialize return js.executeScript(readScript("isDisplayedInViewport"), e.getId()); } public static Boolean isVisibleInViewport(String xPath){ driver().findElementByXPath("//button[@id='should_be_visible']"); } @Test public demo_isVisibleInViewport(){ // you can build all kinds of abstractions on top of the base method // to make it more Selenium-ish using retries with timeouts, etc assertTrue(isVisibleInViewport("//button[@id='should_be_visible']")); assertFalse(isVisibleInViewport("//button[@id='should_be_hidden']")); } }
вот как я бы это сделал (Пожалуйста, игнорируйте вызовы класса worry Logger):
public boolean isElementExist(By by) { int count = driver.findElements(by).size(); if (count>=1) { Logger.LogMessage("isElementExist: " + by + " | Count: " + count, Priority.Medium); return true; } else { Logger.LogMessage("isElementExist: " + by + " | Could not find element", Priority.High); return false; } } public boolean isElementNotExist(By by) { int count = driver.findElements(by).size(); if (count==0) { Logger.LogMessage("ElementDoesNotExist: " + by, Priority.Medium); return true; } else { Logger.LogMessage("ElementDoesExist: " + by, Priority.High); return false; } } public boolean isElementVisible(By by) { try { if (driver.findElement(by).isDisplayed()) { Logger.LogMessage("Element is Displayed: " + by, Priority.Medium); return true; } } catch(Exception e) { Logger.LogMessage("Element is Not Displayed: " + by, Priority.High); return false; } return false; }
public boolean isElementFound( String text) { try{ WebElement webElement = appiumDriver.findElement(By.xpath(text)); System.out.println("isElementFound : true :"+text + "true"); }catch(NoSuchElementException e){ System.out.println("isElementFound : false :"+text); return false; } return true; } text is the xpath which you would be passing when calling the function. the return value will be true if the element is present else false if element is not pressent
try{ if( driver.findElement(By.xpath("//div***")).isDisplayed()){ System.out.println("Element is Visible"); } } catch(NoSuchElementException e){ else{ System.out.println("Element is InVisible"); } }
попробуй такое
public boolean isPrebuiltTestButtonVisible() { try { if (preBuiltTestButton.isEnabled()) { return true; } else { return false; } } catch (Exception e) { e.printStackTrace(); return false; } }
element instanceof RenderedWebElementдолжны работать. // Но это для более старой версии selenium rc.обратите внимание:
RenderedWebElementбыл устаревший четыре года назад (в 2013 г.).он поддерживался до селен-2.0-rc-2 и удалены из selenium-2.0-rc-3 и далеетак что нет такого класса
RenderedWebElementв последней версии.Текущая версия 2.46.0.Попробуйте использовать последнюю версиюПожалуйста, Используйте
WebElementвместо этого нет необходимости бросить и все сisDisplayed() isEnabled() and driver.findElements(By.xpath(accessor)).size() > 0что-то вроде этого:
public static boolean isElementFoundDisplayedEnabled(WebDriver driver, String accessor){ return driver.findElements(By.xpath(accessor)).size() > 0 && driver.findElement(By.xpath(accessor)).isDisplayed() && driver.findElement(By.xpath(accessor)).isEnabled(); //isDisplayed(): method avoids the problem of having to parse an element's "style" attribute to check hidden/visible. False when element is not present //isEnabled(): generally return true for everything but disabled input elements. }
Comments