EventFiringWebDriver找到一个不实现IWrapsDriver的IWebElement

时间:2014-05-10 17:58:05

标签: c# events webdriver extension-methods

我为网站开发了一些测试,并希望添加日志记录。似乎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接口?

1 个答案:

答案 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;
    }