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.