I'm trying to test a complicated JavaScript interface with Selenium (using the Python interface, and across multiple browsers). I have a number of buttons of the form:
<div>My Button</div>
I'd like to be able to search for buttons based on "My Button" (or non-case-sensitive, partial matches such as "my button" or "button").
I'm finding this amazingly difficult, to the extent to which I feel like I'm missing something obvious. The best thing I have so far is:
driver.find_elements_by_xpath('//div[contains(text(), "' + text + '")]')
This is case-sensitive, however. The other thing I've tried is iterating through all the divs on the page, and checking the element.text property. However, every time you get a situation of the form:
<div class="outer"><div class="inner">My Button</div></div>
div.outer also has "My Button" as the text. To fix that, I've tried looking to see if div.outer is the parent of div.inner, but I couldn't figure out how to do that (element.get_element_by_xpath('..') returns an element's parent, but it tests not equal to div.outer).
Also, iterating through all the elements on the page seems to be really slow, at least using the Chrome webdriver.
Ideas?
I asked (and answered) a more specific version here: How to get text of an element in Selenium WebDriver, without including child element text?
https://stackoverflow.com/questions/12323403/how-do-i-find-an-element-that-contains-specific-text-in-selenium-webdriver-pyth/18701085#18701085
Share
Improve this answer
Follow
–
–
–
–
https://stackoverflow.com/questions/12323403/how-do-i-find-an-element-that-contains-specific-text-in-selenium-webdriver-pyth/12323689#12323689
Share
Improve this answer
Follow
–
–
–
–
<div>My Button</div>
The text My Button
is the innerHTML
and have no whitespaces around it so you can easily use text()
as follows:
my_element = driver.find_element_by_xpath("//div[text()='My Button']")
Note: text()
selects all text node children of the context node
Text with leading/trailing spaces
In case the relevant text containing whitespaces either in the beginning:
<div> My Button</div>
or at the end:
<div>My Button </div>
or at both the ends:
<div> My Button </div>
In these cases you have two options:
You can use contains()
function which determines whether the first argument string contains the second argument string and returns boolean true or false as follows:
my_element = driver.find_element_by_xpath("//div[contains(., 'My Button')]")
You can use normalize-space()
function which strips leading and trailing white-space from a string, replaces sequences of whitespace characters by a single space, and returns the resulting string as follows:
driver.find_element_by_xpath("//div[normalize-space()='My Button']]")
XPath expression for variable text
In case the text is a variable, you can use:
foo= "foo_bar"
my_element = driver.find_element_by_xpath("//div[.='" + foo + "']")
https://stackoverflow.com/questions/12323403/how-do-i-find-an-element-that-contains-specific-text-in-selenium-webdriver-pyth/59698552#59698552
Share
Improve this answer
Follow
–
//* will be looking for any HTML tag. Where if some text is common for Button and div tag and if //* is categories it will not work as expected. If you need to select any specific then You can get it by declaring HTML Element tag. Like:
driver.find_element_by_xpath("//div[contains(text(),'Add User')]")
driver.find_element_by_xpath("//button[contains(text(),'Add User')]")
https://stackoverflow.com/questions/12323403/how-do-i-find-an-element-that-contains-specific-text-in-selenium-webdriver-pyth/53813097#53813097
Share
Improve this answer
Follow
https://stackoverflow.com/questions/12323403/how-do-i-find-an-element-that-contains-specific-text-in-selenium-webdriver-pyth/41693743#41693743
Share
Improve this answer
Follow
Interestingly virtually all answers revolve around XPath's function contains()
, neglecting the fact it is case sensitive - contrary to the OP's ask.
If you need case insensitivity, that is achievable in XPath 1.0 (the version contemporary browsers support), though it's not pretty - by using the translate()
function. It substitutes a source character to its desired form, by using a translation table.
Constructing a table of all upper case characters will effectively transform the node's text to its lower() form - allowing case-insensitive matching (here's just the prerogative):
contains(
translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),
'my button'
# will match a source text like "mY bUTTon"
The full Python call:
driver.find_elements_by_xpath("//*[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZЙ', 'abcdefghijklmnopqrstuvwxyzй'), 'my button')]")
Naturally this approach has its drawbacks - as given, it'll work only for Latin text; if you want to cover Unicode characters - you'll have to add them to the translation table. I've done that in the sample above - the last character is the Cyrillic symbol "Й"
.
And if we lived in a world where browsers supported XPath 2.0 and up (🤞, but not happening any time soon ☹️), we could having used the functions lower-case()
(yet, not fully locale-aware), and matches
(for regex searches, with the case-insensitive ('i'
) flag).
https://stackoverflow.com/questions/12323403/how-do-i-find-an-element-that-contains-specific-text-in-selenium-webdriver-pyth/54417109#54417109
Share
Improve this answer
Follow
Similar problem: Find <button>Advanced...</button>
Maybe this will give you some ideas (please transfer the concept from Java to Python):
wait.until(ExpectedConditions.elementToBeClickable(//
driver.findElements(By.tagName("button")).stream().filter(i -> i.getText().equals("Advanced...")).findFirst().get())).click();
https://stackoverflow.com/questions/12323403/how-do-i-find-an-element-that-contains-specific-text-in-selenium-webdriver-pyth/56120529#56120529
Share
Improve this answer
Follow
https://stackoverflow.com/questions/12323403/how-do-i-find-an-element-that-contains-specific-text-in-selenium-webdriver-pyth/65786684#65786684
Share
Improve this answer
Follow
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(text(), 'YourTextHere')]")));
assertNotNull(driver.findElement(By.xpath("//*[contains(text(), 'YourTextHere')]")));
String yourButtonName = driver.findElement(By.xpath("//*[contains(text(), 'YourTextHere')]")).getAttribute("innerText");
assertTrue(yourButtonName.equalsIgnoreCase("YourTextHere"));
https://stackoverflow.com/questions/12323403/how-do-i-find-an-element-that-contains-specific-text-in-selenium-webdriver-pyth/45639766#45639766
Share
Improve this answer
Follow
Use driver.find_elements_by_xpath and matches regex matching function for the case insensitive search of the element by its text.
driver.find_elements_by_xpath("//*[matches(.,'My Button', 'i')]")
https://stackoverflow.com/questions/12323403/how-do-i-find-an-element-that-contains-specific-text-in-selenium-webdriver-pyth/52097487#52097487
Share
Improve this answer
Follow
–
If using C#
ChromeOptions options = new ChromeOptions();
var driver = new ChromeDriver(options);
var urlLink = "https://www.pexels.com/tr-tr/arama/do%C4%9Fa/";
driver.Navigate().GoToUrl(urlLink);
Thread.Sleep(10000);
var divList = driver.FindElementsByXPath(".//div[contains(@class,'hide-featured-badge')]");
foreach (var divItem in divList)
var photoOwnerName = divItem.FindElement(By.XPath(".//span[@class='photo-item__name']")).GetAttribute("innerHTML");
https://stackoverflow.com/questions/12323403/how-do-i-find-an-element-that-contains-specific-text-in-selenium-webdriver-pyth/68153270#68153270
Share
Improve this answer
Follow
https://stackoverflow.com/questions/12323403/how-do-i-find-an-element-that-contains-specific-text-in-selenium-webdriver-pyth/21630803#21630803
Share
Improve this answer
Follow
–
–
–
–