Perform a WebDriverWait() or similar check on a Regular Expression in Python
Asked Answered
E

2

3

I would like to be able to perform something similar to a WebDriverWait(), i.e:

WebDriverWait(driver, 60).until(
    expected_conditions.text_to_be_present_in_element((By.XPATH, "//tr[5]/td[11]/div"), "1.000000")
)

...for a regular expression, where it waits for an allotted amount of time before failing. I am aware I could do something, such as...

assert re.search(r"[0,1]{1}.[0-9]{6}", driver.find_element_by_xpath("//tr[5]/td[11]/div").text)

...or I could replace search with match in the above example. The problem with this method is it'll fail if the object.. (1) hasn't loaded yet or.. (2) is still in the process of changing to what's expected. I could do something like...

for x in range (1,60):
    try:
        assert re.search(r"[0,1]{1}.[0-9]{6}", driver.find_element_by_xpath("//tr[5]/td[11]/div").text)
    except AssertionError:
        if x < 60:
            time.sleep(1)
        else:
            raise AssertionError

...where it checks every second for 60 seconds to see if the assert statement has evaluated to true. This could fit into a module or class. What I'm wondering is if there is a more elegant solution, in Python for the Selenium WebDriver, to handling this that I'm unaware of.

Eluviation answered 30/1, 2015 at 16:30 Comment(0)
I
7

If you look into what an "Expected Condition" is, you would find it easy to make a custom one:

import re

from selenium.webdriver.support.expected_conditions import _find_element


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

    def __call__(self, driver):
        element_text = _find_element(driver, self.locator).text
        return re.search(self.regexp, element_text)

Usage:

WebDriverWait(driver, 60).until(
    text_match((By.XPATH, "//tr[5]/td[11]/div"), r"[0,1]{1}.[0-9]{6}")
)
Intercalate answered 30/1, 2015 at 16:40 Comment(4)
Thank you for your reply! I will spend some time dissecting how it works when I get a chance. I also believe this will help deepen my understanding of Python. Much appreciated!Eluviation
Hey @alecxe. I just finally got around to trying this and received the following error for the return statement: AttributeError: 'tuple' object has no attribute 'text'Eluviation
@Eluviation yeha, my bad, fixed - please check it out again. Thanks.Intercalate
+1 for the great answer. It is from 2015 and but the current documentation selenium-python.readthedocs.io/waits.html implements it a little different now.Edla
A
0

In newer versions of Selenium, you can do it like this

def regex_to_be_present_in_element(locator, regexp):
    """ An expectation for checking if the given text is present in the
    specified element, extended to allow and return a regex match
    locator, text
    """

    def _predicate(driver):
        try:
            element_text = driver.find_element(*locator).text
            return re.search(regexp, element_text)
        except StaleElementReferenceException:
            return False

    return _predicate

Usage:

match = WebDriverWait(driver, 60).until(
    regex_to_be_present_in_element((By.XPATH, "//tr[5]/td[11]/div"), r"[0,1]{1}.[0-9]{6}")
)

You can even access the match groups using match.groups(), e.g. to process status/error messages.

Acanthoid answered 17/2, 2023 at 22:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.