I'm needing to add a new condition to the code below because my click and arrow_right commands have sometimes been (unknowingly) failing:
value_items = \
(selection_section.find_elements_by_class_name("stuff")
selection_section.find_elements_by_class_name("stuff1")) or \
(selection_section.find_elements_by_css_selector(".stuff2.stuff3"))
for value in value_items:
if value.text in values_to_select:
self.browser.execute_script("arguments[0].scrollIntoView();", value)
# Removing "move_to_element" from the ActionChains below seems to result in a marginal speed-up, but often causes the run
# to fail when running headless. (The run can also fail with "move_to_element", just not as often)
self.wait.until(expected_conditions.element_to_be_clickable(value))
ActionChains(self.browser).click(value).send_keys(Keys.ARROW_RIGHT).perform()
The documentation for element_to_be_clickable states that it accepts either a locator or a WebElement, but when I run the code above I get the following error:
TypeError: selenium.webdriver.remote.webdriver.WebDriver.find_element() argument after * must be an iterable, not WebElement
CodePudding user response:
Your code is wrong
You use element_to_be_clickable
too later (after value_items = ....
)
You need use element_to_be_clickable
before your 1st line value_items = ....
CodePudding user response:
As per the documentation element_to_be_clickable()
should be called within a tuple
as it is not a function but a class, where the initializer expects just 1 argument beyond the implicit self:
def element_to_be_clickable(mark):
"""
An Expectation for checking an element is visible and enabled such that
you can click it.
element is either a locator (text) or an WebElement
"""
# renamed argument to 'mark', to indicate that both locator
# and WebElement args are valid
def _predicate(driver):
target = mark
if not isinstance(target, WebElement): # if given locator instead of WebElement
target = driver.find_element(*target) # grab element at locator
target = visibility_of(target)(driver)
if target and target.is_enabled():
return target
else:
return False
return _predicate
So irrespective of a locator or a WebElement you have to pass as a tuple
.
This usecase
Your effective line of code will be:
self.wait.until(expected_conditions.element_to_be_clickable((value)))