Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium: How to locate a node using exact text match

Tags:

selenium

xpath

I want to locate a Element on a Web Page using text.
I know there is a method name contains to do so, for example:

tr[contains(.,'hello')]/td

But problem is if I have two elements name hello and hello1 then this function does not work properly.

Is there any other method like contains for exact string match for locating elements?

like image 881
Abhinav Garg Avatar asked Oct 14 '11 09:10

Abhinav Garg


4 Answers

tr[.//text()='hello']/td

this will select all td child elements of all tr elements having a child with exactly 'hello' in it. Such an XPath still sounds odd to me.

I believe that this makes more sense:

tr/td[./text()='hello']

because it selects only the td that contains the text.

does that help?

like image 55
Dennis Münkle Avatar answered Oct 02 '22 13:10

Dennis Münkle


It all depends on what your HTML actually contains, but your tr[contains(.,'hello')]/td XPath selector means "the first cell of the first row that contains the string 'hello' anywhere within it" (or, more accurately, "the first TD element in the TR element that contains the string 'hello' anywhere within it", since Selenium has no idea what the elements involved really do). That's why it's getting the wrong result when there are rows containing "hello" and "hello1" - both contain "hello".

The selector tr[. ='hello']/td would be more accurate, but it's a little unusual (because HTML TR elements aren't supposed to contain text - the text is supposed to be in TH or TD elements within the TR), and it probably won't work (because text in any other cells would break the comparison). You probably want tr[td[.='hello']]/td, which means "the first TD element contained in the TR element that contains a TD element that has the string 'hello' as it's complete text".

like image 44
Ross Patterson Avatar answered Oct 02 '22 15:10

Ross Patterson


Well, your problem is that you are searching text into the tr (which is not correct anyway) and this cause a problem to the function contains which cannot accept a list of text. Try to use this location path instead. It should retrieve what you want.

//tr/td[contains(./text(),"hello")]

This location path will retrieve a set of node on which you have to iterate to get the text. You can try to append the

/text()

but this will cause (at least on my test) a result that is a string which is a concatenation of all the matched strings.

like image 42
Aurelio De Rosa Avatar answered Oct 02 '22 13:10

Aurelio De Rosa


I had the same probem. I had a list of elements, one was named "Image" and another one was named "Text and Image". After reading all the posts here, non of the sugestions worked for me. So I tryed the following and it worked:

List<WebElement> elementList = new ArrayList<WebElement>();
elementList = driver.findElements(By.xpath("//*[text()= '" +componentName+"']"));

for(WebElement element : elementList){
    if(element.getText().equals(componentName)){
       element.click();
    }
}
like image 22
Lazar Zoltan Avatar answered Oct 02 '22 13:10

Lazar Zoltan