WatiN: When finding text, how do I get a reference to its containing element?

谁说胖子不能爱 提交于 2019-12-05 06:04:48

Bellow code will find first element inside the <body/> with text containing "World". Elements which are classified as element containers and has child elements will be omitted.

var element = ie.ElementOfType<Body>(Find.First()).Element(e =>
{
    if (e.Text != null && e.Text.Contains("World"))
    {
        var container = e as IElementContainer;
        if (container == null || container.Elements.Count == 0)
            return true;
    }
    return false;
});

Note: You may wonder why I wrote ie.ElementOfType<Body>(Find.First()).Element instead of just ie.Element. This should work, but it doesn't. I think it's a bug. I wrote a post about it on WatiN mailing list and will update this answer when I receive the answer.

You could use Find.BySelector

var element = ie.Element(Find.BySelector("p:contains('World')"));

I've come up with something that works, but it's a bit hacky and very inefficient.

This essentially works on the basis that the deepest containing element will have the shortest InnerHtml. That is, all other elements which contain the immediate parent will include it's HTML as well, and therefore be longer!

public static Element FindElementContaining(IElementsContainer ie, string text)
{
    Element matchingElement = null;

    foreach (Element element in ie.Elements)
    {
        if (element.Text == null) continue;

        if (!element.Text.ToLower().Contains(text.ToLower())) continue;

        // If the element found has more inner html than the one we've already matched, it can't be the immediate parent!
        if (matchingElement != null && element.InnerHtml.Length > matchingElement.InnerHtml.Length) continue;

        matchingElement = element;
    }

    return matchingElement;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!