Rails capybara,fill_in failing - ruby-on-rails

I have next spec:
click_link('Edit')
expect(current_path).to eq(edit_news_path(#news))
fill_in('Body', with: 'Changed body')
click_button('Edit')
expect(current_path).to eq(admin_path)
expect(#news.body).to eq('Changed body')
All expectings are passing the test, but not fill_in expecting:
Failure/Error: expect(#news.body).to eq('Changed body')
expected: "Changed body"
got: "Example"
(compared using ==)
And its all ok on site,every editings both saved,so whats the problem in rspecs?

That usually means capybara can't find the field you mean.
A couple of things you might check: is the label Body linked to the input field via ? Is there only one field with a label "Body"? You might also try using the id for the field in the fill_in call, like
fill_in("content_body", with...

I think that your click_button('edit') seems to have problem. I think that you are not saving the body, you must be having click_button('save')
Use binding.pry in between the test statements to check the value of various objects.

Related

How to keep en.yml DRY?

I have a en.yml which contains the following
en:
article:
title:
format: "Requires at least one alphanumeric character"
title_format: "Title Requires at least one alphanumeric character"
The article.title.format is used in my article model and article.title_format is used in article_test test. Is there any way to make this DRY?
YAML is limited for things like this, but you do have anchors, aliases and merge_keys. This SO answer is VERY exhaustive on this issue.
So, you can repeat the exact same message, but not modify that message without some other library or code injection:
&standard_answer: "Requires at least one alphanumeric character"
en:
article:
title:
format: *standard_answer
title_format: *standard_answer
in Ruby, is equivalent to:
en:
article:
title:
format: "Requires at least one alphanumeric character"
title_format: "Requires at least one alphanumeric character"
To answer the question you aren't asking...
If you are trying to test model validations, I think you're doing too much anyway:
These will break if Rails decides to tweak the language used
Your tests now rely on your i18n file just to find a hard-coded string
It's less readable because the test constraints are now in 2 separate files (but it is more compact, so you could argue that)
What you want to know is: "Can I save this record without any alphanumeric characters in the title?"
I would only test whether the validation succeeds or fails.
If you're using RSpec, I like this pattern.
Or, another option, RSpec Expectations ships with Predicate matchers:
# prove the record is valid
expect(record).to be_valid
# make the record invalid in only 1 way
record.title = 'does not have a number'
expect(record).to be_invalid # also works: expect(record).not_to be_valid
Note that I'm making sure the record is valid first, then changing one thing, then checking for validity again. This helps ensure you are testing the right validation.

Why does RSpec/Capybara throw an error with hyphenated values provided with public_send?

I have a shared example I am using to test the same thing on several controllers. I pass the controller the model and a list of fields to check to make sure they are on the page, but when the value is a hyphenated string it throws an error, even when the value is on the page. The strange thing is, though, that it drops the hyphen in the check. So, if the last name field in the user table has "Johnson-Smith" This is what I get back...
expected to find text matching "Johnson Smith" in...
And looking down in the page text it renders I can clearly see "Johnson-Smith". I don't understand why Rspec/Capybara aren't checking for the correct value. Here is the shared example code..
RSpec.shared_examples 'renders proper fields' do |klass, fields|
it 'should render the expected text' do
model_object = klass.order(:created_at).last
fields&.each do |field|
expect(page).to have_text(model_object.public_send(field))
end
end
end
EDIT I tested the results for every public_send(field) that is evaluated and it turns out that public_send is returning the field from the database as expected. So the issue is, for some reason, Capybara is evaluating it without the hyphen, even though it passed the text with the hyphen.

How can I test (Minitest) that a (Rails) view contains a <td> element with a certain text?

When I simply use
assert_select td, "test"
it seems that it expects the first of the found td-elements to have the value test.
So I tried to first select all of them in an array, and then assume that the array
contains the expected value:
assert_select 'td' do |elements|
assert elements.include?("test")
end
But this also doesn't work for me, as it is always green. I am not really sure which parts of Rails and Ruby are available in the test so this last idea was just a shot in the dark.
Try this
assert_select 'td', /test/
it seems your td in not contains test only. // will work because it will match rather then comparing exact values.

How do the Capybara set and fill_in differ?

Recently I found that elements found using 'find' of capybara may not work properly with 'fill_in'( Refer:Capybara can find but not fill_in)
So the params used by fill_in and find are different. Hence I can use set and fill my form fields found using 'find' is what I have observed.
Is there any other difference?
In terms of actually inputting the field, set and fill_in are exactly the same.
The method definition for fill_in is:
def fill_in(locator, options={})
raise "Must pass a hash containing 'with'" if not options.is_a?(Hash) or not options.has_key?(:with)
with = options.delete(:with)
fill_options = options.delete(:fill_options)
find(:fillable_field, locator, options).set(with, fill_options)
end
As you can see on the last line, the fill_in method is doing the same thing - ie using find to get the node and then inputting it with set.

Is it the right way to output more information about tests that are going to be run?

I am using Ruby on Rails 3.2.2 and rspec-rails-2.8.1. I would like to output more information about tests that are going to be run, for example, this way:
# file_name.html.erb
...
# General idea
expected_value = ...
it "... #{expected_value}" do
...
end
# Usage that I am trying to implement
expected_page_title =
I18n.translate(
'page_title_html'
:user => #user.firstname
)
it "displays the #{expected_page_title} page title" do
view.content_for(:page_title).should have_content(expected_page_title)
end
Note: "Outputs" are intended to be those that are output when you run the rspec . --format documentation command line in the Terminal window.
Is it a right way to test?
Related questions:
How to use an instance variable throughout an Example Group, even if it is outside a Example?
Your question is going to solicit some opinions, but I'll try and justify mine with some examples.
Short answer: No, this isn't how you should be writing RSpec (or any test) descriptions. It's unconventional and doesn't add much value for the extra code.
Long answer: RSpec is a BDD (behavior driven development) tool that was designed to help describe the behavior and intent of your code at the same time as writing automated tests. When you think about the behavior of your code, does adding the expected result to the test description really add much value? If so, maybe you should rethink what you are testing.
For example, say you have a User class and you want to test a method that concatenates a user's first and last name:
describe User do
expected_full_name = 'Software Guy'
subject { User.new(first: 'Software', last: 'Guy') }
it 'should have the full name #{expected_full_name}' do
subject.full_name.should == 'Software Guy'
end
end
VS
describe User do
subject { User.new(first: 'Software', last: 'Guy') }
it 'should have a full name based on the first and last names' do
subject.full_name.should == 'Software Guy'
end
end
In the first test, what does having the expected result in the description really buy you? Does it tell you anything about the expected behavior of a user? Not really.
Take your example. If I was coming along to your project and saw a test description like that, I would be confused because it doesn't really tell me what is being tested. I would still need to look at the code to understand what is going on. Compare these two examples:
it "displays the #{expected_page_title} page title" do
view.content_for(:page_title).should have_content(expected_page_title)
end
Which would give you something in the console like:
"displays the My Awesome Title page title"
Compare that to:
it "should translate the page title" do
view.content_for(:page_title).should have_content(expected_page_title)
end
Which would be exactly the same in the console as it is in the test:
"should translate the page title"
Your obviously free to choose whichever one you want, but I am speaking from a few years of testing experience and highly recommend you don't do this.

Resources