Как проверить загрузку файлов с помощью Watin / IE9? - PullRequest
10 голосов
/ 21 сентября 2011

Я пытаюсь проверить загрузку файлов с помощью Watin 2.1.0 против IE9.Я использовал предложенный код из принятого ответа на вопрос Загрузка файла с помощью Watin в IE9 , например:

var downloadHandler = new FileDownloadHandler(fname);
WebBrowser.Current.AddDialogHandler(downloadHandler);
link.ClickNoWait();
downloadHandler.WaitUntilFileDownloadDialogIsHandled(15);
downloadHandler.WaitUntilDownloadCompleted(200);

Однако время ожидания вызова downloadHandler.WaitUntilFileDownloadDialogIsHandled(15) истекло.Что мне делать?

Ответы [ 2 ]

21 голосов
/ 16 декабря 2011

Диалог загрузки файла не работает в IE9 (Windows7) NetFramework 4.0.

Следующий фрагмент кода может помочь вам решить проблему:

Сначала вы должны добавить ссылки UIAutomationClient и UIAutomationTypes в ваш тестовый проект.

После In Ie9 Инструменты -> Просмотр загрузок -> Параметры определяют путь к вашей папке сохранения.

Следующий метод расширяет класс Browser

public static void DownloadIEFile(this Browser browser)
{
    // see information here (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633515(v=vs.85).aspx)
    Window windowMain = new Window(WatiN.Core.Native.Windows.NativeMethods.GetWindow(browser.hWnd, 5));
   System.Windows.Automation.TreeWalker trw = new  System.Windows.Automation.TreeWalker(System.Windows.Automation.Condition.TrueCondition);
   System.Windows.Automation.AutomationElement mainWindow = trw.GetParent(System.Windows.Automation.AutomationElement.FromHandle(browser.hWnd));

    Window windowDialog = new Window(WatiN.Core.Native.Windows.NativeMethods.GetWindow(windowMain.Hwnd, 5));
    // if doesn't work try to increase sleep interval or write your own waitUntill method
    Thread.Sleep(1000);
    windowDialog.SetActivate();
    System.Windows.Automation.AutomationElementCollection amc = System.Windows.Automation.AutomationElement.FromHandle(windowDialog.Hwnd).FindAll(System.Windows.Automation.TreeScope.Children, System.Windows.Automation.Condition.TrueCondition);

    foreach (System.Windows.Automation.AutomationElement element in amc)
    {
        // You can use "Save ", "Open", ''Cancel', or "Close" to find necessary button Or write your own enum
        if (element.Current.Name.Equals("Save"))
        {
            // if doesn't work try to increase sleep interval or write your own waitUntil method
            // WaitUntilButtonExsist(element,100);
            Thread.Sleep(1000);
            System.Windows.Automation.AutomationPattern[] pats = element.GetSupportedPatterns();
            // replace this foreach if you need 'Save as' with code bellow
            foreach (System.Windows.Automation.AutomationPattern pat in pats)
            {
                // '10000' button click event id 
                if (pat.Id == 10000)
                {
                    System.Windows.Automation.InvokePattern click = (System.Windows.Automation.InvokePattern)element.GetCurrentPattern(pat);
                    click.Invoke();
                }
            }
        }
    }
}

если вы хотите нажать «Сохранить как», замените код foreach на этот

System.Windows.Automation.AutomationElementCollection bmc =  element.FindAll(System.Windows.Automation.TreeScope.Children,   System.Windows.Automation.Automation.ControlViewCondition);
System.Windows.Automation.InvokePattern click1 =  (System.Windows.Automation.InvokePattern)bmc[0].GetCurrentPattern(System.Windows.Automation.AutomationPattern.LookupById(10000));
click1.Invoke();
Thread.Sleep(10000);

System.Windows.Automation.AutomationElementCollection main =  mainWindow.FindAll(System.Windows.Automation.TreeScope.Children
,System.Windows.Automation.Condition.TrueCondition);
foreach (System.Windows.Automation.AutomationElement el in main)
{
    if (el.Current.LocalizedControlType == "menu")
    {
        // first array element 'Save', second array element 'Save as', third second array element    'Save and open'
        System.Windows.Automation.InvokePattern clickMenu = (System.Windows.Automation.InvokePattern)
                    el.FindAll(System.Windows.Automation.TreeScope.Children,        System.Windows.Automation.Condition.TrueCondition)  [1].GetCurrentPattern(System.Windows.Automation.AutomationPattern.LookupById(10000));
                       clickMenu.Invoke();
        //add ControlSaveDialog(mainWindow, filename) here if needed
        break;

    }
}

Edit: Также, если вам нужно автоматизировать диалоговое окно «Сохранить как», указав путь и нажав «Сохранить», вы можете сделать это, добавив этот код непосредственно перед разрывом;

private static void ControlSaveDialog(System.Windows.Automation.AutomationElement mainWindow, string path)
{
    //obtain the save as dialog
    var saveAsDialog = mainWindow
                        .FindFirst(TreeScope.Descendants,
                                   new PropertyCondition(AutomationElement.NameProperty, "Save As"));
    //get the file name box
    var saveAsText = saveAsDialog
            .FindFirst(TreeScope.Descendants,
                       new AndCondition(
                           new PropertyCondition(AutomationElement.NameProperty, "File name:"),
                           new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit)))
            .GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
    //fill the filename box 
    saveAsText.SetValue(path);

    Thread.Sleep(1000);
    //find the save button
    var saveButton =
            saveAsDialog.FindFirst(TreeScope.Descendants,
            new AndCondition(
                new PropertyCondition(AutomationElement.NameProperty, "Save"),
                new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button)));
    //invoke the button
    var pattern = saveButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
    pattern.Invoke();
}
8 голосов
/ 22 сентября 2011

IE9 больше не использует диалоговое окно для сохранения файлов.Вместо этого он использует панель уведомлений, чтобы предотвратить удаление фокуса с веб-сайта.См. http://msdn.microsoft.com/en-us/ie/ff959805.aspx в разделе «Диспетчер загрузки» для справки.

К сожалению, это означает, что текущий FileDownloadHandler в WatiN не будет работать.Он создает экземпляр класса «DialogWatcher» для каждого экземпляра браузера, который является основным насосом сообщений для любого типа дочернего окна.Когда встречаются дочерние окна, DialogWatcher проверяет, является ли окно определенно диалоговым окном (которым не является панель уведомлений).Если это диалог, он перебирает зарегистрированные экземпляры IDialogHandler, вызывая «CanHandleDialog».Даже если панель уведомлений была диалоговым окном, она имеет другой стиль окна (http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx),, именно так WatiN определяет тип диалога.

Из того, что я вижу, поддержки пока нетдля обнаружения панели уведомлений IE 9 и ее запросов в WatiN. Пока эта поддержка не будет добавлена, вы не сможете автоматизировать загрузку файлов в IE9.

...