【问题标题】:WatiN and .net winforms WebBrowser control - is DialogWatcher possible?WatiN 和 .net winforms WebBrowser 控件 - DialogWatcher 可能吗?
【发布时间】:2011-05-26 05:33:24
【问题描述】:

我们的目标是:在 .net winform 中嵌入支持 Watin 的浏览器测试。

目前,我们正在使用 .net WebBrowser 控件将浏览器行为嵌入到 winform 中。 我们使用如下代码将 WatiN 附加到表单上的 WebBroswer 控件(感谢 prostynick):

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 控件(而不是使用它自己的WatiN 生成的IE 窗口)时,如何处理弹出窗口?
a) 可以继续使用 Watin 的 DialogWatcher 吗?如果是……怎么办?
b) 如果没有,那么也许我们可以编写自己的 DialogWatcher——但我们需要一个 hWnd 或 processID 来添加它。在 Waitin 没有自己的窗口或进程的情况下,我们将在哪里获得正确的 hWnd 或 processId?

在此先感谢您提供任何想法...欢迎使用其他方法达到相同目标!

【问题讨论】:

    标签: webbrowser-control watin browser-automation


    【解决方案1】:

    我刚刚升级到最新版本的 WatiN(头部修订版 - 1166 - 在后备箱中: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 ”)。有什么想法吗?
    • 由于您在方法中使用局部变量ie(我猜)并且您将此变量传递给线程,这意味着当线程退出。你不能强迫它被丢弃
    【解决方案2】:

    哦,伙计,这个问题出现了很多次,我总是写这样的东西:但是通过一点黑客攻击,您可以根据原始 DialogWatcher 类创建自己的(来自:How to use watin with WebBrowser control? ),所以我挖掘了我的源代码来找到它,我将展示我是如何做到的。也许它并不完美,但它可以工作而且我没有任何问题。

    1. 通过复制原始DialogWatcher、更改类名称、命名空间等来创建FormDialogWatcher 类。
    2. 我已从原始类中删除了以下字段和方法。这可能不需要,但您可能只会使用WebBrowser controll 的一个实例,因此您并不真正需要此代码,我不确定在不删除它的情况下更改后它是否能正常工作。删除:

      • 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. Start() 方法中替换这个:

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

      用这个:

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

      (唯一真正的区别在于GetWindows 调用内部)

    4. HandleWindow(Window window) 中删除这一行:

      if (!IsWindowOfIexploreProcess(window)) return;
      

    就是这样!要启动它,只需创建它:new FormDialogWatcher(Handle) 其中Handle 只是Form 的一个属性。您可以在示例代码中创建IE 对象后创建它(哈哈,我刚刚发现,我的昵称有问题:))-Form_Load 或类似的东西。它将立即启动(参见构造函数),并且在窗口不存在后主循环将中断。

    编辑:请注意,如果您将此类(或 WatiN 设置)设置为关闭未处理的对话框,那么即使您的 MessageBox.Show 也会被关闭 :)

    编辑 2(重要!):上面的全部解释与取自 WatiN SVN 主干修订版 1056 的原始 DialogWatcher 类有关。此修订和文件的直接链接:http://watin.svn.sourceforge.net/viewvc/watin/trunk/src/Core/DialogHandlers/DialogWatcher.cs?revision=1056&content-type=text/plain&pathrev=1056

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-05
      • 2023-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      相关资源
      最近更新 更多