问题描述
||
我在自动从网站下载文件的过程中遇到问题。该网站有一个Java按钮,单击该按钮会触发Excel文件的下载。我正在使用最新版的Watin(v2.1)。
我设法让Watin登录到网站,导航到相应的页面,更改页面上的参数,然后单击按钮开始下载。
但是,下载完成后,将显示IE9下载框,直到Watin超时为止,什么也不会发生。
非常感谢您提出的任何建议,因为我看不到下载文件或保存文件的任何方法。即使它通过\'Alt + S \'到页面,也可以保存它。我已经尝试通过WatinTestRecorder运行它,但不会提示您进行保存。
using (var browser = new IE(sLogin))
{
browser.AddDialogHandler(new OKDialogHandler());
browser.AddDialogHandler(new DialogHandlerHelper());
browser.AddDialogHandler(new ConfirmDialogHandler());
browser.AddDialogHandler(new ReturnDialogHandlerIe9());
browser.TextField(Find.ByName(\"txtUserID\")).TypeText(\"username\");
browser.TextField(Find.ByName(\"txtPassword\")).TypeText(\"password\");
browser.Button(Find.ByName(\"btnLogin\")).Click();
browser.WaitForComplete();
browser.GoTo(targetUri);
browser.SelectList(\"ctl00_phFormContent_ucoptionParam0_lst\").SelectByValue(\"4\");
browser.Button(Find.ByName(\"ctl00$phFormbuttonbar$btnRun\")).Click();
browser.WaitForComplete();
//Some code to download the file here!
}
解决方法
从1.1.0.4000版本开始应支持此功能。该版本的发行说明不再在线(http://watin.org/documentation/),但是我在Google缓存中找到了它(http://svn6.assembla.com/svn/ci-samples/dotnet /watir/website/releasenotes-1-1-0-4000.html)
应该是这样的:
using(IE ie = new IE(someUrlToGoTo))
{
FileDownloadHandler fileDownloadHandler = new FileDownloadHandler(fullFileName);
ie.AddDialogHandler(fileDownloadHandler);
ie.Link(\"startDownloadLinkId\").Click();
fileDownloadHandler.WaitUntilFileDownloadDialogIsHandled(15);
fileDownloadHandler.WaitUntilDownloadCompleted(200);
}
编辑:
在下面的评论之后,该答案被接受。因此,我假设以下代码可以工作(在我的最后一条注释中,它是指向SourceForge的链接,请注意ClickNoWait):
using(IE ie = new IE(someUrlToGoTo))
{
FileDownloadHandler fileDownloadHandler = new FileDownloadHandler(fullFileName);
ie.AddDialogHandler(fileDownloadHandler);
ie.Link(\"startDownloadLinkId\").ClickNoWait();
fileDownloadHandler.WaitUntilFileDownloadDialogIsHandled(15);
fileDownloadHandler.WaitUntilDownloadCompleted(200);
}
,接受的答案对我不起作用,因为IE 9弹出一个\“ Notification \”,您必须先导航才能进入“另存为”对话框(WatiN无法自动处理通知)。我关注了Borris Pavlov的链接,该链接很好地展示了方法。我清理了一些张贴在这里的代码,这就是结果文件:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WatiN.Core;
using WatiN.Core.Native.Windows;
using System.Threading;
using System.Windows.Automation;
namespace MyProject
{
public static class BrowserExtensionMethods
{
public static void DownloadIeFile(this IE browser,string saveAsFilename=null)
{
// see information here (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633515(v=vs.85).aspx)
Window windowMain = new Window(NativeMethods.GetWindow(browser.hWnd,5));
TreeWalker dialogElementTreeWalker = new TreeWalker(Condition.TrueCondition);
AutomationElement mainWindow = dialogElementTreeWalker.GetParent(AutomationElement.FromHandle(browser.hWnd));
Window windowDialog = new Window(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();
AutomationElementCollection dialogElements = AutomationElement.FromHandle(windowDialog.Hwnd).FindAll(TreeScope.Children,Condition.TrueCondition);
if (string.IsNullOrEmpty(saveAsFilename))
{
ClickSave(dialogElements);
}
else
{
ClickSaveAs(mainWindow,dialogElements,saveAsFilename);
}
}
private static void ClickSaveAs(AutomationElement mainWindow,AutomationElementCollection dialogElements,string filename)
{
foreach (AutomationElement element in dialogElements)
{
if (element.Current.Name.Equals(\"Save\"))
{
AutomationElementCollection dialogSubElements = element.FindAll(TreeScope.Children,Automation.ControlViewCondition);
InvokePattern clickPatternForSaveDropdown = (InvokePattern)dialogSubElements[0].GetCurrentPattern(AutomationPattern.LookupById(10000));
clickPatternForSaveDropdown.Invoke();
Thread.Sleep(3000);
AutomationElementCollection dialogElementsInMainWindow = mainWindow.FindAll(TreeScope.Children,Condition.TrueCondition);
foreach (AutomationElement currentMainWindowDialogElement in dialogElementsInMainWindow)
{
if (currentMainWindowDialogElement.Current.LocalizedControlType == \"menu\")
{
// first array element \'Save\',second array element \'Save as\',third second array element \'Save and open\'
InvokePattern clickMenu = (InvokePattern)currentMainWindowDialogElement.FindAll(TreeScope.Children,Condition.TrueCondition)[1].GetCurrentPattern(AutomationPattern.LookupById(10000));
clickMenu.Invoke();
Thread.Sleep(5000);
ControlSaveDialog(mainWindow,filename);
break;
}
}
}
}
}
private static void ClickSave(AutomationElementCollection dialogElements)
{
foreach (AutomationElement element in dialogElements)
{
// 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);
AutomationPattern[] automationPatterns = element.GetSupportedPatterns();
// replace this foreach if you need \'Save as\' with code bellow
foreach (AutomationPattern currentPattern in automationPatterns)
{
// \'10000\' button click event id
if (currentPattern.Id == 10000)
{
InvokePattern click = (InvokePattern)element.GetCurrentPattern(currentPattern);
click.Invoke();
}
}
}
}
}
private static void ControlSaveDialog(AutomationElement mainWindow,string path)
{
//obtain the save as dialog
//*** must disable throwing of the NonComVisibleBaseClass \"exception\" for this to work in debug mode:
// 1. Navigate to Debug->Exceptions...
// 2. Expand \"Managed Debugging Assistants\"
// 3. Uncheck the NonComVisibleBaseClass Thrown option.
// 4. Click [Ok]
//***copied from http://social.msdn.microsoft.com/Forums/en-US/27c3bae8-41fe-4db4-8022-e27d333f714e/noncomvisiblebaseclass-was-detected?forum=Vsexpressvb
var saveAsDialog = mainWindow.FindFirst(TreeScope.Descendants,new PropertyCondition(AutomationElement.NameProperty,\"Save As\"));
//var saveAsDialog = mainWindow.FindFirst(TreeScope.Descendants,\"[#] Save As [#]\")); //needed if using sandboxie
//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\"),ControlType.Button)));
//invoke the button
var pattern = saveButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
pattern.Invoke();
}
}
}
请参阅ControlSaveDialog方法中的注释,以获取有关如何使它作为调试版本(VS设置)工作的信息。
我实际上只测试了“另存为”操作,所以我希望其他工作也可以(似乎原始海报在事后添加了“另存为”,所以我猜他是测试了“另存为”操作更彻底地)。
要调用它,您可以使用一些代码,例如:
Link lastMp4Link = mp4Links[mp4Links.Count - 1]; //mp4Links is a WatiN.Core.LinkCollection
lastMp4Link.Click();
browser.DownloadIeFile(string.Format(@\"c:\\temp\\myFile.blah\")); //\"browser\" is a WatiN.Core.IE object
,我只是从Watin-users邮件列表中得知FileDownloadHandler被IE9破坏了。尚无修复程序,但是我卸载了IE9(回滚到IE8),并且它具有由WatiN处理的旧样式对话框。
,Watin找不到下载对话框和对话框按钮。它可以解决。
如何使用Watin / IE9测试文件下载?
看评论
,在使用WaitN进行许多修订之后,我最终使用了Selenium。它使您可以更好地控制正在处理和使用的内容,并允许您使用更现代的Web浏览器。