回答

23

你永遠不能確定該元素將被發現,實際上這是功能測試的目的 - 告訴你,如果你的網頁上有任何改變。但有一兩件事肯定是有幫助的,增加了對元素等待這往往造成NoSuchElementException

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

這有一定的幫助內通過try-catch塊處理NoSuchElementException異常。我們是否可以有一個通用的等待條件,以便我們不需要檢查使用哪個ExpectedConditions條件? –

+1

也可以訪問'Webdriver API'提供的'隱式'等待,但是因爲這只是設置一個任意時間段'不做任何事情',非常類似於'sleep',所以鼓勵使用'顯式等待'如上所述的可靠性和速度。 –

+0

這實際上是我從所有代碼示例中看到的最乾淨和最簡單的代碼。謝謝! – mkorman

4

你也可以用FluentWait

每個FluentWait實例定義的最長時間等待條件,以及檢查條件的頻率。

此外,用戶可以配置等待,以在等待期間忽略特定類型的例外,例如在頁面上搜索元素時的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

你可以嘗試結合「明確的等待包圍的嘗試和捕捉」與流利的等待。 – Amith

+0

嘗試{「使用明確的等待」}趕上(例外e){刷新您的網頁和使用流利的等待} – Amith

3

我完全同意彼得Mensik上方。你永遠不能說元素是否存在。 你應該清楚地理解它何時發生。從我的經驗,我應該說,它的原因如下情況發生的原因:

  • 1)頁仍然被渲染,你已經完成了你的 元搜索和獲取任何元素例外。
  • 2)第二個原因是AJAX還沒有回來,你已經 獲得NoSuchElementException
  • 3)第三個是最明顯的:元素是真的不 只要在網頁上。

因此,使用一個函數調用來處理所有這三個條件的最強大的IMHO方式是使用如Amith003建議的fluentWait

,使代碼如下所示:

讓基本元素有定位:

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

此外,如果你的目的是健壯的代碼包fluentWait()try{} catch{}塊。

而且不要忘了

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等待啓用元素的可見

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

我通常使用此行的主要功能

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

希望這有助於。

0

我們可以應用下面的代碼移除這一異常情況

  1. 通過其可見度的元件的施加WebDriverWait,對象的webdriver等待一個特定的時間(以秒計)。

     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

相關問題