13

Java를 사용하여 Selenium WebDriver에서 테스트 케이스를 거의 작성하지 않고 그리드 (허브 및 다중 노드)에서 실행합니다. 몇 가지 테스트 케이스가 NoSuchElementException으로 인해 실패한 것으로 나타났습니다. NoSuchElementException을 피하고 그 요소가 항상 발견되는 가장 확실한 방법은 무엇입니까?Selenium에서 NoSuchElementException을 피하는 가장 좋은 방법은 무엇입니까?

답변

23

페이지에서 변경된 사항을 알려주는 요소가 실제로는 기능 테스트의 목적임을 알 수 없습니다. 그러나 확실히 도움이 한 가지

FluentWait 인스턴스 조건을 기다리는 최대 시간을 정의 종종

WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds); 
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>)); 
+0

내에서 시도-catch 블록을 통해 예외 : NoSuchElementException를 처리 할 수 ​​있습니다. 사용할 ExpectedConditions 조건을 확인할 필요가 없도록 일반 대기 조건을 사용할 수 있습니까? –

+1

'Webdriver API '에 의해 제공되는'암시 적'대기에 대한 접근도 가능하지만'do nothing'이라는 임의의 기간을 설정하기 때문에'sleep'와 매우 유사합니다.'explicit wait'를 사용하는 것이 좋습니다. 신뢰성 및 속도면에서 위와 같습니다. –

+0

이것은 실제로 모든 코드 샘플에서 본 가장 깨끗하고 간단한 코드입니다. 감사! – mkorman

4

당신은 또한 FluentWait을 사용할 수 있습니다처럼 NoSuchElementException를 일으키는 요소에 대한 대기를 추가하는 것입니다 뿐만 아니라 상태를 점검 할 빈도를 표시합니다.

또한 사용자는 페이지에서 요소를 검색 할 때 NoSuchElementExceptions과 같이 대기 중에 특정 유형의 예외를 무시하도록 대기 시간을 구성 할 수 있습니다.

// Waiting 30 seconds for an element to be present on the page, checking 
    // for its presence once every 5 seconds. 
    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver) 
     .withTimeout(30, SECONDS) 
     .pollingEvery(5, SECONDS) 
     .ignoring(NoSuchElementException.class); 

    WebElement foo = wait.until(new Function<WebDriver, WebElement>() { 
    public WebElement apply(WebDriver driver) { 
     return driver.findElement(By.id("foo")); 
    } 
    }); 

Click here for more info

+0

이것은 확실히 도움이됩니다. 그러나 일반적인 적용 방법을 사용할 수 있습니까? 예를 들어, 페이지가 완전히로드 될 때까지 기다린 다음 요소를 찾고, 요소가 발견되지 않으면 페이지를 새로 고치고 이것이 fluentwait의 시간 초과까지 계속됩니다. –

+0

유창한 대기와 함께 "try and catch로 둘러싸인 명시 적 대기"조합을 시도 할 수 있습니다. – Amith

+0

try { "use explicit wait"} catch (예외 e) {페이지를 새로 고침하고 유창한 대기 시간} – Amith

3

나는 완전히 위의 페트르 Mensik에 동의합니다. 당신이 요소가 있는지 여부를 말할 수없는 문제. 왜 발생했는지 분명히 이해해야합니다.

  • 1) 페이지가 여전히 렌더링되는 당신은 이미 요소 검색을 완료했고 어떤 요소 예외를 얻을 수 없습니다 : 내 경험에서 나는 다음과 같은 이유로 인해 발생 있다고한다.
  • 2) 두 번째 이유는 세 번째는 가장 명백하다) AJAX 아직 반환하지 않은 당신은했습니다 이미 NoSuchElementException
  • 3을 얻을 수 있습니다 : 요소가 페이지 마다에 정말 없습니다.

그래서 하나의 함수 호출을 사용하여이 세 가지 조건을 모두 처리하는 가장 강력한 IMHO 방법은 Amith003이 제안한대로 fluentWait을 사용하는 것입니다.

통해 UR 요소는 로케이터를 가지고하자 :

그래서 코드는 다음이 될

String elLocXpath= "..blablabla"; 
WebElement myButton= fluentWait(By.xpath(elLocXpath)); 
myButton.click(); 

public WebElement fluentWait(final By locator){ 
     Wait<WebDriver> wait = new FluentWait<WebDriver>(driver) 
       .withTimeout(30, TimeUnit.SECONDS) 

       .pollingEvery(5, TimeUnit.SECONDS) 

     .ignoring(org.openqa.selenium.NoSuchElementException.class); 
     WebElement foo = wait.until(
       new Function<WebDriver, WebElement>() { 
        public WebElement apply(WebDriver driver) { 
         return driver.findElement(locator); 
        } 
       } 
     ); 
     return foo; 
    }; 

또한 당신의 목적은 try{} catch{} 블록과 강력한 코드 랩 fluentWait() 경우.

또한 유용에 대한

public boolean isElementPresent(By selector) 
    { 

       return driver.findElements(selector).size()>0; 
} 

입니다 잊지 마세요.

따라서 모든 언급을 결론 지으면 NoElement 예외는 페이지의 요소 존재를 보장 할 수 없으므로 예외를 올바르게 처리하지 않아야합니다.

지금 당신에게 더 분명합니다.감사합니다

1
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds); 
wait.until(ExpectedConditions.elementToBeClickable(By.id<locator>)); 

elementToBeClickable 에 대한 대기 나는 보통의 주요 기능이 도움이

public static void main(String[] args) throws ParseException { 
    driver= new ChromeDriver(); 
    driver.manage().window().maximize(); 
    **driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);** 

희망이 줄을 사용 요소의보이는

1
public WebElement fluientWaitforElement(WebElement element, int timoutSec, int pollingSec) { 

    FluentWait<WebDriver> fWait = new FluentWait<WebDriver>(driver).withTimeout(timoutSec, TimeUnit.SECONDS) 
    .pollingEvery(pollingSec, TimeUnit.SECONDS) 
    .ignoring(NoSuchElementException.class, TimeoutException.class); 

    for (int i = 0; i < 2; i++) { 
     try { 
      //fWait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//*[@id='reportmanager-wrapper']/div[1]/div[2]/ul/li/span[3]/i[@data-original--title='We are processing through trillions of data events, this insight may take more than 15 minutes to complete.']"))); 
      fWait.until(ExpectedConditions.visibilityOf(element)); 
      fWait.until(ExpectedConditions.elementToBeClickable(element)); 
     } 
     catch (Exception e) { 

      System.out.println("Element Not found trying again - " + element.toString().substring(70)); 
      e.printStackTrace(); 
     } 
    } 

    return element; 
} 
0

을 사용합니다. 우리는 코드 아래 적용 할

0

는 가시성 요소의 (초) WebDriverWait 특정 시간 webdriver 객체 대기를 적용함으로써이 예외 상황

  1. 을 제거한다.

     WebDriverWait wait = new WebDriverWait(driver, 10);  
         wait.until(ExpectedConditions.visibilityOf(link)); 
    
  2. 우리는 일반적인 방법이 확실히 도움이된다

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

http://selenium-code.blogspot.in/2017/08/selenium-exception-nosuchelementexcepti.html

관련 문제