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? Commented Jan 14, 2021 at 22:10
  • @trickymuffin Can you update the HTML with the parent element of <div class="button-face">? Commented Jan 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)

Sign up to request clarification or add additional context in comments.

2 Comments

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 :(
which browser? As I stated, it's not actually valid CSS. I would just use xpath.
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

Comments

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:

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.