【问题标题】:How to test file download with Watin / IE9?如何使用 Watin / IE9 测试文件下载?
【发布时间】:2011-11-21 22:55:37
【问题描述】:

我正在尝试使用 Watin 2.1.0 针对 IE9 测试文件下载。我使用问题Downloading a file with Watin in IE9接受的答案中的建议代码,如下所示:

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

但是,downloadHandler.WaitUntilFileDownloadDialogIsHandled(15) 调用超时。我该怎么办?

【问题讨论】:

  • 尝试等待更长时间?对于大文件,“文件下载”对话框可能需要一段时间才会出现。 15 秒看起来不够长
  • @Jeremy McGee 该文件非常小,我已验证确实出现了下载对话框。我什至手动取消了它,WaitUntilFileDownloadDialogIsHandled 仍然超时。
  • 尝试使用 DialogHandlerHelper 来识别 WATIN 认为的 IE9 下载对话框窗口实际上是什么,因为在我看来 IE9 的下载对话框不符合 WATIN 用来查找它的标准。
  • @HollyStyles 我尝试使用 DialogHandlerHelper 来查找任何候选对话处理程序,谢谢。但是没有找到:(
  • 呃 - 我希望有人能找到解决方案,我真的希望能够自动化这些下载测试:(

标签: c# internet-explorer-9 watin


【解决方案1】:

文件下载对话框在 IE9 (Windows7) NetFramework 4.0 中不起作用。

以下代码 sn-p 可能会帮助您解决问题:

首先,您必须将引用 UIAutomationClient 和 UIAutomationTypes 添加到您的测试项目中。

在 Ie9 工具 -> 查看下载 -> 选项定义保存文件夹的路径之后。

下一个方法扩展了浏览器类

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

【讨论】:

  • 这真的很酷,但是另存为对话框可以自动保存为特定的文件名吗?我已经尝试修改代码,但是当我尝试查找“另存为”对话框时遇到了问题。
  • 解决了自动另存为路径并单击保存,因此将代码添加到您的答案中。希望没问题。
  • 您能否使用另存为发布完整解决方案的 github 要点?我很难让它在 IE10 中工作。
【解决方案2】:

IE9 不再使用对话窗口来保存文件。相反,它使用通知栏来防止焦点从网站上移开。请参阅“下载管理器”下的http://msdn.microsoft.com/en-us/ie/ff959805.aspx 以供参考。

不幸的是,这意味着 WatiN 中当前的 FileDownloadHandler 将无法工作。它为每个浏览器实例实例化一个“DialogWatcher”类,该类是任何类型的子窗口的基本消息泵。当遇到子窗口时,DialogWatcher 会检查该窗口是否专门是一个对话框(通知栏不是)。如果它是一个对话框,它会遍历已注册的 IDialogHandler 实例,调用“CanHandleDialog”。即使通知栏是一个对话框,它也是不同的窗口样式(http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx),这就是 WatiN 检测对话框类型的方式。

据我所知,目前尚不支持检测 IE 9 通知栏及其在 WatiN 中的提示。在添加该支持之前,您将无法在 IE9 中自动下载文件。

【讨论】:

  • 啊,你可能是对的,虽然我无法确认。
  • 只使用 watin 2.1 是不可能的,但是使用下面关于 UIAutomation* 的方法,可以执行所有的黄白条命令,包括打开和另存为。
猜你喜欢
  • 1970-01-01
  • 2011-09-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-24
  • 1970-01-01
  • 2011-05-08
  • 2020-09-14
  • 1970-01-01
相关资源
最近更新 更多