Проверить наличие элемента с помощью Selenium WebDriver?

Есть ли способ проверить, присутствует ли элемент? Любой метод findElement завершится исключением, но это не то, что я хочу, потому что может быть, что элемент отсутствует, и это нормально, это не провал теста, поэтому исключение не может быть решением.

Я нашел этот пост: Selenium С# Webdriver: Подождите, пока не появится элемент. Но это для С#, и я не очень хорош в этом. Может ли кто-нибудь перевести код на Java? Мне жаль, ребята, я попробовал это в Eclipse, но я не понимаю его в Java-коде.

Это код:

public static class WebDriverExtensions{
    public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds){

        if (timeoutInSeconds > 0){
            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
            return wait.Until(drv => drv.FindElement(by));
        }

        return driver.FindElement(by);
    }
}

Ответ 1

Используйте findElements вместо findElement.

findElements вернет пустой список, если не найдены соответствующие элементы вместо исключения.

Чтобы проверить, присутствует ли элемент, вы можете попробовать это

Boolean isPresent = driver.findElements(By.yourLocator).size() > 0

Это вернет true, если хотя бы один элемент найден, и false, если он не существует.

Официальная документация рекомендует этот метод:

findElement не должен использоваться для поиска несуществующих элементов, используйте findElements (By) и вместо этого утверждайте ответ нулевой длины.

Ответ 2

Как насчет частного метода, который просто ищет элемент и определяет, присутствует ли он вот так:

private boolean existsElement(String id) {
    try {
        driver.findElement(By.id(id));
    } catch (NoSuchElementException e) {
        return false;
    }
    return true;
}

Это будет довольно легко и выполнит эту работу.

Изменить: вы даже можете пойти дальше и взять параметр By elementLocator as, устраняя проблемы, если вы хотите найти элемент с помощью чего-то другого, кроме id.

Ответ 3

Я обнаружил, что это работает для Java:

WebDriverWait waiter = new WebDriverWait(driver, 5000);
waiter.until( ExpectedConditions.presenceOfElementLocated(by) );
driver.FindElement(by);

Ответ 4

public static WebElement FindElement(WebDriver driver, By by, int timeoutInSeconds)
{
    WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds);
    wait.until( ExpectedConditions.presenceOfElementLocated(by) ); //throws a timeout exception if element not present after waiting <timeoutInSeconds> seconds
    return driver.findElement(by);
}

Ответ 5

У меня была такая же проблема. Для меня, в зависимости от уровня разрешения пользователя, некоторые ссылки, кнопки и другие элементы не отображаются на странице. Часть моего пакета тестировала, что элементы, которые ДОЛЖНЫ быть отсутствующими, отсутствуют. Я потратил часы, пытаясь понять это. Наконец я нашел идеальное решение.

Что это значит, это означает, что браузер ищет все установленные элементы. Если это приводит к 0, это означает, что элементы, основанные на спецификации, не найдены. Тогда у меня есть код, выполняющий оператор if, чтобы сообщить мне, что он не был найден.

Это находится в C#, поэтому переводы должны выполняться с Java. Но не должно быть слишком сложно.

public void verifyPermission(string link)
{
    IList<IWebElement> adminPermissions = driver.FindElements(By.CssSelector(link));
    if (adminPermissions.Count == 0)
    {
        Console.WriteLine("User permission properly hidden");
    }
}

Там также есть другой путь, который вы можете взять в зависимости от того, что вам нужно для вашего теста.

Следующий фрагмент проверяет, существует ли на странице очень специфический элемент. В зависимости от существования элемента у меня есть тест execute if if else.

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

Если элемент "Не существует" и не отображается на странице. У меня есть else в if, если еще выполнить тест.

IList<IWebElement> deviceNotFound = driver.FindElements(By.CssSelector("CSS LINK GOES HERE"));
//if the element specified above results in more than 0 elements and is displayed on page execute the following, otherwise execute whats in the else statement
if (deviceNotFound.Count > 0 && deviceNotFound[0].Displayed){
    //script to execute if element is found
} else {
    //Test script goes here.
}

Я знаю, что немного опоздал на ответ на OP. Надеюсь, это поможет кому-то!

Ответ 6

Попробуйте следующее: Вызвать этот метод и передать 3 аргумента:

  • переменная WebDriver.//Предположим, что driver_variable в качестве драйвера.
  • Элемент, который вы собираетесь проверить. Должен обеспечить метод By.//ex: By.id( "id" )
  • Ограничение по времени в секундах.

Пример: waitForElementPresent (драйвер, By.id( "id" ), 10);

public static WebElement waitForElementPresent(WebDriver driver, final By by, int timeOutInSeconds) {

        WebElement element; 

        try{
            driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait() 

            WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds); 
            element = wait.until(ExpectedConditions.presenceOfElementLocated(by));

            driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); //reset implicitlyWait
            return element; //return the element
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return null; 
    }

Ответ 7

Вы можете сделать код быстрее, сократив тайм-аут селена до утверждения try catch.

Я использую следующий код, чтобы проверить, присутствует ли элемент.

