2013-07-23 72 views
5

我一直在使用@FindBy一段時間了,我喜歡這個事實,該元素直到它的必要(而不是實例化)才能找到。如何返回一個懶惰實例化的動態webelement

然而,網頁可以在任何地方從某一個元素的2-10,並在元素的ID編號(所以第一個元素「元素1」等字樣的ID)

我會喜歡寫一個函數,我可以傳遞一個整數,並且它會返回一個WebElement和相應的ID,被延遲實例化。這意味着有類似下面的功能將無法正常工作:

public WebElement getElement(int numOnPage){ 
    return driver.findElement(By.id("element"+numOnPage)); 
} 

因爲我打電話的瞬間功能WebElement被定位。 (之所以不能被實例化,是因爲我有一個函數,通過反覆調用isDisplayed()來等待它的存在,並捕獲它。

我也意識到我可以創建一個List<WebElement>,它通過CSS選擇每個元素的ID以「element」開頭,但我有其他情況下我想要返回一個動態生成的元素,並且必須使用解決方法那裏也是。

謝謝!

回答

1

首先,我不明白爲什麼你絕對需要在元素真正在頁面之前得到一個WebElement引用。在正常情況下,您可以檢查頁面是否已完全加載,然後查找WebElement。首先,通常會使用循環和NoSuchElementException的捕獲方法,如您所述。

但是,如果你需要一個WebElement參考之前,不能在網頁中找到,我將只創建(僅在需要時第一時間)的實際WebElement實例,它懶洋洋地加載的代理。事情是這樣的:

public WebElement getElement(final int numOnPage) { 
     return (WebElement) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class<?>[] { WebElement.class }, new InvocationHandler() { 
      // Lazy initialized instance of WebElement 
      private WebElement webElement; 

      public Object invoke(Object proxy, Method method, Object[] args) 
        throws Throwable { 
       if (webElement == null) { 
        webElement = driver.findElement(By.id("element" + numOnPage)); 
       } 
       return method.invoke(webElement, args); 
      } 
     }); 
    } 

通過調用getElement,您檢索WebElement類型的對象。只要您調用其中一種方法,就會使用WebDriver.findElement進行檢索。請注意,如果您在代理實例上調用方法,則該元素必須位於頁面中,否則當然會得到NoSuchElementException

+0

原因是我有一個函數,我反覆調用了isDisplayed()(帶有try/catch),但是如果我傳遞從getElement()返回的元素,並且該元素不存在但是,getElement()會在它遇到等待它存在的函數之前拋出異常。謝謝! –

1

如果我正確地理解了這個問題,你不能用@FindBy註解來做這件事。問題是,在Java註解在編譯時進行處理,並作爲一個結果,你不能修改它們的飛行:

http://docs.oracle.com/javase/tutorial/java/annotations/

但它確實聽起來像你的問題可以通過使用一個明確的等待很容易解決:

public WebElement getElement(int numOnPage){ 
    WebDriverWait waiting= new WebDriverWait(driver, 15, 100); 
    return waiting.until(ExpectedConditions.visibilityOfElementLocated(By.id("element"+numOnPage))); 
} 

這將掃描等待元素存在,可見,當它返回一個WebElement到你的頁面。

相關問題