2016-04-27 83 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())); 
} 

和你去那里