msmith1114
msmith1114

Reputation: 3241

Capybara wait until button is enabled?

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

Answers (2)

Thomas Walpole
Thomas Walpole

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

jmq
jmq

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

Related Questions