protected boolean isElementPresent(By selector) {
    selenium.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
    logger.debug("Is element present"+selector);
    boolean returnVal = true;
    try{
        selenium.findElement(selector);
    } catch (NoSuchElementException e){
        returnVal = false;
    } finally {
        selenium.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
    }
    return returnVal;
}

Ответ 8

Напишите следующую функцию/методы, используя Java:

protected boolean isElementPresent(By by){
        try{
            driver.findElement(by);
            return true;
        }
        catch(NoSuchElementException e){
            return false;
        }
    }

Вызвать метод с соответствующим параметром во время утверждения.

Ответ 9

если вы используете rspec-Webdriver в ruby, вы можете использовать этот script, полагая, что элемент действительно не присутствует, и это пройденный тест.

Сначала напишите этот метод сначала из своего файла RB класса

class Test
 def element_present?
    begin
        browser.find_element(:name, "this_element_id".displayed?
        rescue Selenium::WebDriver::Error::NoSuchElementError
            puts "this element should not be present"
        end
 end

Затем в вашем файле спецификации вызовите этот метод.

  before(:all) do    
    @Test= Test.new(@browser)
  end

 @Test.element_present?.should == nil

Если ваш элемент НЕ присутствует, ваш спецификатор пройдет, но если элемент присутствует, он выдаст ошибку, тест не будет выполнен.

Ответ 10

Это работает для меня:

 if(!driver.findElements(By.xpath("//*[@id='submit']")).isEmpty()){
    //THEN CLICK ON THE SUBMIT BUTTON
}else{
    //DO SOMETHING ELSE AS SUBMIT BUTTON IS NOT THERE
}

Ответ 11

Самый простой способ, который я нашел в Java:

List<WebElement> linkSearch=  driver.findElements(By.id("linkTag"));
int checkLink=linkSearch.size();
if(checkLink!=0){  //do something you want}

Ответ 12

Чтобы найти определенный Элемент, присутствует или нет, мы должны использовать метод findElements() вместо findElement()..

int i=driver.findElements(By.xpath(".......")).size();
if(i=0)
System.out.println("Element is not present");
else
System.out.println("Element is present");

это сработало для меня.. предложите мне, если я ошибаюсь.

Ответ 13

Это должно сделать это:

try {
    driver.findElement(By.id(id));
} catch (NoSuchElementException e) {
    //do what you need here if you were expecting
    //the element wouldn't exist
}

Ответ 14

Вы можете попробовать неявное ожидание:

WebDriver driver = new FirefoxDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
driver.Url = "http://somedomain/url_that_delays_loading";
IWebElement myDynamicElement = driver.FindElement(By.Id("someDynamicElement"));

'

Или Вы можете попробовать явно подождать: '

IWebDriver driver = new FirefoxDriver();
driver.Url = "http://somedomain/url_that_delays_loading";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
    {
        return d.FindElement(By.Id("someDynamicElement"));
    });

'

Явный проверит, присутствует ли элемент перед каким-либо действием. Неявное ожидание может быть вызвано в любом месте кода. Например, после некоторых действий AJAX.

Больше вы можете найти на странице SeleniumHQ

Ответ 15

Предоставление моего фрагмента кода. Таким образом, приведенный ниже метод проверяет наличие на странице случайного веб-элемента " Создать новое приложение". Обратите внимание, что я использовал период ожидания как 0 секунд.

public boolean isCreateNewApplicationButtonVisible(){
    WebDriverWait zeroWait = new WebDriverWait(driver, 0);
    ExpectedCondition<WebElement> c = ExpectedConditions.presenceOfElementLocated(By.xpath("//input[@value='Create New Application']"));
    try {
        zeroWait.until(c);
        logger.debug("Create New Application button is visible");
        return true;
    } catch (TimeoutException e) {
        logger.debug("Create New Application button is not visible");
        return false;
    }
}

Ответ 16

Я бы использовал что-то вроде (с Scala [код в старой "хорошей" Java 8 может быть похож на это]):

object SeleniumFacade {

  def getElement(bySelector: By, maybeParent: Option[WebElement] = None, withIndex: Int = 0)(implicit driver: RemoteWebDriver): Option[WebElement] = {
    val elements = maybeParent match {
      case Some(parent) => parent.findElements(bySelector).asScala
      case None => driver.findElements(bySelector).asScala
    }
    if (elements.nonEmpty) {
      Try { Some(elements(withIndex)) } getOrElse None
    } else None
  }
  ...
}

значит,

val maybeHeaderLink = SeleniumFacade getElement(By.xpath(".//a"), Some(someParentElement))

Ответ 17

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

Ответ 18

public boolean isElementDisplayed() {
        return !driver.findElements(By.xpath("...")).isEmpty();
    }

Ответ 19

Лично я всегда использую смесь вышеупомянутых ответов и создаю повторно используемый статический метод Utility, который использует предложение size() < 0:

public Class Utility {
   ...
   public static boolean isElementExist(WebDriver driver, By by) {
      return driver.findElements(by).size() < 0;
   ...
}

Это аккуратный, многоразовый, поддерживаемый... весь этот хороший материал; -)