2016-04-27 36 views
0

可以說我有試圖IWebElement轉換成通過元素

[FindsBy(How = How.Id, Using = "buttonSignIn")] public IWebElement BtnSignin { get; set; }

我試圖傳遞到這個方法將IWebElement轉換成By元素的頁面對象。

public void MoveAndClick(IWebElement element) 
{ 
    var findElement = driver.FindElement((By)element); 

    Actions act = new Actions(driver); 
    act.MoveToElement(findElement); 
    act.Click(findElement); 
    act.Perform(); 
} 

我知道,這段代碼將工作沒有元素鑄造成By元素,但是對於我的測試工作,我需要弄清楚如何將IWebElement轉換成By元素。

當我運行這個,我得到一個空的異常錯誤。有沒有人有這個簡單的解決方案?

+1

http://stackoverflow.com/a/31677984/2246511 – jibbs

回答

1

簡短回答,這是不可能的。 Selenium的開發人員已經決定沒有有用的用例。

0

可以使用get元素的獨特屬性:

IWebElement element = driver.FindElements(/* Example */By.Id("ID")); 
String id = item.GetAttribute("id"); 
By elemBy = By.Id(id); 
+0

如果沒有任何ID屬性會怎麼樣? –

1

硒並沒有提供我們一個IWebElement的選擇,但可以創建一個選擇使用javascript:

public static By ConvertToBy(this IWebElement element) 
{ 
    if (element == null) throw new NullReferenceException(); 

    var attributes = 
     ((IJavaScriptExecutor) SeleniumWebDriver.Driver).ExecuteScript(
      "var items = {}; for (index = 0; index < arguments[0].attributes.length; ++index) { items[arguments[0].attributes[index].name] = arguments[0].attributes[index].value }; return items;", 
      element) as Dictionary<string, object>; 
    if (attributes == null) throw new NullReferenceException(); 

    var selector = "//" + element.TagName; 
    selector = attributes.Aggregate(selector, (current, attribute) => 
     current + "[@" + attribute.Key + "='" + attribute.Value + "']"); 

    return By.XPath(selector); 
} 

它將創建一個帶有標記名稱和所有attr名稱和值的XPath,如下所示:"//a[@class='test test-test'][@id='test-id'][@custom='custom-value']"

要小心:因爲沒有正確的方法來轉換將IWebElement組成一個By,如果頁面中有另一個具有相同標籤名稱和attrs名稱和值的元素,擴展可以返回重複結果

1

我不會推薦它,但你可以做到這一點使用反射 - 使用IWebElement「元素」參考

裏面你的方法,:

//Get the RealProxy of the element 
var elementProxy = System.Runtime.Remoting.RemotingServices.GetRealProxy(element); 

//Get the Bys from the RealProxy:  
var bysFromElement = (IReadOnlyList<object>)elementProxy 
    .GetType() 
    .GetProperty("Bys", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public)? 
    .GetValue(elementProxy); 

//Convert bysFromElement to a list of strings for manipulation, or convert into a list of By objects, i.e.:  
var bys = new List<string>(); 
if (bysFromElement != null) 
{ 
    bys.AddRange(bys.Select(@by => @by.ToString())); 
} 

和你去那裏