Selenium WebDriver를 사용하여 요소가 존재하는지 테스트합니까?


163

요소가 있는지 테스트하는 방법이 있습니까? 모든 findElement 메소드는 예외로 끝날 것입니다.하지만 요소가 존재하지 않고 테스트에 실패하지 않아서 예외가 해결책이 될 수 없기 때문에 원하는 것은 아닙니다.

나는이 게시물을 발견했다 : Selenium c # Webdriver : 요소가 나타날 때까지 기다리십시오. 그러나 이것은 C #을위한 것이며 아주 잘하지 않습니다. 누구나 코드를 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);
    }
}

객체를 확인할 때 매우 효과적으로 작동하는 몇 가지 방법이 있지만 객체로 수행하려는 작업에 따라 다릅니다. 예를 들어, 요소가 존재할 때까지 요소를 찾고 싶거나 더 이상 존재하지 않을 때까지 요소를 찾고 싶습니까? 아니면 그냥 찾으려고합니까?
— CBRRacer

1
Java는 C #과 매우 유사합니다. 여기서 겪고있는 주요 문제 중 하나는 java에서 IWebElement 대신 WebElement라고 생각합니다.
— CBRRacer

암시 적 대기 방법에 대해 알고 있습니까? 테스트가 시작될 때 이것을 설정함으로써, 당신은 요소의 존재를 확인할 필요가 없습니다. 그것은 암시 적 대기 값을 사용하여 폴링하기 때문입니다. 그러나 그 값을 초과하면 예외가 발생합니다
— Bob Evans

다음은 Java의 WebDriverWait에 대한 내 게시물입니다. WebDriverWait

두 경우 모두 문제가 없으면 존재하지 않을 것으로 예상되는 요소를 기다리는 데 걸리는 대기 시간이 실제로 더해지기 때문에 테스트 성능에 문제가 될 수 있습니다. 나는 대기 시간을 피하기 위해 몇 가지 해킹을 사용했지만 아직 이것에 대한 진정한 해결책을 찾지 못했습니다.
— mrfreester

답변:


277

findElements대신에 사용하십시오 findElement.

findElements 예외 대신 일치하는 요소가 없으면 빈 목록을 반환합니다.

요소가 존재하는지 확인하려면 다음을 시도하십시오.

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

하나 이상의 요소가 발견되면 true를 리턴하고 존재하지 않으면 false를 리턴합니다.

공식 문서 는이 방법을 권장합니다.

findElement는 존재하지 않는 요소를 찾는 데 사용되어서는 안되며 findElements (By)를 사용하고 대신 길이가 0 인 응답을 지정하십시오.


32
테스트를 실행하는 데 시간이 많이 걸립니다. 이 기술은 어느 곳에서나 사용할 수 없습니다.
— Droogans

8
@Droogans-테스트에 시간을 추가하지 않습니다. 기본 암시 적 대기가 여전히 0이기 때문에 그 이유는 없습니다. 기본 암시 적 대기를 늘리면 그렇습니다. 그러나 여기서는 그렇지 않습니다.
— djangofan

1
장 고환 잘 부탁드립니다! 드라이버 시간 제한의 암시 적 대기를 0으로 변경 한 다음 이전 값으로 다시 변경하여이 전략을 성공적으로 사용했습니다.
— emery

3
이것은 NoSuchElementFound 예외를 주었다. 이것은 주어진 인스턴스에서 예외를 포착하지 않기 위해 이것을 사용하기를 바 랐기 때문에 부끄러운 일이다.

1
훨씬 쉬운 방법은 다음을 사용하는 것입니다. if (driver.getPageSource (). contains ( "A text in page")) {} 페이지에이 텍스트가 포함 된 경우 조건이 true이거나 그렇지 않으면 false이며 코드를 작성할 수 있습니다. 따라서.
— pradyot

56

단순히 요소를 찾고 다음과 같이 존재하는지 판별하는 개인용 메소드는 어떻습니까?

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

이것은 매우 쉽고 일을합니다.

편집 : 당신은 더 나아가서 By elementLocator매개 변수로 매개 변수를 취할 수 있습니다 .id 이외의 다른 요소로 요소를 찾으려면 문제를 제거하십시오.


3
그렇습니다, 이것은가는 길입니다. 사람들이 왜 이런 식으로 무시하고 일치하는 요소를 세는지, 결과가 0인지 알아보십시오.
— Ralph Lavelle

45
글쎄, 예외를 사용하여 프로그램 흐름을 조절하는 것이 가장 좋은 방법은 아니라고 말해야합니다.
— Dennis

2
응? 당신의 제안이었습니다! 테스트에서 요소를 찾지 못할 것으로 예상되는 경우 좋은 방법입니다. 보시다시피 null과 assert.isnull 또는 isnotnull을 반환하면 물건이 있는지 테스트하는 의미있는 방법입니다.
— Ralph Lavelle

