WatiN: When searching for text, how do I get a link to its containing element?

Given the following HTML page:

<html> <head> <title>WatiN Test</title> </head> <body> <div> <p>Hello World!</p> </div> </body> </html> 

I would like to be able to search for some text (for example, "World" ) and get a link to its parent element (in this case, the <p> element).


If I try this:

 var element = ie.Element(Find.ByText(t => t.Contains("World"))) 

or that:

 var element = ie.Element(e => e.Text != null && e.Text.Contains("World")); 

I am returning an <html> element. This is consistent with the WatiN documentation for Element.Text , which states: "Gets the inner text of this element (and the inner text of all elements contained in this element)."

Since all the text inside the page is contained in the <html> element, I always get this back instead of the immediate parent.


Is there a way to get the text immediately below the element (and not the text inside the elements contained in it)?

Is there any other way to do this?

Many thanks.

+6
c # watin
source share
3 answers

Bellow code will find the first element inside <body/> with text containing "World". Elements that are classified as element containers and have 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 is not. I think this is a mistake. I wrote a post about this on the WatiN mailing list and will update this answer when I receive a response.

+2
source share

You can use Find.BySelector

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

I came up with something that works, but it is a bit hacked and very inefficient.

This essentially works on the basis that the deepest containing element will have the shortest InnerHtml . That is, all other elements that contain the immediate parent will also contain HTML code, and therefore will 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; } 
+1
source share

All Articles