我们的目标是:嵌入在.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?
提前感谢任何想法...欢迎达到相同目标的替代方法!
答案 0 :(得分:4)
我刚刚升级到最新版本的WatiN(头版本 - 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
实例。否则,在阅读Handle
的{{1}}属性时,您必须修改此类以避免跨线程操作。
答案 1 :(得分:3)
哦,伙计,这个问题出现了这么多次,我总是写一些类似的东西:但是通过一些黑客攻击你可以根据原始的DialogWatcher类创建自己的(来自:{{3因此,我在我的源代码中挖出来找到它,我将展示我是如何做到的。也许它并不完美,但它有效,我没有遇到任何问题。
FormDialogWatcher
,更改类名,命名空间等来创建DialogWatcher
类。我从原始类中删除了以下字段和方法。这可能不需要,但你可能只使用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)
在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
来电)
在HandleWindow(Window window)
中删除此行:
if (!IsWindowOfIexploreProcess(window)) return;
这就是全部!要启动它,只需创建它:new FormDialogWatcher(Handle)
其中Handle
只是Form
的属性。您可以在示例代码中创建IE
对象之后创建它(LOL,我刚刚想通了,我的昵称有问题:)) - Form_Load
或类似的东西。它将立即启动(参见构造函数),并且在窗口停止存在后主循环将中断。
编辑:请注意,如果您设置此类(或WatiN设置)以关闭未处理的对话框,那么即使您的MessageBox.Show
也将关闭:)
编辑2(重要!):上面的整个解释与从WatiN SVN主干修订版1056 中取得的原始DialogWatcher
类有关。直接链接到此修订版和文件:How to use watin with WebBrowser control?