2010-12-15 4 views
3

Наша цель: тестирование браузера с поддержкой Watin, встроенное в winform .net.WatiN и .net winforms Управление WebBrowser - возможно ли DialogWatcher?

В настоящее время мы используем элемент управления .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 (и не использует его собственное окно IE сгенерированное WatiN)?
a) Можно ли использовать DialogWatcher Watin? Если так ... как?
b) Если нет, то, возможно, мы сможем написать наш собственный DialogWatcher, но для его добавления нам понадобится hWnd или processID. Где мы получим правильный hWnd или processId в этом сценарии, где Waitin не имеет собственного окна или процесса?

Заранее благодарим за любые идеи ... альтернативные подходы, которые достигают одной цели, приветствуются!

ответ

3

О людях, этот вопрос возникает так много раз, и я всегда пишу что-то вроде: Но с немного взлома вы можете создать свои собственные на основе оригинального DialogWatcher класса (от: How to use watin with WebBrowser control?), так что я выкопал в мой исходный код, чтобы найти его, и я просто покажу, как я это сделал. Возможно, это не идеально, но это работает, и у меня не было никаких проблем с этим.

  1. Создание FormDialogWatcher класса путем копирования оригинального DialogWatcher, изменив имя класса, имен и т.д.
  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) удалить этот line:

    if (!IsWindowOfIexploreProcess(window)) return; 
    

Это все! Чтобы начать его, просто создайте его: new FormDialogWatcher(Handle), где Handle - это свойство Form. Вероятно, вы можете создать его после создания объекта IE в вашем примере кода (LOL, я только что понял, что есть мое имя ник под вопросом :)) - или что-то в этом роде. Он начнется немедленно (см. Конструктор), и основной цикл будет разорван после того, как окно перестанет существовать.

EDIT: Имейте в виду, что если вы установите этот класс (или настройки WatiN), чтобы закрыть необработанное диалоговые окна, то даже ваш MessageBox.Show будет закрыт :)

EDIT 2 (важно!): Всего объяснение выше относится к оригиналу DialogWatcher класс снят с WatiN SVN trunk редакция 1056. Прямая ссылка на эту ревизию и файл: http://watin.svn.sourceforge.net/viewvc/watin/trunk/src/Core/DialogHandlers/DialogWatcher.cs?revision=1056&content-type=text/plain&pathrev=1056

+0

невероятно полезно, prostynick. Прекрасная работа. – user526186 2010-12-21 18:25:38

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

Используйте его вместо оригинального IE класса и увидеть исчезающий диалог предупреждения JavaScript Alert:

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.

+0

Отлично! Мы используем код выше с хорошим успехом, за исключением загрузки файла. Окно загрузки файла откроется, но не будет дальше (заполните имя файла и закройте), когда мы будем использовать этот код следующим образом: ie.FileUpload (Find.ByName («myInputTagName»)). Set ("c: \\ myUploadFileName.txt «). Есть предположения? – user526186 2010-12-21 21:07:44

Смежные вопросы