3

私たちの目標は: .net winform に埋め込まれた Watin 対応のブラウザー テストです。

現在、ブラウザの動作を winform に埋め込むために .net WebBrowser コントロールを使用しています。次のようなコードを使用して、フォームの WebBroswer コントロールに WatiN をアタッチします (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 が wi​​nforms webBrowser コントロールにアタッチされている場合 (WatiN で生成された独自の IE ウィンドウを使用していない場合)、ポップアップをどのように処理できますか?
a) Watin の DialogWatcher は引き続き使用できますか? もしそうなら...どのように?
b) そうでない場合は、おそらく独自の DialogWatcher を作成できますが、追加するには hWnd または processID が必要です。Waitin が独自のウィンドウまたはプロセスを持たないこのシナリオでは、どこで正しい hWnd または processId を取得できますか?

アイデアをお寄せいただきありがとうございます...同じ目標に到達する別のアプローチを歓迎します!

4

2 に答える 2

4

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);
    }
}

元のクラスの代わりに使用すると、IEJavaScript 警告ダイアログが消えるのを確認できます。

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それ以外の場合は、のプロパティを読み取るときにクロススレッド操作を回避するために、このクラスを変更する必要がありますForm

于 2010-12-16T12:40:24.247 に答える
3

ああ、この質問は何度も出てきて、私はいつも次のようなものを書いています:しかし、少しハッキングするだけで、元のDialogWatcherクラスに基づいて独自のクラスを作成できます(from:WebBrowserコントロールでwatinを使用する方法?) 。ソースコードでそれを見つけて、それをどのように行ったかを示します。完璧ではないかもしれませんが、うまくいき、問題はありませんでした。

  1. FormDialogWatcherオリジナルをコピーしDialogWatcher、クラス名、名前空間などを変更してクラスを作成します。
  2. 元のクラスから次のフィールドとメソッドを削除しました。これはおそらく必要ありませんが、おそらくWebBrowsercontrollのインスタンスを1つだけ使用するので、このコードは実際には必要ありません。変更後にこれを削除せずに正しく機能するかどうかはわかりません。削除するには:

    • 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ます(LOL、私はちょうど理解しました、問題のニックネームがあります:))-Form_Loadまたはそのようなもの。すぐに開始され(コンストラクターを参照)、ウィンドウが存在しなくなった後、メインループが中断します。

編集:このクラス(またはWatiN設定)を未処理のダイアログを閉じるように設定すると、あなたMessageBox.Showも閉じられることに注意してください:)

編集2(重要!):上記の説明全体はDialogWatcher、WatiNSVNトランクリビジョン1056から取得した元のクラスに関連しています。このリビジョンとファイルへの直接リンク:http ://watin.svn.sourceforge.net/viewvc/watin/trunk/src/Core/DialogHandlers/DialogWatcher.cs?revision = 1056&content-type = text / plain&pathrev = 1056

于 2010-12-16T00:42:06.317 に答える