2
"요소가 있는지 테스트하는 방법이 있습니까?"라는 질문을 잘못 해석 한 경우 이것이 잘못된 답변인지 아닌지에 대한 귀하의 의견이 다른 이유를 알게되어 기쁩니다.
— Dennis

대기 시간을 줄이고 싶을 수도 있습니다. 현재 요소가 존재하지 않으면 함수가 false를 리턴하기 전에 "30 초"를 기다려야합니다.
— Jason Smiley

14

나는 이것이 자바에서 작동한다는 것을 발견했다.

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

18
presenceOfElementLocated특정 시도에서 요소를 찾을 수 없으면 예외가 발생합니다. 이를 피하려면 wait.ignoring(NoSuchElementException.class);첫 번째 행과 두 번째 행 사이 에 명령문을 추가하십시오 .
— Steve Chambers

8
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's permission properly hidden");
    }
}

시험에 필요한 것에 따라 다른 길을 선택할 수도 있습니다.

다음 스 니펫은 페이지에 매우 구체적인 요소가 있는지 확인합니다. 요소의 존재에 따라 다른 테스트를 실행합니다.

요소가 존재하고 페이지에 표시되면 console.write알려주고 계속 진행했습니다. 문제의 요소가 존재하면 필요한 테스트를 실행할 수 없습니다.이를 설정 해야하는 주된 이유입니다.

요소가 존재하지 않고 페이지에 표시되지 않는 경우 if else에 테스트를 실행하는 else가 있습니다.

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에 대한 응답이 약간 늦었다는 것을 알고 있습니다. 잘만되면 이것은 누군가를 돕는다!


5

이것을보십시오 :이 방법을 호출하고 세 가지 인수를 전달하십시오 :

  1. WebDriver 변수. // driver_variable을 driver로 가정합니다.
  2. 확인할 요소입니다. By 메소드에서 제공해야합니다. // 예 : By.id ( "id")
  3. 시간 제한 (초)

예 : waitForElementPresent (driver, 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; 
    }

3

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

이것이 내 코드에서 사용하는 것입니다. Selenium 시간 초과를 기본값으로 유지하고 이것을 사용합니다.
— Nicholas DiPiazza

2
이 답변을 작성한 이후 ExpectedConditions를 사용하는 것이 더 나은 형태로 간주되지만 try catch 문을 사용하면 요소가 존재하지 않는지 확인할 때 여전히 유용하다는 것을 알았습니다.
— EsotericNonsense

IE8을 테스트 해야하는 이전 버전의 셀레늄 베큐 아제에 붙어 있습니다. 하지만 업그레이드 할 수있을 때 시도 할 것입니다
— Nicholas DiPiazza

메소드가 암시 적 대기 시간 초과를 설정할 때마다 논리적으로 드라이버 객체를 초기화하고 시간 초과가 드라이버 세션으로 설정된 후 한 번만 암시 적 대기를 설정해야합니다.
— Shekhar Swami

3

Java를 사용하여 다음 함수 / 메소를 작성하십시오.

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

어설 션 중에 적절한 매개 변수를 사용하여 메서드를 호출하십시오.


2

루비에서 rspec-Webdriver를 사용하는 경우 요소가 실제로 존재하지 않아야하며 통과 된 테스트라고 가정하고이 스크립트를 사용할 수 있습니다.

먼저 클래스 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

요소가 없으면 사양이 통과되지만 요소가 있으면 오류가 발생하고 테스트에 실패했습니다.


2

이것은 나를 위해 작동합니다 :

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

"// * [@ id = 'submit']"요소가 없으면 어떻게됩니까? 예외가 발생하므로 조건부 조건이 평가되지 않는 경우
— MrBCut

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

1

개인적으로, 나는 항상 위의 답변을 혼합하여 size() > 0제안 을 사용하는 재사용 가능한 정적 유틸리티 메소드를 만듭니다 .

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

이것은 깔끔하고 재사용 가능하며 유지 보수가 가능합니다 ... 모든 좋은 것들 ;-)


0

특정 요소가 존재하는지 여부를 찾으려면 findElement () 대신 findElements () 메소드를 사용해야합니다.

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

이것은 나를 위해 일했다. 내가 틀렸다면 나에게 제안하십시오 ..


0

이것은해야합니다 :

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

0

코드 스 니펫을 제공합니다. 따라서 아래 방법은 임의의 웹 요소 ' 새 응용 프로그램 만들기 '버튼이 페이지에 있는지 여부를 확인합니다 . 대기 시간을 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;
    }
}

0

나는 다음과 같은 것을 사용할 것이다.

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

0

Java에서 가장 간단한 방법은 다음과 같습니다.

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

0

암시 적 대기를 시도 할 수 있습니다.

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 페이지 에서 찾을 수 있습니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.