0

I have successfully used wait_for_non_empty_text() from this discussion: How to wait for presence of an element with non empty content? in my Selenium v3 project, but after upgrade to Selenium 4, there is no longer _find_element() function in expected_conditions module, so wait_for_non_empty_text() no longer works.

Looks like Python\Python311\Lib\site-packages\selenium\webdriver\support\expected_conditions.py was completely re-written for Selenium 4.

Is there a way to change this custom expected condition to still be able to call this function using "wait.until()" under Selenium 4?

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

I tried for hours but cannot figure out how to make it work without _find_element().

Thanks!

SLB
  • 101
  • 1
  • 1
  • 4

1 Answers1

0

I would suggest updating your code to something like the following. First add these 3 imports to help locate the element you are looking for.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

Next I will give an example of how to use those in the code you provided. Update: Assuming the function is called like this wait_for_non_empty_text((By.ID, "test")).

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

    def __call__(self, driver):
        try:
            # Your old code
            # element_text = EC._find_element(driver, self.locator).text.strip()
            # New Example:
            element_text =  WebDriverWait(driver, 10).until(EC.presence_of_element_located(self.locator)).text.strip()
            return element_text != ""
        except StaleElementReferenceException:
            return False
Jortega
  • 3,616
  • 1
  • 18
  • 21
  • Thank you very much @Jortega, this function is a part of my utilities library in a separate module and it is called in hundreds of places from other Python modules. I use it to wait for some type-in fields to be populated, for example: WebDriverWait(driver, 15).until( U.wait_for_non_empty_text((By.XPATH, "//strong[normalize-space()='New Rule']")) ) This is shown with better formatting in the original post I linked to my question that the function originated from. – SLB Jul 27 '23 at 15:10
  • The way it is re-written by you, a) I'll have to make changes in in these hundreds of places I think since you moved WebDriverWait into this utility function, and b) I am not sure it will work as expected since it will now wait for element to show up and then simply check once whether there is text within it. Does it makes sense? Or am I misinterpreting your response? – SLB Jul 27 '23 at 15:11
  • @SLB I see, I'll update the answer assuming the function is called like this `wait_for_non_empty_text((By.ID, "test"))` – Jortega Jul 27 '23 at 15:25
  • Again, thank you for the quick response, @Jortega. The interface now indeed matches the original one, so I can call it as is, but just to be clear: are you saying that I still should call it from my currently used WebDriverWait(driver, 15).until() wrapper in all the places as I currently do? Despite having another WebDriverWait(driver, 10).until() within wait_for_non_empty_text()--so that would be two waits on every call? Would that work? – SLB Jul 27 '23 at 19:19
  • I can see from https://www.selenium.dev/selenium/docs/api/py/_modules/selenium/webdriver/support/expected_conditions.html#presence_of_element_located that it simply calls _driver.find_element(*locator)_, so not sure if changing the main line of the new function to _element_text = EC.presence_of_element_located(self.locator).text.strip()_ would also work and eliminate one of the waits, making it more like the original function? – SLB Jul 27 '23 at 19:23
  • @SLB Yes, there are many ways to update your code to work in Selenium 4. I was just providing an example. – Jortega Jul 27 '23 at 19:45