如何扩展CodedUI HtmlControls并保留输入

时间:2015-03-26 00:57:38

标签: c# reflection type-conversion coded-ui-tests

我最近一直在深入研究CodedUI,并且已经乐于扩展库以包含其余的HTML元素(无论出于何种原因),这些元素都被排除在Microsoft.VisualStudio.TestTools.UITesting.HtmlControls命名空间之外。

我注意到我可以做以下事情:

var divs = new HtmlDiv(window).FindMatchingControls().OfType<HtmlDiv>();

这将返回您的期望:IEnumerable与FindMatchingControls()调用具有相同的元素(仅键入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);

它会在屏幕上找到标题标记并为您获取第一个标记。

var headerTags = new HeaderTag(window).FindMatchingControls();

工作正常,但

var headerTags = new HeaderTag(window).FindMatchingControls().OfType<HeaderTag>();

是空的。

为什么上述命名空间中的HtmlControl正确解析类型?

我是否可以利用隐式转换运算符/其他技巧来获取OfType()以返回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方法;此外,它设置的字段不可访问(上面评论)。

我不确定是否真的重要,我是否复制这些字段,是否复制过于重要,但我希望找到更好的解决方案。如果没有更好的结果,我可能会采取反思,但如果可以避免,我宁愿不去那条路。

1 个答案:

答案 0 :(得分:1)

UITestControl基本上只是一个访问本机UI控件的包装器。找到UI控件后,UITestControl将保留对该对象的引用。然后,您可以使用其CopyFrom函数来复制该引用(以及搜索属性)。

因此,您可以(并且可能应该)简单地在您自己的类的实例上调用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);
}

我不确定为什么施放没有,因为你的类是从UITestControl派生的。但如果施法失败,你应该使用CopyFrom。