Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I write a Capybara assertion that checks for the presence of a button and its enabled or disabled state?

I have an app that enables/disables buttons in response to things that happen in the UI.

I can easily use capybara to detect if a button exists

should have_button 'save'

but I have no idea how to verify the state of the save button. That is:

How do I write a Capybara assertion that checks for the presence of a button and its enabled or disabled state?

I have hacked together a check for a disabled button; for enabled, I suppose that I could verify that there is a matching button and that there is no matching disabled button. But this, to say the least, is clunky.

This seems like such a fundamental UI check, that I am sure that I have missed something, but I can't seem to figure out what.


Follow up based on gregates's answer:

As I mentioned in the comment, the Capybara behavior is dependent upon the underlying driver. We are using webkit, and it returns "true"/"false" string results. Apparently, other drivers return true/false. The folks at Capybara are aware of the issue (github.com/jnicklas/capybara/issues/705), but they feel (probably correctly) that it isn't really their issue to resolve.

Rather than have my tests depend upon the driver I am using, I ended up creating a custom matcher:

RSpec::Matchers.define :be_enabled do
  match do |actual|
    driver_result = actual[:disabled]
    # nil, false, or "false" will all satisfy this matcher
    (driver_result.nil? || driver_result == false || driver_result == "false").should be_true
  end
end

RSpec::Matchers.define :be_disabled do
  match do |actual|
    driver_result = actual[:disabled]
    (driver_result == "disabled" || driver_result == true || driver_result == "true").should be_true
  end
end

Then you can type:

user_license_area.find_button('Save').should be_disabled
like image 635
Andy Davis Avatar asked Oct 16 '12 14:10

Andy Davis


5 Answers

It appears that Capybara's handling of disabled elements has changed, so I figured I'd give an update.

To test whether a page has a button and is enabled, use:

expect(page).to have_button('Save')

To test whether a page has a button and is disabled, use:

expect(page).to have_button('Save', disabled: true)

This format works with has_field?, find_field, etc.

You can read more on this update at http://www.elabs.se/tag/capybara

UPDATE

The old link is broken. This is the GitHub issue where the feature was discussed and this is the unfortunately barren documentation for the method.

like image 171
J3RN Avatar answered Nov 19 '22 03:11

J3RN


find_button('save')[:disabled].should eq "disabled"

Note that one line will effectively test for both existence and disabled state.

Edit: for enabled, try

find_button('save')[:disabled].should_not be

(Either of these tests may need to be tweaked depending on precisely how you disable/enable the button.)

like image 33
gregates Avatar answered Nov 19 '22 04:11

gregates


There is be_disabled check

it "allows finding elements and checking if they are disabled" do
  expect(string.find('//form/input[@name="bleh"]')).to be_disabled
  expect(string.find('//form/input[@name="meh"]')).not_to be_disabled
end

https://github.com/jnicklas/capybara/blob/2a51b817b355f6c1a5e95a471a87f1a492562e55/spec/basic_node_spec.rb#L108

like image 4
Piotr Kędziak Avatar answered Nov 19 '22 03:11

Piotr Kędziak


There are many ways to do this. I think the best way is to just use css selectors

expect(page).to have_css("#save:enabled")

This example asumes that you have set the css id to save.

like image 3
Thomas Avatar answered Nov 19 '22 04:11

Thomas


with minitest:

assert find('input[name=username]').disabled?
like image 1
Dorian Avatar answered Nov 19 '22 02:11

Dorian