我正在尝试使用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)
来电超时。我该怎么办?
答案 0 :(得分:21)
文件下载对话框在IE9(Windows7)NetFramework 4.0中不起作用。
以下代码段可能有助于您解决问题:
首先,您必须将参考UIAutomationClient和UIAutomationTypes添加到测试项目中。
在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;
}
}
编辑: 此外,如果您需要自动化另存为对话框指定路径并单击保存,您可以通过在中断之前添加此代码来实现;
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();
}
答案 1 :(得分:8)
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检测对话类型的方式。
从我所看到的,目前还没有支持在WatiN中检测IE 9通知栏及其提示。在添加该支持之前,您将无法在IE9中自动下载文件。