C# EventFiringWebDriver查找未实现IWrapsDriver的IWebElement
我为一个网站开发了一些测试,并希望添加日志记录。似乎EventFiringWebDriver类完成了我需要的工作。但是,我在访问通过EventFiringWebDriver实例获取的IWebElement的WrappedDriver属性时遇到问题。请在下面找到演示此问题的代码:C# EventFiringWebDriver查找未实现IWrapsDriver的IWebElement,c#,events,webdriver,extension-methods,C#,Events,Webdriver,Extension Methods,我为一个网站开发了一些测试,并希望添加日志记录。似乎EventFiringWebDriver类完成了我需要的工作。但是,我在访问通过EventFiringWebDriver实例获取的IWebElement的WrappedDriver属性时遇到问题。请在下面找到演示此问题的代码: IWebDriver webDriver = new ChromeDriver(); EventFiringWebDriver driver = new EventFiringWebDriver(webDriver);
IWebDriver webDriver = new ChromeDriver();
EventFiringWebDriver driver = new EventFiringWebDriver(webDriver);
driver.Navigate().GoToUrl("http://www.google.com/");
IWebElement element = driver.FindElement(By.Name("q"));
// ...
// throws a InvalidCastException
IWebDriver drv = ((IWrapsDriver)element).WrappedDriver;
下面是更详细的代码,演示了我为什么需要它:
class Program
{
static void Main(string[] args)
{
IWebDriver webDriver = new ChromeDriver();
EventFiringWebDriver driver = new SeleniumEventListener(webDriver);
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
driver.Navigate().GoToUrl("http://www.google.com/");
IWebElement element = driver.FindElement(By.Name("q"));
element.SendKeys("Cheese!");
element.Submit();
element.Snapshot().Save("./snapshot.png");
}
}
public class SeleniumEventListener : EventFiringWebDriver
{
public SeleniumEventListener(IWebDriver driver)
: base(driver)
{
ElementValueChanged += new EventHandler<WebElementEventArgs>((sender, e) =>
{
Console.WriteLine("Element value changed");
});
Navigated += new EventHandler<WebDriverNavigationEventArgs>((sender, e) =>
{
Console.WriteLine("Navigated to: " + e.Url);
});
}
}
public static class WebElementExtension
{
public static Bitmap Snapshot(this IWebElement element)
{
IWrapsDriver wrappedElement = element as IWrapsDriver;
if (wrappedElement == null)
{
// This exception is thrown if element is retrieved through EventFiringWebDriver instance.
throw new ArgumentException("Element must wrap a web driver", "element");
}
IWebDriver driver = wrappedElement.WrappedDriver;
Screenshot screenshot = driver.TakeScreenshot();
using (MemoryStream stream = new MemoryStream(screenshot.AsByteArray))
using (Bitmap bitmap = new Bitmap(stream))
{
Size size = new Size(
Math.Min(element.Size.Width, bitmap.Width),
Math.Min(element.Size.Height, bitmap.Height));
Rectangle crop = new Rectangle(element.Location, size);
return bitmap.Clone(crop, bitmap.PixelFormat);
}
}
}
类程序
{
静态void Main(字符串[]参数)
{
IWebDriver webDriver=新的ChromeDriver();
EventFiringWebDriver driver=新的SeleniumEventListener(webDriver);
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
driver.Navigate().gotour(“http://www.google.com/");
IWebElement元素=driver.FindElement(By.Name(“q”);
元素。SendKeys(“Cheese!”);
元素。提交();
element.Snapshot().Save(“./Snapshot.png”);
}
}
公共类SeleniumEventListener:EventFiringWebDriver
{
公共SeleniumEventListener(IWebDriver)
:基本(驱动程序)
{
ElementValueChanged+=新事件处理程序((发件人,e)=>
{
Console.WriteLine(“元素值已更改”);
});
导航+=新事件处理程序((发件人,e)=>
{
Console.WriteLine(“导航到:”+e.Url);
});
}
}
公共静态类WebElementExtension
{
公共静态位图快照(此IWebElement元素)
{
IWrapsDriver wrappedElement=作为IWrapsDriver的元素;
if(wrappedElement==null)
{
//如果通过EventFiringWebDriver实例检索元素,则会引发此异常。
抛出新ArgumentException(“元素必须包装web驱动程序”、“元素”);
}
IWebDriver driver=wrappedElement.wrappedriver;
Screenshot Screenshot=driver.TakeScreenshot();
使用(MemoryStream stream=新的MemoryStream(screenshot.AsByteArray))
使用(位图位图=新位图(流))
{
尺寸=新尺寸(
Math.Min(element.Size.Width、bitmap.Width),
Math.Min(element.Size.Height,bitmap.Height);
矩形裁剪=新矩形(element.Location,size);
返回bitmap.Clone(裁剪、位图.PixelFormat);
}
}
}
您可以看到我对IWebElement使用扩展方法,并且我需要通过IWebElement实例访问驱动程序
问题:
- 这是使用EventFiringWebDriver类的正确方法吗
- 为什么通过EventFiringWebDriver实例获取的IWebElement未实现IWrapsDriver接口
- 通过反射解决
public static IWebDriver GetDriver(this IWebElement element)
{
IWrapsDriver wrappedElement = element as IWrapsDriver;
if (wrappedElement == null)
{
FieldInfo fieldInfo = element.GetType().GetField("underlyingElement", BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfo != null)
{
wrappedElement = fieldInfo.GetValue(element) as IWrapsDriver;
if (wrappedElement == null)
throw new ArgumentException("Element must wrap a web driver", "element");
}
}
return wrappedElement.WrappedDriver;
}