【问题标题】:How to extend CodedUI HtmlControls and preserve typing如何扩展 CodedUI HtmlControls 并保留输入
【发布时间】:2015-03-26 00:57:38
【问题描述】:

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

我注意到我可以执行以下操作:

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

这将返回您所期望的:一个与 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);

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

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

工作正常,但是

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

是空的。

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

我能否利用隐式转换运算符/其他一些技巧来让 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 方法无法访问;此外,它正在设置的字段是不可访问的(上面有评论)。

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

【问题讨论】:

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


    【解决方案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。

    【讨论】:

    • 呃,我觉得自己很愚蠢。我正在重新创建我认为出于某种原因是私有的 CopyFrom 方法@_o
    猜你喜欢
    • 1970-01-01
    • 2019-06-28
    • 2014-06-20
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多