Selenium IWebElement到PhantomJSWebElement

时间:2014-01-14 19:37:12

标签: c# selenium xpath ghostdriver

我在我的C#项目中使用Ghost Driver(PhantomJS)。我有个问题。 Selenium有PhantomJSWebElement和PhantomJSDriver。 我正在创建PhantomJSDriver

PhantomJSDriverService service = PhantomJSDriverService.CreateDefaultService();
service.IgnoreSslErrors = true;
service.LoadImages = false;
service.Start();
PhantomJSDriver ghostDriver = new PhantomJSDriver(service);

然后尝试通过xpath

查找元素
List<string> retVal = new List<string>();
var aElements = ghostDriver.FindElementsByXPath("//div[@id='menu']//a[@href]");
foreach(PhantomJSWebElement link in aElements)
{
   try
   {
      retVal.Add(link.GetAttribute("href"));
   }
   catch (Exception)
   {
      continue;
   }
}

所以我将IWebElemet投射到PhantomJSWebElement时出错。

PhantomJSWebElement el = (PhantomJSWebElement)link; 

也不起作用(抛出铸造异常)。所以问题是,如何通过PhantomJSDriver获取PhantomJSWebElement,在查找时只返回IWebElement(或它们的集合)。

1 个答案:

答案 0 :(得分:0)

通常,在使用.NET绑定时,不应使用特定于浏览器的类。相反,您应该编写您期望的接口。这允许您根据需要替换不同的实现。您的代码看起来像这样:

PhantomJSDriverService service = PhantomJSDriverService.CreateDefaultService();
service.IgnoreSslErrors = true;
service.LoadImages = false;

// Not sure I'd use Start here. The constructor will start the service
// for you.
service.Start();

// Use the IWebDriver interface. There's no real advantage to using
// the PhantomJSDriver class.
IWebDriver ghostDriver = new PhantomJSDriver(service);

// ...

List<string> retVal = new List<string>();
var aElements = ghostDriver.FindElements(By.XPath("//div[@id='menu']//a[@href]"));

// Use the IWebElement interface here. The concrete PhantomJSWebElement
// implementation gives you no advantages over coding to the interface.
foreach(IWebElement link in aElements)
{
    try
    {
        retVal.Add(link.GetAttribute("href"));
    }
    catch (Exception)
    {
        continue;
    }
}

您还应注意,类文档很可能不正确。知道了语言绑定的源代码,PhantomJSWebElement类实际上从未在任何地方实例化。我相信你实际从FindElements()调用回来的是RemoteWebElements,所以试图将它们从继承层次结构转移到更具体的子类是注定要失败的。