Reputation: 3241
Surprised I actually haven't come across this, but I have a simple button that is disabled until a dropdown is selected. Sometimes the page isn't fast enough to "enable" the button to be clicked on after the previous dropdown is selected causing it to fail.
I could throw in a "sleep" of a second or two and fix this, but that seems like a lazy/poor way to do this.
Is there a way in capybara (or purely selenium) that I can make it wait until the button is actually enabled? I'd like to throw this is the page model method for this button (as im trying to avoid API specific methods/selenium/etc... in the actual test specs (Although I can if I need to).
FWIW this is specifically for Ruby's capybara framework but pure selenium is fine as well.
Upvotes: 1
Views: 6152
Reputation: 49960
Assuming the button you're referring to is actually a button (<button> element, or <input> element with type submit, reset, image, or button) then Capybaras :button selector will (by default) wait for it to be non-disabled.
click_button('Something')
or
find_button('button_id').click
or
find(:button, 'button_value').click
If any of the finder or action methods aren't waiting long enough for a specific element you can always increase the maximum wait time for a specific finder/action by passing a :wait option
find(:button, 'Something', wait: 10).click
If you're not using selector types (if not, why not) and instead are just using raw CSS to locate the element then you can use the :enabled
pseudo class along with your existing CSS and something like
find('#my_button:enabled', wait: 10).click
If the element you're calling a button isn't actually a button but some other type of element (<a> etc) styled to look like a button, then you'll need to explain exactly how you're disabling the "button".
Upvotes: 5
Reputation: 1591
In Python you can do something like this:
def wait_until_clickable(driver, xpath, timeout = 1):
while timeout > 0:
try:
element = driver.find_element_by_xpath(xpath)
element.click()
return element
except:
time.sleep(0.1)
timeout = timeout - 0.1
return False
Upvotes: 1