WatiN和.NET WinForms WebBrowser控件 - DialogWatcher是否可行?

3
我们的目标是:在 .net winform 中嵌入 Watin 浏览器测试。
目前,我们使用 .net WebBrowser 控件将浏览器行为嵌入到 winform 中。 我们使用类似以下代码(感谢 prostynick)将 WatiN 附加到表单上的 WebBroswer 控件:
var thread = new Thread(() =>
{
    Settings.AutoStartDialogWatcher = false;
    var ie = new IE(webBrowser1.ActiveXInstance);
    ie.GoTo("http://www.google.com");
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();

问题在于 - “winform浏览器”需要在测试/自动化期间处理弹出窗口。
问题:当Watin连接到winforms webBrowser控件时(而不是使用其自己生成的IE窗口),如何处理弹出窗口? a)Watin的DialogWatcher仍然可以使用吗?如果可以…怎么做? b)如果不能,则我们可以编写自己的DialogWatcher - 但我们需要一个hWnd或processID来添加它。在这种情况下,我们从哪里获取正确的hWnd或processId,因为Waitin没有自己的窗口或进程?
感谢您提前提供任何想法…欢迎采用达到相同目标的替代方法!
2个回答

4
我刚刚升级到最新版本的WatiN(head revision - 1166 - 在trunk中:https://watin.svn.sourceforge.net/svnroot/watin/trunk/src/)。由于原始DialogWatcher类发生了变化,现在可以使用现有的DialogWatcher来减少代码量。
创建一个类:
public class WebBrowserIE : IE
{
    private IntPtr hwnd;

    public WebBrowserIE(WebBrowser webBrowserControl)
        : base(webBrowserControl.ActiveXInstance, false)
    {
        hwnd = webBrowserControl.FindForm().Handle;
        StartDialogWatcher();
    }

    public override IntPtr hWnd
    {
        get
        {
            return hwnd;
        }
    }

    protected override void Dispose(bool disposing)
    {
        hwnd = IntPtr.Zero;
        base.Dispose(disposing);
    }
}

请使用它来替代原始的IE类,并查看JavaScript警告对话框的消失:

var ie = new WebBrowserIE(webBrowser1);
var thread = new Thread(() =>
{
    ie.GoTo("http://www.plus2net.com/javascript_tutorial/window-alert.php");
    ie.Button(Find.ByValue("Click here to display alert message")).Click();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();

警告: 在线程外创建 WebBrowserIE 实例。否则,当读取 FormHandle 属性时,您将不得不修改此类以避免跨线程操作。


太好了!我们使用上述代码非常成功,除了文件上传之外。当我们像这样使用此代码时:ie.FileUpload(Find.ByName(“myInputTagName”))。Set(“c:\ myUploadFileName.txt”),文件上传窗口将打开但不会进一步执行(填写文件名并关闭)。有什么想法吗? - user526186
由于您在方法内部使用了本地变量ie,并将此变量传递给线程,这意味着当线程退出时,GC会被通知处理ie。您无法强制它被处理。 - Odys

3

这个问题已经被问了很多次,我总是写一些像这样的东西:但只要稍微hack一下,你就可以创建自己的类,基于原始的DialogWatcher类(来自:如何在WebBrowser控件中使用WatiN?),所以我挖掘了我的源代码找到了它,我将展示我是如何做的。也许它不完美,但它可以工作,我没有遇到任何问题。

  1. Create FormDialogWatcher class by copying original DialogWatcher, changing class name, namespace etc.
  2. I have deleted following fields and methods from original class. This is probably not needed, but you will probably use only one instance of WebBrowser controll, so you don't really need this code and I am not sure if it will work properly after the changes without deleting this. To delete:

    • private static IList<DialogWatcher> dialogWatchers
    • public static DialogWatcher GetDialogWatcher(IntPtr mainWindowHwnd)
    • public static DialogWatcher GetDialogWatcherFromCache(IntPtr mainWindowHwnd)
    • public static void CleanupDialogWatcherCache()
    • public void IncreaseReferenceCount()
    • public void DecreaseReferenceCount()
    • public int ReferenceCount { get; private set; }
    • private bool IsWindowOfIexploreProcess(Window window)
  3. In Start() method replace this:

    if (new Window(MainWindowHwnd).Exists())
    {
        var winEnumerator = new WindowsEnumerator();
        var windows = winEnumerator.GetWindows(win => true);
    

    with this:

    var mainWindow = new Window(MainWindowHwnd);
    if (mainWindow.Exists())
    {
        var winEnumerator = new WindowsEnumerator();
        var windows = winEnumerator.GetWindows(window => window.ProcessID == mainWindow.ProcessID);
    

    (the only real difference is inside GetWindows call)

  4. In HandleWindow(Window window) remove this line:

    if (!IsWindowOfIexploreProcess(window)) return;
    
那就这样了!要启动它,只需创建:new FormDialogWatcher(Handle),其中HandleForm的属性。在您的示例代码中创建IE对象后(哈哈,我刚刚发现问题中有我的昵称:)) - Form_Load或类似的位置即可创建它。它将立即启动(请参见构造函数),并且在窗口消失后主循环将会停止。 编辑:请注意,如果您将此类(或WatiN设置)设置为关闭未处理的对话框,则甚至您的MessageBox.Show也将被关闭:) 编辑2(重要!):上述整个说明与从WatiN SVN trunk的原始DialogWatcher类相关,版本号为1056。直接链接到此版本和文件:http://watin.svn.sourceforge.net/viewvc/watin/trunk/src/Core/DialogHandlers/DialogWatcher.cs?revision=1056&content-type=text/plain&pathrev=1056

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接