Reputation: 654
Selenium offers explicit wait functionality to handle situations (for example) when you want to execute a click()
operation on an element which is not yet clickable.
The syntax is as follows:
WebDriverWait(self._driver, 20).until(EC.element_to_be_clickable(BY.ID, 'some-id')).click()
This tells the program to wait until some element (located by its ID) is clickable.
Under the hood, EC.element_to_be_clickable()
calls an internal _find_element()
function reading in the parameters specified by element_to_be_clickable()
.. In this case, it searches the DOM for elements corresponding with the ID: some-id
.
I cant however, directly pass in a WebElement
object into the element_to_be_clickable()
function because it fails in the internal _find_element()
call.
Is there a way I can use these explicit waits (or any alternatives) while working with the WebElements
themselves?
My initial thought is I can download the code and add functionality to bypass the _find_element()
under certain conditions but wondering if anyone else has had this issue.
Thanks in advance.
Upvotes: 1
Views: 444
Reputation: 20067
You could, stretching the WebDriverWait operations a bit - by passing to it not a driver object, but the element itself, and a lambda function to the until()
.
As you've seen in its code, the "meat" of WebDriverWait's until()
is to call the passed function with an argument the passed object, and return the outcome:
value = method(self._driver)
if value:
return value
So in theory, you could pass the element itself, and as a function to have an expression that returns the element if all checks are matching, or False
if not.
The original element_to_be_clickable
expects two things out of the element (apart from it to be present) - is_displayed()
and is_enabled()
. Thus the expression, inside a lambda, would be:
lambda x: x if x.is_displayed() and x.is_enabled() else False
And the whole call would he:
WebDriverWait(self.your_webelemt_object, 20).until(lambda x: x if x.is_displayed() and x.is_enabled() else False).click()
I said "in theory", causes I'm typing this on mobile :), and I haven't checked it in practice (but the theoery is solid ;). What could go wrong? An exception to be raised, that is different from what WebDriverWait normally handles (it handles during the waits just NoSuchElementException
, by default). If that's the case, you have to pass those additional exceptions to its constructor:
WebDriverWait(self.your_webelemt_object, 20, ignored_exceptions=[NoSuchElementException, the_other_exceptions]). # the rest omitted for brevity
Upvotes: 1