I'm trying to finish the exercises in the Mhartl RoR tutorial.
The question asks you to complete the following integration test
assert_not 'flash.FILLIN'
assert_select 'div#FILLIN'
assert_select 'div.FILLIN'
And I have a flash that shows either
{:success => "success message here"}
or upon error,
<% flash.each do |message_type, message| %>
taking the standard #user.errors.fullmessages.
My questions are:
How would I go about finding the list of #users.errors.fullmessages, and how do assert_not error?
assert_not 'flash.errors'
yields no exit:success... :(
any help appreciated, the link to the exercise is here: https://draft.railstutorial.org/book/sign_up#sec-signup_exercises
Turns out that it is
assert_not flash.nil?
and some helpful places to look: Check for array not empty: any?
:)
assert_not flash.empty?
Michael Hartl says "I prefer only to test that the flash isn’t empty" at
http://3rd-edition.railstutorial.org/book/sign_up#sec-signup_exercises
And he writes the same test at
http://3rd-edition.railstutorial.org/book/updating_and_deleting_users#code-successful_edit_test
To assert that there is no flash message of a particular type set (:error in this example), you can do:
assert_predicate flash[:error], :nil?
Related
I have the following:
test "should update deal" do
patch user_deal_url(#user, #deal), params: { deal: { name: #deal.name+'xxx' } }
# p #response.body
# p #deal.errors.full_messages
assert_select ".alert", false # should not have alert
assert_redirected_to dashboard_url
follow_redirect!
assert_select ".alert", "Deal was successfully updated."
end
It only says:
Failure:
DealsControllerTest#test_should_update_deal [C:/Users/Chloe/workspace/test/controllers/deals_controller_test.rb:73]:
Expected response to be a <3XX: redirect>, but was a <200: OK>
I thought I could print #deal.errors.full_messages but it's not the same #deal in the controller. I'm able to print the entire response body and copy it into Notepad++ and search for the error messages, but it's so tedious. I thought I can assert that .alert doesn't exist and it would tell me what it actually was. I added
assert_select "#error_explanation", false # should not have error
But that only told me that it exists, not why it failed.
Expected exactly 0 elements matching "#error_explanation", found 1..
Expected: 0
Actual: 1
So how do you quickly determine why a model is failing to save or update in a controller during testing?
Rails 5.0.2
Reference: http://guides.rubyonrails.org/testing.html
My solution causes subsequent assert_select statements to fail! Just having puts css_select('#error_explanation') makes the last assert_select fail, but commenting it out makes it succeed. Why?
I entered a Rails bug for that in the mean time: https://github.com/rails/rails/issues/29367
I was able to put
puts css_select('#error_explanation')
right after the put/patch and it prints
# Running:
<div id="error_explanation">
<h2>
2 errors
prohibited this deal from being saved:
</h2>
<ul>
<li>Size can't be blank</li>
<li>Size is not a number</li>
</ul>
</div>
F
Failure:
I'm still looking for something better as leaving this line in causes subsequent assert_selects to fail!
I have the following test:
test "users title when logged out" do
get users_path
assert_select "title", 'Correct title"
end
If we assume that users_path returns a page with <title>Wrong title</title>, then I get the following output:
FAIL["test_users_title_when_logged_out", SiteLayoutTest, 1.0830602300120518]
test_users_title_when_logged_out#SiteLayoutTest (1.08s)
Expected at least 1 element matching "title", found 0..
Expected 0 to be >= 1.
test/integration/site_layout_test.rb:37:in `block in <class:SiteLayoutTest>'
I would like to replace the assert_select with something like assert_equal "Correct title", page.title so that the test failure message actually shows me what the page's title is, which would make tracing the problem much easier! (Naturally, the page shows the correct title in development mode…)
However, page.title does not seem to be available, and my efforts at searching are only turning up stuff like "you can do it with Capybara", which is a bit bulky for this purpose!
Is there a way to write this test so that it shows something like Expected page title to be "Correct title" but got "Wrong title" instead? [Edit for clarity: "Wrong title" is the title in the returned page, not a literal string — that is, I need the error to tell me what was actually returned.]
It looks like the answer is assert_equal 'Correct title', css_select('title').first.content.
This gives the more helpful failure message
FAIL["test_users_title_when_logged_out", SiteLayoutTest, 1.0830602300120518]
test_users_title_when_logged_out#SiteLayoutTest (1.08s)
Expected: "Correct title"
Actual: "Wrong title"
(though I suspect it may be better style to revert to the original assert_select once I've found the problem!)
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"
I'm sure this is something easy but at the moment I can't tell what's wrong with one of my mailer tests.
I have this basic test that I am running.
test "email should be sent when a post is created" do
email = PostNotifier.post_creation_notification(#post)
assert_equal [#user.email], email.to
assert_equal "ohlohadmins#blackducksoftware.com", email[:from].value
assert_equal "Post successfully created", email.subject
assert_match /Hello #{#user.name}, your post has been successfully created for #{#post.topic.title}/, email.body.encoded
end
Here is my text.erb file:
Hello <%= #user.name =>, your post has been successfully created for <%= #post.topic.title =>.
This is the error I receive when I run my test:
As you can see my variables are not formatting. Why are they not formatting? I've been following Agile Web Development 4 as a reference and this setup I have is similar to what is in the book.
I've also tried to wrap the varaibles in the text.erb file in curly braces like so. "#{#user.name} etc. and it still doesn't work. This is annoying. Any ideas? Another set of eyes would be greatly appreciated. Thanks.
Please replace ur text.erb file with following.
Hello <%= #user.name %>, your post has been successfully created for <%= #post.topic.title %>.
i think this will help
I am writing cucumber tests for my RoR app and I need to test for a flash to appear:
<p class='flashnotice flash'>Message was successfully sent.</p>
However, I just can't find a solution that works. I've tried:
page.should have_selector('p', :class => 'flashnotice flash') do
page.should have_content fartknocker
end
But that returns an error on :class and says I can't use that. Can someone show me the right way to test for flash?
You can use this style instead
page.should have_css('.flashnotice', text: "Message was successfully sent")