Rspec/Capybara: How to "expect to see Routing Error"? - ruby-on-rails

How do I tell RSpec/Capybara to expect a RoutingError? The reason is I want users to click a link to "claim a plate" via PUT, not via GET/visiting the path.
Basically I want to expect ActionController::RoutingError: No route matches [GET] "/plates/claim/1".
scenario 'they have to click the claim link' do
create_plates
sign_in_as_doctor
visit claim_plate_path(#plates.first.id)
?????
end

Try this
scenario 'they have to click the claim link' do
create_plates
sign_in_as_doctor
expect{visit claim_plate_path(#plates.first.id)}.to raise_error( ActionController::RoutingError)
end

Accepted answer didn't work for me. What I had to do is:
create_plates
sign_in_as_doctor
expect do
visit claim_plate_path(#plates.first.id)
expect(page).to have_content("make sure visit is completed")
end.to raise_error(ActionController::RoutingError)

Related

How do I confirm a css element attribute with Capybara?

This may seem unusually basic but how do I confirm the presence of a pop up confirmation?
<a data-confirm="delete this video?" rel="nofollow" data-method="delete" href="/videos/21">Delete</a>
<a is the "tag"/"element" and data-confirm is an attribute. I want to test for the existence of the "data-confirm" attribute within the <a> element/tag
I have tried
expect(page).to have_css("a.data-confirm.delete this video?")
from
capybara assert attributes of an element
but no joy.
Edit:
I've tried the expectation from Arup's comment below
expect(page).to have_content "Content"
click_link "Delete"
expect(page).to have_css('a[data-confirm="delete this video?"]')
But it raises the following (same) error
Failures:
1) Visiting the video index page should search and save movies
Failure/Error: expect(page).to have_css('a[data-confirm="delete this video?"]')
expected #has_css?("a[data-confirm=\"delete this video?\"]") to return true, got false
but the page source shows it there and it is clearly working for the user
Any assistance would be very appreciated
You can write this expectation as:
expect(page).to have_css('a[data-confirm="delete this video?"]')
The answer by Arup is correct for the title of the question (and as he stated in the comments it's just valid CSS - https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors), however it's not actually testing the more detailed part of the question "how do I confirm the presence of a pop up confirmation". All it is doing is confirming the correct data attribute is on the link element to trigger the rails provided JS that should show a confirm.
If you wanted to actually test the confirm box is shown you would need to swap to using a JS capable driver - https://github.com/teamcapybara/capybara/tree/2.17_stable#drivers - and then use something like the following in your test
expect(page).to have_content "Content"
accept_confirm "delete this video?" do
click_link "Delete" # The action that will make the system modal confirm box appear
end
See - http://www.rubydoc.info/gems/capybara/Capybara/Session#accept_confirm-instance_method

Testing ruby with rails, Element not found

I get the error:
Capybara::ElementNotFound:
Unable to find field "user_email"
And this is the test code:
feature 'User' do
given!(:user) { User.new(email: 'testuserid#example.com', encrypted_password: 'test') }
scenario 'opens sign_up page' do
visit new_user_session_path
expect(page).to have_content 'unique text on the page'
end
scenario 'signs in with invalid email' do
visit new_user_session_path
fill_in('user_email',with: 'ssd')
expect(page).to have_content 'unique text on the page'
end
end
My HTML file consists of this code literally:
unique text on the page
<br>
<input type="text" id="user_email">
So this proves that the path is correct because my first scenario runs correctly. It is visiting the right page. But still I get this error for second scenario in fill_in.
I have also tried element = page.find("user_email"), it gives same error.
What am I possibly doing wrong?
I have been scratching my head like hell.
Usually the reason for this is that the input isn't actually visible on the page. You can verify this by doing
fill_in('user_email', with: 'ssd', visible: false)
If that succeeds in finding the element, then you need to change your test to first perform whatever actions make the field visible before attempting to fill it in.
Your code seems right. Maybe you are visiting wrong url or you have used user_email id once more. But you can give a try with alternative syntax like following :
find("input[id$='user_email']").set "ssd"

Best practice for testing capybara visit page

So I was wondering what the best way is to go about testing that a page was actually visited using capybara
describe "Pages" do
subject { page }
describe "Home page" do
it "should have the title 'My Home Page'" do
visit root_path
expect(page).to have_title('My Home Page')
end
end
end
Now it seems like the standard way to test this is to compare the title of the page (as above). This doesn't seem super robust though, as if the page title changes, it will break any tests that reference this.
Is this the standard practice? or is there another way to test it.
Thanks,
Matt
I don't think that the example you gave is the standard way to test that a page is visited. It is the standard way to see if the page's title match what you expect =P
If you want to make an assertion about the path in capybara, a much more reliable way to do it is using current_path. So, you can rewrite your example as follows:
describe "Pages" do
describe "Home page" do
it "will visit root_path" do
visit root_path
expect(current_path).to eql root_path
end
end
end
Notice that this is not a much valuable test though. We all know that capybara is well tested and that it will visit root_path if we tell it to do so. Anyways, if you want to make a sanity check or something, this is the right way to go.
I hope it helps !

Capybara can't click link, response contains shows the link

I'm trying to write a test that clicks a link but when I run the test, Capybara returns the following error:
"no link with title, id or text 'New Mwod post' found
so I put a 'debugger' and printed the response. The body contained the following:
New Mwod post
the test has the following code:
describe "GET /mwod_posts/new" do
it "creates a new mwod post" do
FactoryGirl.create(:mwod_tag)
get mwod_posts_path
debugger
response.status.should be(200)
click_link "New Mwod post"
end
end
Any ideas why capybara can't click the link?
The problem is that you're using get when you should be using visit.
Switch:
get mwod_posts_path
to:
visit mwod_posts_path
That will let you click links with click_link etc. To parse the response, you'll need to change:
response.status.should be(200)
to:
page.response_code.should be(200)
I haven't actually confirmed that this works, but discussion elsewhere would seem to indicate you can check response codes this way from page. Although, as noted in that discussion, this is not something you should really be doing in integration tests.
For more see on the difference between get and visit see this answer and this post. (This is a common point of confusion.).

Capybara + Webkit: How to test client side validations - "required" input elements?

Using Rspec and Capybara, I'm trying to test a failing validation for a form, where a "required" input is not filled in, so it fails. New navigators understanding HTML5 provide built-in validations, and I understand Capybara is using that as well. Before, I was using
page.should have_error
which doesn't work for me anymore.
Someone knows how to test this now?
Many thanks!
David
HTML5 client side validations are tricky to find. I found this post with a great answer.
The code is:
describe "when I leave required field empty" do
it "I get an the correct html5 validation error" do
#Leave the field empty
click_on "Save" # or whichever button triggers the submit
message = page.find("#field_id_attr").native.attribute("validationMessage")
expect(message).to eq "Please fill out this field."
end
end
Basically the way it works is that the field element has an attribute called "validationMessage" and the process is:
Click submit - this triggers the error message
Get a reference to the native(html) attribute(as opposed to the Capybara page object attribute) called "validationMessage". This will give you the value or the message itself.
Assert that the value is as expected.
I am not familiar with RSpec so I am not sure about what does have_error.
You should think about what you want to test exactly.
You surely don't want to test the exact behavior (what message is displayed, and how) as it is specific to each browser. What you want to test, because this is not specific to the browser, is the fact that the form is not submitted.
For instance, for a basic html form at root, with a required radio button "My value".
# Check form can not be submitted without the radio button
visit '/'
click_button 'Submit'
assert_equal '/', current_path
# Check form can be submitted with the radio button
visit '/'
choose 'My value'
click_button 'Submit'
assert_equal '/next', current_path
You should also consider to test only the presence of required in your html code, as the browser is supposed to work as expected (test only your code, not other's code)
If there is an error message, you can something along the lines of
page.should have_content("error")
This depends on how you handle the errors, and whether you use javascript or not.
This is an old post, however I will try to answer it
have_error is a method provided by webkit, to check e.g. if ajax requests or javascript in general running fine
I use to test my validations in my model specs:
describe 'validations' do
it { is_expected.to validate_presence_of :competitor_name }
it { is_expected.to validate_presence_of :chassi }
it { is_expected.to validate_presence_of :auction }
it { is_expected.to validate_presence_of :car_template_id }
end
or like
expect(FactoryGirl.create(:customer)).to be_valid
to check if my Factory is valid.
If you need to check your notices by targeting invalid inputs, you could test the html of your notice by capybara with the following:
it 'searches for specific order_car by chassi and model' do
visit order_cars_search_detailed_path
fill_in 'order_car_chassi', with: '123456'
select 'Octavia', from: 'order_car_car_template_car_template_id'
click_button 'Search Order'
expect(page).to have_content('THIS IS MY NOTICE')
expect(page).to have_content('123456')
end
Hope I could help some others running into this question.

Resources