C# 非常慢的WatiN.Core.Document.FileUpload集
我正在Windows 7 64位上使用WatiN 2.1.0 C和IE 9 我的问题是调用这个函数 速度非常慢。 我的意思是这个东西很好地找到了。这段代码会打开“文件”对话框,但它会在很长时间后开始键入文件名,大约3到5分钟,比WatiNs超时时间长得多。在此之后,测试的其余部分将正常工作C# 非常慢的WatiN.Core.Document.FileUpload集,c#,testing,internet-explorer-9,watin,C#,Testing,Internet Explorer 9,Watin,我正在Windows 7 64位上使用WatiN 2.1.0 C和IE 9 我的问题是调用这个函数 速度非常慢。 我的意思是这个东西很好地找到了。这段代码会打开“文件”对话框,但它会在很长时间后开始键入文件名,大约3到5分钟,比WatiNs超时时间长得多。在此之后,测试的其余部分将正常工作 有什么治疗方法吗?这种大延迟非常烦人,当有更多的文件上传测试用例时,它会显著延长测试持续时间。好的,这不是Watin解决方案,但我们遇到了完全相同的问题;我们的文件浏览器测试占用了大量的测试时间,我解决了这
有什么治疗方法吗?这种大延迟非常烦人,当有更多的文件上传测试用例时,它会显著延长测试持续时间。好的,这不是Watin解决方案,但我们遇到了完全相同的问题;我们的文件浏览器测试占用了大量的测试时间,我解决了这一问题,将Watin踢出进行文件上传,转而使用可怕的UIAutomation框架 用法示例:
public CustomFileUpload FileUpload
{
get
{
return new CustomFileUpload(WebBrowser.Current.hWnd, "_Layout");
//return Document.FileUpload(Find.ByName("file"));
}
}
您必须在测试项目中向UIAutomationClient和UIAutomationTypes添加引用。下面的解决方案不是通用的,因此您可能需要调整它以满足您的需要
public class CustomFileUpload
{
private readonly IntPtr _browserHandle;
private readonly string _tabHeader;
public CustomFileUpload(IntPtr browserHandle, string tabHeader)
{
_browserHandle = browserHandle;
_tabHeader = tabHeader;
}
public void Set(string filePath)
{
Automate(filePath);
}
private void Automate(string filePath)
{
AutomationElement browser = AutomationElement.FromHandle(_browserHandle);
AutomationElement tab = FindTab(browser, _tabHeader);
// IE10 adds the name (or value?) "Browse..." to the upload-button. Need to hack it :)
AutomationElement uploadButton = tab.FindFirst(TreeScope.Children,
new AndCondition(
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button),
new PropertyCondition(AutomationElement.NameProperty, "Browse..."))) ??
tab.FindFirst(TreeScope.Children,
new AndCondition(
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button),
new PropertyCondition(AutomationElement.NameProperty, "")));
ClickButton(uploadButton);
var openFileDialog = WaitUntilOpenFileDialogAvailable();
var valuePattern = FindFileNameTextBox(openFileDialog).GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
if (valuePattern == null)
throw new InvalidOperationException("Can't set the file path");
valuePattern.SetValue(filePath);
SetFocusToSomethingElse(browser);
var okButton = WaitUntilOkButtonLoaded(openFileDialog);
ClickButton(okButton);
}
private static AutomationElement FindTab(AutomationElement browser, string tabHeader)
{
return browser.FindFirst(TreeScope.Descendants,
new AndCondition(
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Pane),
new PropertyCondition(AutomationElement.NameProperty, tabHeader)));
}
private static void SetFocusToSomethingElse(AutomationElement elementWhichShouldNotBeSelected)
{
do
{
foreach (AutomationElement element in AutomationElement.RootElement.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.IsKeyboardFocusableProperty, true)))
{
if (element != elementWhichShouldNotBeSelected)
{
element.SetFocus();
return;
}
}
} while (true);
}
private static AutomationElement WaitUntilOkButtonLoaded(AutomationElement openFileDialog)
{
AutomationElement okButton;
do
{
okButton = openFileDialog.FindFirst(TreeScope.Children,
new AndCondition(
new PropertyCondition(AutomationElement.IsContentElementProperty, true),
new PropertyCondition(AutomationElement.IsControlElementProperty, true),
new PropertyCondition(AutomationElement.NameProperty, "Open"),
new PropertyCondition(AutomationElement.IsInvokePatternAvailableProperty, true)
));
} while (okButton == null);
return okButton;
}
private static AutomationElement WaitUntilOpenFileDialogAvailable()
{
AutomationElement openFileDialog = null;
do
{
AutomationElement openFileDialogContainer = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "Alternate Modal Top Most"));
if (openFileDialogContainer != null)
openFileDialog = openFileDialogContainer.FindFirst(TreeScope.Children, Condition.TrueCondition);
} while (openFileDialog == null);
return openFileDialog;
}
private static void ClickButton(AutomationElement button)
{
var clickPattern = button.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
if (clickPattern == null)
throw new InvalidOperationException("Can't find the buttons click pattern");
clickPattern.Invoke();
}
private static AutomationElement FindFileNameTextBox(AutomationElement openFileDialog)
{
AutomationElement findElementToTypePathInto;
do
{
findElementToTypePathInto = openFileDialog.FindFirst(TreeScope.Descendants, new AndCondition(new PropertyCondition(AutomationElement.NameProperty, "File name:"), new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit)));
} while (findElementToTypePathInto == null);
return findElementToTypePathInto;
}
}
在WatiN开始在文件上传对话框中输入文件名之前,我也经历了3到5分钟的延迟 每当IE中打开“开发人员工具”窗格时,我就会遇到这种情况。如果没有打开,则会立即开始键入
关于默认浏览器和类似弹出窗口的提示似乎也会导致延迟。我有一个稍微简单的解决方案,再次依靠自动化,但仅用于选择文件 我使用了。单击文件输入上的Nowait,这不会导致浏览器挂起 然后,我编写了一个扩展方法来设置要选择的文件:
public static void UploadFile(this Browser browser, string uploadPath)
{
var trw = new TreeWalker(Condition.TrueCondition);
var mainWindowElement = trw.GetParent(AutomationElement.FromHandle(browser.hWnd));
// Wait for the dialog to open
Thread.Sleep(1000);
// Get the select dialog
var selectDialogElement = mainWindowElement.FindFirst(TreeScope.Descendants,
new PropertyCondition(AutomationElement.NameProperty, "Choose File to Upload"));
// Get the file name box and set the path
var selectTextElement = selectDialogElement.FindFirst(
TreeScope.Descendants,
new AndCondition(new PropertyCondition(AutomationElement.NameProperty, "File name:"),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit)));
var selectValue = (ValuePattern)selectTextElement.GetCurrentPattern(ValuePattern.Pattern);
selectValue.SetValue(uploadPath);
// Get the open button and click it
var openButtonElement = selectDialogElement.FindFirst(TreeScope.Descendants,
new AndCondition(new PropertyCondition(AutomationElement.NameProperty, "Open"),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button)));
var openButtonClick = (InvokePattern)openButtonElement.GetCurrentPattern(InvokePattern.Pattern);
openButtonClick.Invoke();
}
用法示例:
var browser = (IE)Document.DomContainer;
Document.FileUpload(Find.BySelector("#FileUpload")).ClickNoWait();
browser.UploadFile("c:\\myfile.txt");
Document.Button(Find.BySelector("#submit")).Click();
UIAutomation将从call UploadFilePath接管,并将找到对话框窗口,然后像用户那样填写表单。我也有同样的问题。到目前为止,我还没有找到解决方案,也许你会更幸运。看起来很有希望,但我被转移到了其他项目,现在无法验证此解决方案,所以我会接受你的命运,因为你也有同样的问题。
var browser = (IE)Document.DomContainer;
Document.FileUpload(Find.BySelector("#FileUpload")).ClickNoWait();
browser.UploadFile("c:\\myfile.txt");
Document.Button(Find.BySelector("#submit")).Click();