Reputation: 6168
I'm using RSpec2 and Capybara for acceptance testing.
I would like to assert that link is disabled or not in Capybara. How can I do this?
Upvotes: 91
Views: 75176
Reputation: 14630
According to the docs you can use the [attribute] accessor syntax:
find('#selector')['class'] => "form-control text optional disabled"
For disabled, you could also do this:
expect(find('#selector').disabled?).to be(true)
Upvotes: 0
Reputation: 7097
Simply you can use page.has_css?
method
page.has_css?('.class_name')
this will return true
if element exists.
Do some action based on validation.
page.has_css?('.class_name') do
#some code
end
Upvotes: 1
Reputation: 99
Using Rspec3's syntax i did it this way:
expect(page).not_to have_selector(:link_or_button, 'Click here')
Upvotes: 0
Reputation: 19573
I recommend using have_link
and find_link(name)[:disabled]
in two separate assertions. While performing the second assertion alone is simpler, this makes error messages about missing links look nicer, making your test results easier to read.
expect(page).to have_link "Example"
expect(find_link("Example")[:disabled]).to be false
Note that "Example"
can be changed to the name or id of the link.
Upvotes: 4
Reputation: 12574
Another simple solution is to access the HTML attribute you are looking for with []
:
find('#my_element')['class']
# => "highlighted clearfix some_other_css_class"
find('a#my_element')['href']
# => "http://example.com
# or in general, find any attribute, even if it does not exist
find('a#my_element')['no_such_attribute']
# => ""
Note that Capybara
will automatically try to wait for asynchronous requests to finish, but it may not work in some cases:
Here is one workaround if you are having trouble with assertions on elements that are updated asynchronously:
Upvotes: 146
Reputation: 384414
Whenever possible, you should try to use the Capybara provided wrappers which will work more consistently across drivers.
For the particular case of disabled
, a wrapper was introduced in 2.1: https://github.com/jnicklas/capybara/blob/fc56557a5463b9d944207f2efa401faa5b49d9ef/History.md#version-210
If you use it, you will get sensible results on both RackTest and Poltergeist:
HTML:
<input type="text" id="disabled-false" ></div>
<input type="text" id="disabled-true" disabled></div>
<input type="text" id="disabled-js-true" ></div>
<input type="text" id="disabled-js-false" disabled></div>
<script>
document.getElementById('disabled-js-true').disabled = true
document.getElementById('disabled-js-false').disabled = false
</script>
Tests:
!all(:field, 'disabled-false', disabled: false).empty? or raise
all(:field, 'disabled-false', disabled: true ).empty? or raise
all(:field, 'disabled-true', disabled: false).empty? or raise
!all(:field, 'disabled-true', disabled: true ).empty? or raise
all(:field, 'disabled-js-true', disabled: true ).empty? or raise
all(:field, 'disabled-js-false', disabled: false).empty? or raise
Capybara.current_driver = :poltergeist
!all(:field, 'disabled-false', disabled: false).empty? or raise
all(:field, 'disabled-false', disabled: true ).empty? or raise
all(:field, 'disabled-true', disabled: false).empty? or raise
!all(:field, 'disabled-true', disabled: true ).empty? or raise
!all(:field, 'disabled-js-true', disabled: true ).empty? or raise
!all(:field, 'disabled-js-false', disabled: false).empty? or raise
Note how by using this instead of CSS selectors, the Javascript tests will work without any changes if you start using a Js capable driver.
Runnable test file here.
Upvotes: 1
Reputation: 552
bowsersenior, thanks for a hint
Another simple solution is to access the HTML attribute you are looking for with []
Here is an example:
let(:action_items) { page.find('div.action_items') }
it "action items displayed as buttons" do
action_items.all(:css, 'a').each do |ai|
expect(ai[:class]).to match(/btn/)
end
end
Upvotes: 0
Reputation: 107
page.should have_link('It will work this way!', {:href => '/clowns?ordered_by=clumsyness', :class => "smile"})
have_link expects a hash of options which is empty if you do not provide any. You can specify any attributes the link should have - just make sure you pass all the options in ONE hash.
Hope this helps
PS: For attributes like data-method you have to pass the attribute name as a string since the hyphen breaks the symbol.
Upvotes: 1
Reputation: 183
It was a bit messy to find out the correct xpath, here is the correct one,
using capybara 0.4.1.1
# <a href="/clowns?ordered_by=clumsyness" class="weep">View Clowns</a>
page.should have_xpath("//a[@class='weep'][@href='/clowns?ordered_by=clumsyness']", :text => "View Clowns")
If you only have a link without a class, use
page.should have_link('View Clowns', :href => '/clowns?ordered_by=clumsyness')
Something like this will sadly not work:
page.should have_link('This will not work!', :href => '/clowns?ordered_by=clumsyness', :class => "weep")
The class option will be ignored.
Upvotes: 4
Reputation: 32067
How are you disabling the link? Is it a class you're adding? An attribute?
# Check for a link that has a "disabled" class:
page.should have_css("a.my_link.disabled")
page.should have_xpath("//a[@class='disabled']")
# Check for a link that has a "disabled" attribute:
page.should have_css("a.my_link[disabled]")
page.should have_xpath("//a[@class='disabled' and @disabled='disabled']")
# Check that the element is visible
find("a.my_link").should be_visible
find(:xpath, "//a[@class='disabled']").should be_visible
The actual xpath selectors may be incorrect. I don't use xpath often!
Upvotes: 92