2014-12-09 51 views
2

希望有人能在這個問題上幫助...硒C# - OpenQA.Selenium.StaleElementReferenceException:陳舊的元素參考:元素沒有連接到網頁文件

我不斷收到上述錯誤消息(見標題)時與級聯下拉菜單進行交互。 我已經成功地採用的只有基本的解決方法是「Thread.sleep代碼」看看下面的代碼提取物:

注我傳遞下列參數:

屬性:ID

attrval:例如ID123456(下拉的ID)

參數:汽車(下拉值,我們想選擇)

IWebElement element = findMyElement(attribute, attrval); 
SelectElement selectElement = new SelectElement(element); 
selectElement.SelectByText(parameter); 
// dirty code - needs to be re-written 
Thread.Sleep(500); 
if (new SelectElement(findMyElement(attribute, attrval)).SelectedOption.Text.Equals(parameter)) 
{ 
    return "pass"; 
} 

注2:findMyElement是一個自定義的方法(這裏是摘錄):

public static IWebElement findMyElement(string attribute, string attrval) 
     { 
      WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30)); 
      switch (attribute.ToLower()) 
      { 
       case "id": 
        wait.Until(ExpectedConditions.ElementExists(By.Id(attrval))); 
        wait.Until(ExpectedConditions.ElementIsVisible(By.Id(attrval))); 
        return driver.FindElement(By.Id(attrval)); 

正如我在我的代碼已經指出的意見是有反正我能避免使用的Thread.Sleep我所知,這是不是一個推薦的方法。

感謝提前:)

+0

什麼行引發異常?選擇下拉菜單時,您的應用程序中會發生什麼?頁面是否改變了?任何新元素添加?任何新請求已發送? – Arran 2014-12-09 12:09:15

+0

此處引發異常(不帶thread.sleep)if(new SelectElement(findMyElement(attribute,attrval))。SelectedOption.Text.Equals(parameter)) – David 2014-12-09 12:14:41

+0

關於頁面本身,因爲它是一個級聯下拉列表中的可選選項下拉菜單會更新,例如如果我在第一個下拉列表中選擇汽車,第二個將詢問顏色。在後臺注意,當第一個下拉列表中的值已被選中時,頁面會回發 – David 2014-12-09 12:34:17

回答

1

它看起來好像第一個下拉元素被從DOM卸載回傳,並開始重新加載到DOM一次回傳完成時。

當您的代碼在回發期間嘗試觸摸此元素時,會引發StaleElementReferenceException。調用的工作方式是,通過觸摸此元素來停止代碼一段時間,這段時間恰巧足以讓回發完成。

理想的解決方案是確定回發何時完成。

什麼謂詞只會在回發完成後才返回true?用等待該謂詞返回true替換Sleep()

例如如果第二個下拉只在回傳出現,則更換Thread.Sleep(500);有:

Func<IWebDriver, bool> predicate = (x) => 
{ 
    try 
    { 
     IWebElement elementThatOnlyAppearsOnPostback = findMyElement(attribute, attrval); 
     return true; 
    } 
    catch (NoSuchElementException) 
    { 
     return false; 
    } 
}; 
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30)); // or whatever timeout you want to set 
wait.Until(predicate); 

如果第二個下拉已經存在,但只有變得與上回發的選項填充,謂切換到:

Func<IWebDriver, bool> predicate = (x) => 
{ 
    SelectElement secondDropDown = new SelectElement(findMyElement(attribute, attrval)); 
    return (secondDropDown.Options.Count > 0); 
} 
相關問題