Как проверить загрузку файла с помощью Watin / IE9?

Я пытаюсь проверить загрузку файлов с помощью 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 ответа

Решение

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.

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

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

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

После In Ie9 Tools -> View Downloads -> Options укажите путь к вашей папке сохранения.

Следующий метод расширяет класс 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;

    }
}

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

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();
}
Другие вопросы по тегам