1

Hi I can't figure out how to get an element by CSS and matching with text. I know it can be done with Xpath but I'd rather use CSS.

<div class="button-face"> <div class="button-face-caption"> Text I want to find 1</div> </div> <div class="button-face"> <div class="button-face-caption"> Text I want to find 2</div> </div> 

So in by CSS would be something like...

driver.find_element_by_css('div.button-face-caption')

But how can add the text matching to that? i tried with contains and innerText and none seem to work.

2
  • Why the preference for css in this case?
    – DMart
    CommentedJan 14, 2021 at 22:10
  • @trickymuffin Can you update the HTML with the parent element of <div class="button-face">?CommentedJan 15, 2021 at 18:20

3 Answers 3

1

As you said it's supported in xpath:

This would be a solution with an xpath using contains and text()

driver.find_element_by_xpath('//div[@class="button-face-caption" and contains(text(),"Text I want to find")]') 

The xpath being:

//div[@class="button-face-caption" and contains(text(),"Text I want to find")] 

For css, look here: https://sqa.stackexchange.com/q/362/34209 which should allow us to use:

div:contains('Text I want to find') 

Which would lead us to

driver.find_element_by_css("div:contains('Text I want to find')") 

However this comes with a BIG caveat:

:contains() is not part of the current CSS3 specification so it will not work on all browsers, only ones that implemented it before it was pulled. (see w3.org/TR/css3-selectors)

2
  • driver.find_element_by_css_selector("div:contains('No, I need to create an account')").click() InvalidSelectorException: Message: An invalid or illegal selector was specified :(CommentedJan 14, 2021 at 22:21
  • which browser? As I stated, it's not actually valid CSS. I would just use xpath.
    – DMart
    CommentedJan 15, 2021 at 3:56
0

As workaround you can create your own function

def find_by_css(selector, text=''): return [element for element in driver.find_elements_by_css_selector(selector) if text in element.text][0] 

Then you can call it as

find_by_css('div.button-face-caption') # search only by CSS-selector 

or

find_by_css('div.button-face-caption', 'Text I want to find 2') # search by CSS + text 
    0

    As per the following discussions:

    The :contains pseudo-class isn't in the CSS Spec and is not supported by either Firefox or Chrome (even outside WebDriver).


    Solution

    You need to consider the ancestor of the <div class="button-face"> element and traverse down. Let us assume that both the <div class="button-face"> are with in a parent <div class="class">:

    <div class="class"> <div class="button-face"> <div class="button-face-caption"> Text I want to find 1</div> </div> <div class="button-face"> <div class="button-face-caption"> Text I want to find 2</> </div> </div> 

    So to identify the element with text as:

    • Text I want to find 1:

      div.class div:first-child > div.button-face-caption 
    • Text I want to find 2:

      div.class div:nth-child(2) > div.button-face-caption 

    References

    You can find a couple of relevant detailed discussions in:

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.