我为网站开发了一些测试,并希望添加日志记录。似乎EventFiringWebDriver类完成了我需要的工作。但是,我在访问通过EventFiringWebDriver实例获取的IWebElement的WrappedDriver属性时遇到了麻烦。请找到演示以下问题的代码:
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);
}
}
}
你可以看到我使用IWebElement的扩展方法,我需要通过IWebElement实例访问驱动程序。
问题:
这是使用EventFiringWebDriver类的正确方法吗?
为什么通过EventFiringWebDriver实例获取的IWebElement没有实现IWrapsDriver接口?
答案 0 :(得分:1)
解决了反思
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;
}