RSpec does not recognise my internationalised labels - ruby-on-rails

In my Rails 4 application I have specified my locales as follows:
config/locales/views/show_user/en.yml
with content:
en:
activerecord:
attributes:
user:
first_name: First name
last_name: Last name
...
layouts:
header:
home: "Home"
help: "Help"
...
footer:
about: "About"
contact: "Contact"
users:
new:
signup: "Sign up!"
create_my_account: "Create my account"
When I run my application in my localhost, all my labels display correctly. However, my RSpec test,
describe "with valid information" do
before do
fill_in "First name", with: "Jenny"
fill_in "Last name", with: "Johnson"
fails when I make the following change to my partial, /views/users/_fields.html.erb
<%= f.label t :first_name, scope: [:activerecord, :attributes, :user] %>
<% # f.label :first_name %>
<%= f.text_field :first_name %>
<%= f.label :last_name %>
<%= f.text_field :last_name %>
My RSpec test displays this failure:
1) User pages signup with valid information should create a user
Failure/Error: fill_in "First name", with: "Jenny"
Capybara::ElementNotFound:
Unable to find field "First name"
# ./spec/requests/user_pages_spec.rb:88:in `block (4 levels) in <top (required)>'
I have noticed that the generated html of my form displays a different id for first_name, but I do not know if this is important:
<label for="user_First name">First name</label>
<input id="user_first_name" name="user[first_name]" type="text" />
<label for="user_last_name">Last name</label>
<input id="user_last_name" name="user[last_name]" type="text" />
My question is therefore: Why can Capybara not find my label, :first_name, while my page displays correctly in my browser?

It is important. Capybara uses the locator argument to fill_in in one several ways:
if there is a text field (or similar input) with that id then it will use that field
if there is a label that contains the text, then it will use the field that label for.
You're in the second case, so capybara uses the for attribute on the label to find the text field. This doesn't work because the label's for is user_First name but the id on the text field is user_first_name.
By default rails derives both the label text and the for attribute of the label from the value you pass as the first argument, so you should pass the attribute name as the first argument and then the human readable translation as the second argument
f.label :first_name, t(:first_name, scope: [:activerecord, :attributes, :user])
My reading of the documentation is that looking for this transaction would actually be the default - you may not need to specify it at all.

Related

Rails system tests fail when I manually name a label

In a form, I manually named a label:
<%= f.label :name, "DEA License Number" %>
<%= f.text_field :dea_license_number, class: 'form-control' %>
The HTML looks like this:
<label for="dentist_detail_name">DEA License Number</label>
<input class="form-control" type="text" name="dentist_detail[dea_license_number]" id="dentist_detail_dea_license_number" />
And my system test:
fill_in "DEA License Number", with: "999999"
When I run the tests, I get this:
Error:
SignUpJobSeekersTest#test_Sign_Up_Job_Seekers:
Capybara::ElementNotFound: Unable to find visible field "DEA License Number" that is not disabled
I'm at a bit of a loss. Thanks for supporting a newbie.
When you look at the generated HTML the for attribute of the label element doesn't match the id attribute of the input
'dentist_detail_name' != 'dentist_detail_dea_license_number'
therefore the label is not actually associated with the input (label must either wrap the input or for must match id).
I think there is something wrong with your label. It should be
<%= f.label :dea_license_number, "DEA License Number" %>
Give that a try?

Capybara fill_in multiple input fields

Below is my form, you can see that there will be many rows of inputs fields all with the same classes:
<%= q.simple_fields_for :choices do |c|%>
<div class="row-fluid choice-row">
<%= c.text_field :sort_order, class: 'span1' %>
<%= c.text_field :title, class: 'span9' %>
<%= c.link_to_remove 'Remove', class: 'btn btn-danger span2 pull-right' %>
</div>
<% end %>
For my tests I'm trying:
fill_in(:sort_order, with: '3')
fill_in(:title, with: 'Choice 3')
I've also tried:
fill_in('Sort Order', with: '3')
fill_in('Title', with: 'Choice 3')
And:
fill_in('Sort Order', :with => '3')
fill_in('Title', :with => 'Choice 3')
The error I get is:
Failure/Error: fill_in(:title, with: 'Choice 3')
Capybara::ElementNotFound:
cannot fill in, no text field, text area or password field with id, name, or label 'title' found
Can someone please recommend how I can fill a specific input, like say the third row?
You'll find in your markup that fields output by a form-helper are namespaced within the object passed to fields_for, this indeed the entire point of using fields_for.
In this case, your form elements will have names like choices[title] and choices[sort_order].
To find and fill_in the correct field when selecting by name yields many fields, you need to get more creative, because this is not a very typical setup:
You can use within to select a unique parent element
You can use CSS selectors to find the nth element
You can find all elements and use [2] on the returned array to access the 3rd element

