Selenium Find Element Based on String in Text or Attribute
Asked Answered
O

3

17

I'm trying to have Selenium find an element based on a string that can be contained in the element's text or any attribute, and I'm wondering if there's some wildcard I can implement to capture all this without having to use multi-condition OR logic. What I'm using right now that works is ...

driver.findElement(By.xpath("//*[contains(@title,'foobar') or contains(.,'foobar')]"));

And I wanted to know if there's a way to use a wildcard instead of the specific attribute (@title) that also encapsulates element text like the 2nd part of the OR condition does.

Oconnor answered 27/8, 2015 at 21:36 Comment(6)
I don't think so, but something that might help you arrive at a more definitive answer is here.Erwinery
Is there even at least a way to wildcard just the attribute-specific portion (like turning just @title into any attribute) but leaving out text()?Oconnor
Can you give us an idea of why you want to do this? How are you using this?Neoteric
Basically I have 3 different pages, each with an element containing this string in different ways as I've described above, and I want to implement an ExpectedConditions wait that waits for this element to be present or visible.Oconnor
So you'd have to write 3 different functions and you're trying to boil it down to just one? Why?Neoteric
Both for learning's sake and if I get a 4th page in the future that uses it differently than the other three, the code will still successfully find the element.Oconnor
B
35

This will give all elements that contains text foobar

driver.findElement(By.xpath("//*[text()[contains(.,'foobar')]]"));

If you want exact match,

driver.findElement(By.xpath("//*[text() = 'foobar']"));

Or you can execute Javascript using JQuery in Selenium

This will return all web elements containing the text from parent to the last child, hence I am using the jquery selector :last to get the inner most node that contains this text, but this may not be always accurate, if you have multiple nodes containing same text.

(WebElement)((JavascriptExecutor)driver).executeScript("return $(\":contains('foobar'):last\").get(0);");

If you want exact match for the above, you need to run a filter on the results,

(WebElement)((JavascriptExecutor)driver).executeScript("return $(\":contains('foobar')\").filter(function() {" +
    "return $(this).text().trim() === 'foobar'}).get(0);");

jQuery returns an array of Elements, if you have only one web element on the page with that particular text you will get an array of one element. I am doing .get(0) to get that first element of the array and cast it to a WebElement

Hope this helps.

Bield answered 27/8, 2015 at 22:11 Comment(3)
Doesn't seem either of the top two will cover the case where an attribute like @title contains the string.Oconnor
@Oconnor when you say @title, you mean the title of the page right? The <title> tag inside <head>. I tested the xpath for this page itself, //*[text() = 'java - Selenium Find Element Based on String in Text or Attribute - Stack Overflow'] and it gave the title webelement. I am not sure if I understand right, the last 2 lines of your question is a little unclear to me.Bield
Actually it's just the title attribute of a WebElement, in this case a button element. It's not the page title.Oconnor
C
5

This will return the element with text foobar

driver.findElement(By.xpath("//*[text()='foobar']"))
Classy answered 28/8, 2015 at 13:15 Comment(0)
T
0

Text Containing

To find an element with the text (displayed in the HTML page) containing a specific text, you can use the following XPath:

//*[contains(text(), 'text_to_be_contained')]
  • '*', selects all elements in the document, regardless of the tag name. You can replace the asterisk (*) with a specific tag name if you want to search within a particular tag type.
  • [contains(text(), 'text_to_be_contained')] is a condition that checks if the text contains the specified text ('text_to_be_contained'). This will match elements whose text attribute contains the specified text, even if it is part of a larger text value.
  • 'text_to_be_contained', should be the text you want to find

Attribute Containing

To find an element with the attribute containing a specific text, you can use the following XPath expression:

//*[contains(@attribute_name, 'text_to_be_contained')]
  • Replace 'attribute_name' with the actual name of the attribute you want to search within, such as: class, name, href, value, or any other

Text/Attribute Is Equal

To find an element with the text or attribute a matching exactly a specific text, you can use the following XPath expressions: For the text

For the text:

//*[text()='exact_text']

For the attribute:

//*[@attribute_name='exact_text']
  • 'exact_text', should be the text you want to find
Tribune answered 6/6, 2023 at 14:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.