2015-10-14 27 views
4

我有一個Selenium Grid和WebDriver 2.48.2測試運行得太快。大部分時間測試停止,因爲在按下按鈕之前沒有選擇單選按鈕。硒測試運行速度太快,不等待單選按鈕被選中

單選按鈕使用基於JSON文件的JavaScript進行設置,以便在動態區段內創建任意數量的按鈕。一旦點擊繼續按鈕,該部分被銷燬,並且新的單選按鈕創建一個新的部分。

我嘗試了一個沒有成功的隱含等待。

driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); 

對我來說唯一的解決方法是延遲時間讓單選按鈕有足夠的時間點擊。

driver.findElement(By.id("radiobuttonid")).click(); 
Thread.sleep(delay); 

但在我看來這不是一個理想的解決方案,這是可能的延遲可能不夠長,或者它太長,浪費時間;可能有任何數量的單選按鈕,所以時間會呈指數增長。

我試過設置各種explicit waitsexpected conditions不同,但沒有成功。

我試過等待單選按鈕被創建,因爲它可能不存在(presenceOfElementLocated & elementToBeClickable)。我試過等待它被選中(elementToBeSelected)。

我很難找到預期的條件應該做什麼,因爲描述很簡短並且容易誤解。

理想情況下,我希望在單擊單選按鈕後立即繼續測試。如果可能的話,最好的辦法是什麼?

編輯

L.Bar的suggestion下面並沒有爲我工作,但它是非常有益的,以確定單選按鈕的存在,只是在不斷被點擊按鈕的單選按鈕有一個前被選中的機會。

EDIT 2

這僅僅是對耶利米正確答案擴大。我將代碼放入一個方法中,使其可重用。

private static Predicate<WebDriver> forceSelectionOfElement (final String id) 
{ 
    return new Predicate<WebDriver>() 
    { 
     @Override 
     public boolean apply(WebDriver arg0) 
     { 
      WebElement element = arg0.findElement(By.id(id));     
      boolean rval = element.isSelected(); 

      if (!rval) { 
       element.click(); 
      } 

      return rval; 
     } 
    }; 
} 

使用

WebDriverWait wait = new WebDriverWait(driver, 5); 
wait.until(forceSelectionOfElement("q___01_02_01___1___a")); 

記得導入這個命名空間,它花了我一個尷尬長的時間來弄清楚我進口錯了:)

import com.google.common.base.Predicate; 
+0

好問題。像這樣的事情可能是一個難以解決的問題。你在用什麼語言?它看起來像Java。請將相關的編程語言標記添加到問題中。單擊單選按鈕時會發生什麼變化?任何你可以檢測到的東西? – JeffC

+0

@JeffC這是Java,我添加了標籤。單擊單選按鈕時沒有任何變化。點擊繼續按鈕後,它會在單選按鈕上執行操作,看看是否應該繼續下一部分。 – Pat

+0

只是爲了使該函數更有用,你可以做forceSelectionOfElement(final By)而不是使用字符串參數(這樣你可以選擇xpath,id或者css) –

回答

2

我也曾有過類似的問題,但對我來說我的「click」事件的某處丟失。我的測試會繼續,點擊代碼會觸發,但元素的狀態永遠不會明顯改變,測試會失敗。我最終通過添加一個自定義謂詞來充分利用WebDriverWait的循環行爲,該謂詞對選定狀態更加持久。

WebDriverWait wait = new WebDriverWait(driver, 5); 
     final By lookup = By.id("radio"); 
     LOG.debug("Wait for radio to be clickable."); 
     wait.until(ExpectedConditions.elementToBeClickable(lookup)); //I assume this implies visibility. 
     LOG.debug("Element clickable. Proceeding into click behavior."); 
     wait.until(new Predicate<WebDriver>() { 
      @Override 
      public boolean apply(WebDriver arg0) { 
       LOG.debug("Resolving 'myId' Element"); 
       WebElement radio = arg0.findElement(lookup);     
       boolean rval = radio.isSelected(); 
       LOG.debug("Element Resolved and has a state of " + (rval ? "selected" : "not selected")); 
       if (!rval) { 
        LOG.debug("Clicking on the Element!"); 
        radio.click(); 
       } 
       //If we return false we will loop. So the first time through we let this click the radio for us. 
       //Second time through we should find that the element is clicked. If it's not we click it again until it represents the state we're wanting. 
       return rval;; 
      }}); 

自定義謂詞

  1. 解決的WebElement
  2. 捕捉當前選擇的狀態
  3. 如果沒有選擇
  4. 返回當前的選中狀態單擊WebElement。

所以這不應該讓測試繼續下去,直到元素的點擊狀態是我想要的狀態。到目前爲止,它基本上是我想要的。

還值得注意的是,Thread.sleep被認爲不是硒相互作用的最佳實踐。這就是ExplicitWait概念所要解釋的。我已經將我正在討論的這個最新主題鏈接到其中。

Thread.sleep works but implicit wait, webdriverwait and fluent wait does not?

好運!

+0

這對我有用。我做的唯一改變就是把它放到一個方法中。我假設這也可以與複選框一起使用。 – Pat

+0

也許吧。我一直關心的一件事是在等待循環之前檢查狀態不能切換的可能性。如果您看到該行爲,則可以使用wait.pollingEvery(長持續時間,TimeUnit單位)稍微減慢循環。我還沒有看到這種行爲,但我相信這是可能的。 – Jeremiah

3

我的方式去做:

public bool IsElementPresent(By by, IWebDriver driver) 
{ 
    try 
    { 
     driver.FindElement(by); 
     return true; 
    } 
    catch (NoSuchElementException) 
    { 
     return false; 
    } 
} 

public bool IsElementPresent(By by, IWebDriver driver, int sec) 
{ 
    bool itemExist = false; 

    itemExist = IsElementPresent(by, driver); 
    while (!itemExist && sec >= 0) 
    { 
     Thread.Sleep(1000); 
     itemExist = IsElementPresent(by, driver); 
     sec--; 
    } 

    if (sec == -1) 
     return false; 
    else 
     return true; 
} 

Callin g來測試是否存在

//Checking if element exist 10 sec 
if(IsElementPresented(By.Id("radiobuttonid"),driver,10)) 
{ 
//element exist click on it 
} 
else 
{ 
//didn't exist. 
} 
+0

好主意,但它對我不起作用。這是非常有用的,我認爲這證明單選按鈕存在,它只是在繼續按鈕被點擊之前未被選擇。我確實將Thread.sleep更改爲50ms,因爲1s會太長(我的帖子中的「延遲」是500ms)。 – Pat

+0

這段代碼都可以用WebDriverWait和'ExpectedConditions.presenceOfElementLocated(locator)'代替。 – JeffC

1

你說你探索ExpectedConditions,你試過ExpectedConditions.elementToBeSelected()?您應該能夠檢測單選按鈕是否被選中,然後向前移動。嘗試這樣的事情

WebDriverWait wait = new WebDriverWait(driver, 10); 
WebElement radio = driver.findElement(By.id("radiobuttonid")); 
radio.click(); 
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("ID of message element"))); 
// do stuff 

編輯後

更改代碼的詳細信息從OP

+0

我確實嘗試過(我在我的問題中提到過),但沒有奏效。 :(但我很高興知道我正在使用它 – Pat

+0

如果這個代碼通過,它表明單選按鈕被選中。這個代碼後出現錯誤/失敗的地方? – JeffC

+0

我沒有直觀地看到無線電按鈕被選中,如果用戶沒有選擇一個單選按鈕,就會顯示一條消息指出這個消息,我看到這條消息被顯示出來,然後測試超時了 – Pat