如何扩展 CodedUI HtmlControls 并保留输入
How to extend CodedUI HtmlControls and preserve typing
我最近一直在深入研究 CodedUI,并且很高兴扩展库以包含其余 HTML 元素(无论出于何种原因)被排除在 Microsoft.VisualStudio.TestTools.UITesting.HtmlControls 之外命名空间。
我注意到我可以做如下事情:
var divs = new HtmlDiv(window).FindMatchingControls().OfType<HtmlDiv>();
这将 return 您所期望的:具有与 FindMatchingControls() 调用相同元素的 IEnumerable(只是键入 HtmlDiv 而不是 UITestControl)。
此外,我可以这样做:
public class HtmlHeader : HtmlCustom
{
public static readonly string HeaderTag = "header";
public HtmlHeader() : base() {
this.SearchProperties.Add(HtmlControl.PropertyNames.TagName, HeaderTag, PropertyExpressionOperator.EqualTo);
}
public HtmlHeader(UITestControl parent) : base(parent) {
this.SearchProperties.Add(HtmlControl.PropertyNames.TagName, HeaderTag, PropertyExpressionOperator.EqualTo);
}
}
甚至这个也有效:
var headerTag = new HeaderTag(window);
它将在屏幕上找到 header 个标签,并为您找到第一个标签。
var headerTags = new HeaderTag(window).FindMatchingControls();
工作正常,但是
var headerTags = new HeaderTag(window).FindMatchingControls().OfType<HeaderTag>();
为空。
为什么上述命名空间中的 HtmlControls 可以正确解析类型?
我能否利用隐式转换运算符/其他技巧将 OfType() 转换为 return 一个 collection HtmlTags?
我开始写这样的转换:
protected HeaderTag ConvertControl(HtmlControl toConvert)
{
if (StringComparer.OrdinalIgnoreCase(toConvert.TagName, "header"))
{
var ret = new HeaderTag();
ret.SearchProperties.AddRange(toConvert.SearchProperties);
ret.SearchConfigurations = toConvert.SearchConfigurations;
ret.FilterProperties.AddRange(toConvert.FilterProperties);
// screen element
// technology is already set - web
// cached queryid
// cached parent
// boundary screen element
return ret;
}
throw new InvalidOperationException("Control cannot be converted.");
}
但是,在反编译HtmlControl 类型本身之后,我看到有一个CopyFromControl 方法是不可访问的;此外,它设置的字段不可访问(上面已评论)。
我不确定我是否复制这些字段是否真的很重要,以及它们是否过于重要而无法复制,但我希望找到更好的解决方案。如果没有更好的办法出现,我可能会诉诸反思,但如果可以避免的话,我宁愿不走那条路。
UITestControl 基本上只是一个用于访问本机 UI 控件的包装器。一旦找到 UI 控件,UITestControl 就会保留对该对象的引用。然后您可以使用其 CopyFrom 函数复制该引用(连同搜索属性)。
因此,您可以(并且可能应该)简单地在您自己的 class 实例上调用 CopyFrom 函数,而不是转换或强制转换,将其传递给 FindMatchingControls 返回的 UITestControl。
我对 Linq 不够熟练,所以代码不够漂亮,但这样的东西会起作用:
List<HeaderTag> list = new List<HeaderTag>();
foreach (var item in new HeaderTag(window).FindMatchingControls())
{
HeaderTag temp = new HeaderTag();
temp.CopyFrom(item);
list.Add(temp);
}
我不确定为什么不能转换,因为您的 class 是从 UITestControl 派生的。但是如果转换失败你应该使用 CopyFrom.
我最近一直在深入研究 CodedUI,并且很高兴扩展库以包含其余 HTML 元素(无论出于何种原因)被排除在 Microsoft.VisualStudio.TestTools.UITesting.HtmlControls 之外命名空间。
我注意到我可以做如下事情:
var divs = new HtmlDiv(window).FindMatchingControls().OfType<HtmlDiv>();
这将 return 您所期望的:具有与 FindMatchingControls() 调用相同元素的 IEnumerable(只是键入 HtmlDiv 而不是 UITestControl)。
此外,我可以这样做:
public class HtmlHeader : HtmlCustom
{
public static readonly string HeaderTag = "header";
public HtmlHeader() : base() {
this.SearchProperties.Add(HtmlControl.PropertyNames.TagName, HeaderTag, PropertyExpressionOperator.EqualTo);
}
public HtmlHeader(UITestControl parent) : base(parent) {
this.SearchProperties.Add(HtmlControl.PropertyNames.TagName, HeaderTag, PropertyExpressionOperator.EqualTo);
}
}
甚至这个也有效:
var headerTag = new HeaderTag(window);
它将在屏幕上找到 header 个标签,并为您找到第一个标签。
var headerTags = new HeaderTag(window).FindMatchingControls();
工作正常,但是
var headerTags = new HeaderTag(window).FindMatchingControls().OfType<HeaderTag>();
为空。
为什么上述命名空间中的 HtmlControls 可以正确解析类型?
我能否利用隐式转换运算符/其他技巧将 OfType() 转换为 return 一个 collection HtmlTags?
我开始写这样的转换:
protected HeaderTag ConvertControl(HtmlControl toConvert)
{
if (StringComparer.OrdinalIgnoreCase(toConvert.TagName, "header"))
{
var ret = new HeaderTag();
ret.SearchProperties.AddRange(toConvert.SearchProperties);
ret.SearchConfigurations = toConvert.SearchConfigurations;
ret.FilterProperties.AddRange(toConvert.FilterProperties);
// screen element
// technology is already set - web
// cached queryid
// cached parent
// boundary screen element
return ret;
}
throw new InvalidOperationException("Control cannot be converted.");
}
但是,在反编译HtmlControl 类型本身之后,我看到有一个CopyFromControl 方法是不可访问的;此外,它设置的字段不可访问(上面已评论)。
我不确定我是否复制这些字段是否真的很重要,以及它们是否过于重要而无法复制,但我希望找到更好的解决方案。如果没有更好的办法出现,我可能会诉诸反思,但如果可以避免的话,我宁愿不走那条路。
UITestControl 基本上只是一个用于访问本机 UI 控件的包装器。一旦找到 UI 控件,UITestControl 就会保留对该对象的引用。然后您可以使用其 CopyFrom 函数复制该引用(连同搜索属性)。
因此,您可以(并且可能应该)简单地在您自己的 class 实例上调用 CopyFrom 函数,而不是转换或强制转换,将其传递给 FindMatchingControls 返回的 UITestControl。
我对 Linq 不够熟练,所以代码不够漂亮,但这样的东西会起作用:
List<HeaderTag> list = new List<HeaderTag>();
foreach (var item in new HeaderTag(window).FindMatchingControls())
{
HeaderTag temp = new HeaderTag();
temp.CopyFrom(item);
list.Add(temp);
}
我不确定为什么不能转换,因为您的 class 是从 UITestControl 派生的。但是如果转换失败你应该使用 CopyFrom.