如何使用Watin / IE9测试文件下载?

发布于 2024-12-06 01:21:44 字数 526 浏览 0 评论 0 原文

我正在尝试使用 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) 调用超时。我应该怎么办?

I'm trying to test file download with Watin 2.1.0 against IE9. I used the suggested code from the accepted answer to the question Downloading a file with Watin in IE9, like this:

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

However, the downloadHandler.WaitUntilFileDownloadDialogIsHandled(15) call times out. What should I do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

世界如花海般美丽 2024-12-13 01:21:44

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

以下代码片段可能会帮助您解决该问题:

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

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

替换 foreach 代码,下一个方法将扩展 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();
                }
            }
        }
    }
}

如果您想单击“另存为”,用此

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

File download dialog doesn't work in IE9 (Windows7) NetFramework 4.0.

Following code snippet might help you resolve the issue:

First you must add references UIAutomationClient and UIAutomationTypes to your test project.

After In Ie9 Tools -> View Downloads -> Options define path to your save folder.

The next method extends Browser class

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

if you want click 'Save As' replace foreach code with this

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:
Also if you need to automate the save as dialog specifying a path and clicking save you can do it by adding this code just before 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();
}
知足的幸福 2024-12-13 01:21:44

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

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

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

IE9 no longer uses a dialog window for saving files. Instead, it uses the notification bar to prevent focus from being removed from the web site. See http://msdn.microsoft.com/en-us/ie/ff959805.aspx under "Download Manager" for reference.

Unfortunately, this means that the current FileDownloadHandler in WatiN will not work. It instantiates a "DialogWatcher" class per browser instance that is a basic message pump for any kind of child window. When child windows are encountered, the DialogWatcher checks to see if the window is specifically a dialog (which the notification bar is not). If it is a dialog, it then iterates over the registered IDialogHandler instances calling "CanHandleDialog." Even if the notification bar were a dialog, it is of a different Window Style (http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx), which is how WatiN detects the type of dialog.

From what I can see, there is no support yet for detecting the IE 9 notification bar and its prompts in WatiN. Until that support is added, you will not be able to automate downloading files in IE9.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文