4

How can I wait for a presence of an element which the content (text) is not empty? I tried select by xpath using //*[@id="test" and text() != ""], but the return of WebDriverWait#until does not retrieve the element.

My code:

selector = '//*[@id="test" and text() != ""]'
element = WebDriverWait(driver, timeout).until(
  expected_conditions.presence_of_element_located((By.XPATH, selector))
)

I would like to get the text content of the element. I tried:

print element.text # prints 0

If i print only element, the output is <selenium.webdriver.remote.webelement.WebElement(session="xxx", element="xxx")>. What is wrong?

The div I'm tryin to get has this structure:

<div>
   Test:
   <div id="test"><b>this text here</b></div>
</div>
Renan Gomes
  • 771
  • 1
  • 15
  • 34

2 Answers2

3

You can wait for an element by xpath with non empty text like this:

xpath = "//*[@id='test']"

WebDriverWait(driver, 30).until(lambda driver: driver.find_element_by_xpath(xpath).text.strip() != '')

source

Sergey
  • 321
  • 2
  • 9
2

The text() xpath function would not help in this case since it would not consider the texts of the child elements. You actually need to call the .text in your Expected Condition. You can create a custom one:

from selenium.webdriver.support import expected_conditions as EC

class wait_for_non_empty_text(object):
    def __init__(self, locator):
        self.locator = locator

    def __call__(self, driver):
        try:
            element_text = EC._find_element(driver, self.locator).text.strip()
            return element_text != ""
        except StaleElementReferenceException:
            return False

Usage:

wait = WebDriverWait(driver, timeout)
element = wait.until(
    wait_for_non_empty_text((By.ID, "test"))
)
print(element.text)
Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • @renan hm, should not be the case if you copied the code correctly, please recheck. – alecxe Dec 08 '16 at 16:13
  • @renan could you please put a `print(element_text)` into the Expected Condition to see what the value is printed. Also, is there a difference if you would use `element_text = EC._find_element(driver, self.locator).get_attribute("textContent").strip()` instead? Thanks. – alecxe Dec 08 '16 at 16:24
  • @renan oh yeah, try without calling `strip()` please. – alecxe Dec 08 '16 at 16:40
  • I put a print to show `element_text` value and it's `0`. – Renan Gomes Dec 08 '16 at 16:58
  • @renan ah, so, do you need to wait for the text to be non-zero or non-empty? – alecxe Dec 08 '16 at 17:49
  • Non empty alecxe, but the return of `EC._find_element(driver, self.locator).text.strip()` is being `0` and don't know from where this value is comming, the page does not insert `0` inside the div `#test`. – Renan Gomes Dec 08 '16 at 17:57
  • @alecxe, this was a great tip I used successfully in my work, but after upgrade to Selenium 4, there is no longer _find_element() function in expected_conditions, so your wait_for_non_empty_text no longer works. Is there a way to change it to still be able to call this function using wait.until() in Selenium 4 please? – SLB Jul 26 '23 at 21:15