Capybara Conundrum, field cannot be found

I'm perplexed about an error message that I am receiving from my feature spec regarding a missing capybara element.
I have a simple form in my new.html.erb as shown below:
<h1>Register a Building</h1>
<h4 class="notice"></h4>
<%= simple_form_for #building do |f| %>
<%= f.input :street_address %>
<%= f.input :city %>
<%= f.input :state, collection: Building::STATES %>
<%= f.input :postal_code %>
<%= f.input :description %>
<%= f.button :submit %>
<% end %>
My feature_spec is testing for the registration of a new building with the required fields as shown below:
scenario 'I want to submit a valid building to record' do
building_count = Building.count
visit new_building_path
fill_in 'Street address', with: '5555 Summer Drive'
fill_in 'City', with: 'Boston'
fill_in ' State', with: 'WA'
fill_in 'Postal code', with: '78526'
fill_in 'Description', with: ''
click_on 'Create Building'
expect(page).to have_content('Building Submitted')
expect(page).to have_content('')
expect(Building.count).to eql(building_count + 1)
end
Everything is fine up until it reaches the state field. I keep getting an element not found error, but when I do a save and open page it is CLEARLY there.
Here is my error:
Failure/Error: fill_in 'State', with: 'WA'
Capybara::ElementNotFound:
Unable to find field "State"
I've noticed the double/single quotes in the error message but when I match the quotes and change them nothing happens. Also, I've inspected my element and I get that the title is this " State". I've changed my test to look for " State" not "State" but still to no avail. What can I do to fix or get around this?
Your State field is a select box not a text field.
Use:
select 'WA', from: 'State'
fill_in specifically looks for the field as fillable, i.e. text fields and text areas.
The Capybara docmentation about this is here: http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions

Capybara error when trying to fill a text_field_tag

In my application a user can search for a zipcode which gives back its corresponding street name and city. The zipcode is written in a <%= text_field_tag %> while the street name and city would be put into a div.
Now I have changed it that the street name would also be rendered into a <%= text_field_tag %> but my spec is now failing.
The code below is a working test where the streetname and city would be put into a div.
it 'submits the zipcode and house number', js: true do
fill_in 'zipcode', with: '1111AA'
fill_in 'house_number', with: 1
click_button('Search')
within('#street_name') do
page.should have_content 'Street X'
end
within('#city') do
page.should have_content 'Town X'
end
end
My divs:
<div id="street_name"><%= street_name %></div>
<div id="city"><%= city %></div>
My text field tags:
<%= text_field_tag 'street_name', street_name, placeholder: 'Straatnaam', id: 'street_name' %>
<%= text_field_tag 'city', city, placeholder: 'Woonplaats', id: 'city' %>
How should I write my spec so it checks that the streetname and city are in a <%= text_field_tag %> instead of a div?
I'm pretty sure that you can find your text field and make an assertion about it's value with the following code:
find_field("street_name").value.should eq 'Street X'
Make sure, though, that the id is unique across the layout, otherwise you can run into some nasty ambiguity failures.
I hope that helps !

Fill in a field without label

I have a text field like this :
<%= form_for(ownership, remote: true) do |f| %>
<div>
<%= f.text_field :confirm, value: nil, title: t('label.transaction.confirmation.code') %>
<%= f.hidden_field :start_date, value: Time.now %>
</div>
<%= f.submit t('button.ownership.take.confirmation'), class: "btn btn-small"%>
<% end %>
And I want to fill in the text field with rspec :
fill_in t('label.transaction.confirmation.code'), with: "something"
But it doesn't work because the rspec don't recognize the title tag in order to fill in the text field :
Failure/Error: fill_in t('label.transaction.confirmation.code'), with: confirmation_code
Capybara::ElementNotFound:
Unable to find field "Code de confirmation"
Do you know a way to fill in the text field with rspec without adding a label ?
the fill_in method's first argument must be a css selection. for example: #id, li, .class.
So you can change t('label.transaction.confirmation.code')
to the text field id or [title='#{t('label.transaction.confirmation.code')}']
e.g.
<input id="conf_code">
fill_in 'conf_code', with: 'something'

Resources