capybara and click_on method + simple_form [javascript error] - ruby-on-rails

I'm using minitest, capybara and poltergeist and this is the simple_form to test:
<%= simple_form_for :search, url: ads_path , wrapper: :inline_form, html: {class: 'form-inline'}, :method => :get do |f| %>
<%= f.error_notification %>
<%= f.input :type_id, collection: #types, label_html: {class: 'form_home'}, selected: 'house'%>
<%= f.input :city, label: 'Where?', placeholder: 'What is the city ?'%>
<br>
<br>
<%= f.submit "Search", :class => "btn btn-primary btn-xl page-scroll" %>
<% end %>
The problem relies when I add the click_on 'Search'
test "search correctly" do
visit "/"
select "house", :from => "search_type_id"
fill_in 'search_city' , with: ""
click_on 'Search'
end
The javascrip error on the terminal:
Capybara::Poltergeist::JavascriptError:
Capybara::Poltergeist::JavascriptError: One or more errors were raised
in the Javascript code on the page. If you don't care about these
errors, you can ignore them by setting js_errors: false in your
Poltergeist configuration (see documentation for details).
Error: Bounds are not valid.
Error: Bounds are not valid.
at http://127.0.0.1:43411/assets/application-1442915127e4fa1072f69aa9aa4d07ce85cdc5115df9b3a40da528ee05ebfe94.js:43537
at http://127.0.0.1:43411/ads?utf8=%E2%9C%93&search%5Btype_id%5D=1&search%5Bcity%5D=&commit=Search:135
test/integration/home_test.rb:16:in `block in <class:HomeTest>'
Is there other alternative ?

You have two options, fix your JS or disable JS error reporting as mentioned in the error message.
To fix your JS either start by looking at the combined JS line 43537 to see why it's logging "Bounds are not valid" or do the same behavior in dev mode to figure out which individual JS file is producing the error and start debugging from there.
If on the other hand you don't care about fixing the cause of the error (you should care about it though) then you can configure your driver to not report JS errors with
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, js_errors: false)
end
as mentioned in the Poltergeist readme - https://github.com/teampoltergeist/poltergeist#customization

Related

How to check a check box in Capybara test when using simple_form

Trying to test some functionality in a simple page and I am getting this error when using page.check:
Failures:
1) searching for stores serving a taco and a sauce: Adobada tacos with Chile de Arbol sauce
Failure/Error: page.check 'Adobada'
Capybara::ElementNotFound:
Unable to find checkbox "Adobada"
# ./spec/views/store_search_spec.rb:8:in `block (2 levels) in <top (required)>'
Here is my HTML:
<%= simple_form_for :stores, url: stores_path, method: :get do |f| %>
<%= f.label :tacos, 'Select Tacos to Find: ', class: 'label' %>
<div class='taco-select checkboxes'>
<%= f.collection_check_boxes :tacos, Taco.order(:name), :id, :name,
:include_hidden => false, :item_wrapper_class => 'checkbox_container' %>
</div>
<%= f.label :salsa, 'Select Sauces to Find: ', class: 'label' %>
<div class='salsa-select checkboxes'>
<%= f.collection_check_boxes :salsas, Salsa.order(:name), :id, :name,
:include_hidden => false, :item_wrapper_class => 'checkbox_container' %>
</div>
<%= f.submit 'Search!' %>
<% end %>
And this is my test:
require 'rails_helper'
feature 'searching for stores', %(serving a taco and a sauce:) do
scenario 'Adobada tacos with Chile de Arbol sauce' do
visit root_path
page.check 'Adobada'
page.check 'Chile de Arbol'
click_button 'Search!'
expect(page).to have_content "Store"
expect(page).to have_content 'City'
end
end
I would like to test that when some checkboxes are set to true a certain content is rendered in the page.
Don't know how to fix this.
Try with these, they should work for you:
find(:css, "#YOUR_CHECKBOX_ID").set(true)
or
page.check('YOUR_CHECKBOX_ID')
or simply
find('THE CSS SELECTOR OF YOUR CHECKBOX').click
find(:xpath, 'THE XPATH OF YOUR CHECKBOX').click
You don't have to use an ID to check a checkbox. You can just use the label on the checkbox. Say you have a checkbox like this
<label for="...">
<input type="checkbox" name="...">Something</label>
You 'check' it in capybara like so
it "" do
page.check 'Something'
end
Official docs on this can be found here

No route matches [POST] "/" only in testing

Using Simple Form For, I have created a custom auth system.
routes.rb
get '/users/sign_in' => 'sessions#new', as: :sessions_new_user
post '/users/sign_in' => 'sessions#create', as: :sessions_create_user
match '/users/sign_out' => 'sessions#destroy', as: :sessions_destroy_user, via: :delete
get '/users/process_login' => 'sessions#process_login', as: :sessions_process_login
new.html.erb
<%= simple_form_for :user do |f| %>
<%= f.input :login, placeholder: "Login", label_html: { class: 'form-control' }%>
<%= f.input :password, label_html: { class: 'form-control' } %>
<%= f.submit "Log in", class: 'btn btn-lg btn-primary btn-block' %>
<% end %>
This issue is when i run the tests to simulate a sign in, I get this error.
user visits root of application
Failure/Error: click_on 'Log in'
ActionController::RoutingError:
No route matches [POST] "/"
user_spec.rb
scenario 'user visits root of application' do
visit root_path
expect(page).to have_content("Sign in to continue")
fill_in ' Login', with: ENV['NTUSERNAME']
fill_in ' Password', with: ENV['NTPASSWORD']
click_on 'Log in'
end
This works fine in development. I cant figure it out.
Firstly, if you are learning Rails I'd recommend you start out with the simple form helpers, as you can more clearly define what you're looking for. Since you are not using RESTful routes, you'll have to define everything by hand and are really missing out on Rails's approach of convention over configuration.
However, if you really want to make Simple Form work, here's how you would do it:
<%= simple_form_for :user, url: sessions_create_user, method: :post do |f| %>
<%= f.input :login, placeholder: "Login", label_html: { class: 'form-control' }%>
<%= f.input :password, label_html: { class: 'form-control' } %>
<%= f.submit "Log in", class: 'btn btn-lg btn-primary btn-block' %>
<% end %>
Also be aware that since you are not using an ActiveRecord-backed object (just a label), you'll have to be careful to match your expected params to what Simple Form is sending in. I'm also curious as to how you have SF render out the correct action path for a user session in development without specifying it out...
because simple_form_for don't have url, it will use the current url to submit data
Not tested but I think as below:
In development, when you visit root, it will redirect to /users/sign_in, posting to /users/sign_in is acceptable
In rspec, redirecting not change the current url, it still root_path, so posting to / is invalid
Nested forms are not allowed...
I had accidentally nested a form tag with an action of "#". It all worked in development as the browser spotted it was a nested form, and it was ignoring the tag. But when I ran a rack test it failed with No route matches [POST] “/” - it also did work when I used JS/selenium test as it was being run in a real browser.
<%= simple_form_for #user do |f| %>
<form action="#" method="POST">
<%= f.input :login %>
<%= f.input :password %>
<%= f.submit "Log in" %>
</form>
<% end %>

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

Why is the semantic_nested_form_for method missing in my production environment?

I'm trying to switch a site to use the nested_form gem in combination with formtastic, which I'm already using, but I'm getting a strange error. Everything works perfectly fine in development, and tests pass. This error only occurs in production.
Visiting the page where semantic_nested_form_for is used causes the following error:
ActionView::Template::Error (undefined method `semantic_nested_form_for' for #<#<Class:0x0000000524cca0>:0x00000004e46a70>):
1: <%= semantic_nested_form_for(#volume) do |f| %>
2: <%= f.inputs do %>
3: <%= f.input :number, :label => 'Volume #', :input_html => {:style => 'width:100px;', :autofocus => true}, :hint => raw('Choose the volume number.') %>
4: <% end %>
app/views/volumes/_form.html.erb:1:in `_app_views_volumes__form_html_erb__2632693694855646779_43838320'
app/views/volumes/new.html.erb:3:in `_app_views_volumes_new_html_erb___2327298489284463705_41053660'
The gem is in my Gemfile and seems to be installed correctly:
[~/application/current]$ bundle show nested_form
/home/deployer/application/shared/bundle/ruby/1.9.1/gems/nested_form-0.3.1
I can even successfully call the semantic_nested_form_for in the production console:
[~/application/current]$ rails c production
Loading production environment (Rails 3.2.12)
irb(main):001:0> helper.semantic_nested_form_for(Volume.new, url: '/volumes' do |f|
irb(main):002:2* f.inputs
irb(main):003:2> f.actions
irb(main):004:2> end
irb(main):005:1>
Additionally, semantic_form_for works fine by itself, but nested_form_for (without the semantic_ part) does NOT work, leading me to think this is related directly to nested_form.
I don't think the erb code is really relevant to this issue, but here it is anyway:
<%= semantic_nested_form_for(#volume) do |f| %>
<%= f.inputs do %>
<%= f.input :number, label: 'Volume #', input_html: {autofocus: true}, hint: 'Choose the volume number.' %>
<% end %>
<div id="issues_fields">
<%= f.semantic_fields_for :issues %>
<%= f.link_to_add 'Add an Issue', :issues %>
</div>
<%= f.actions do %>
<%= f.action :submit, label: 'Save' %>
<% end %>
<% end %>
Well I'm a little dumbfounded. Capistrano restarts unicorn when I deploy, and before I asked this question I had tried manually restarting nginx and unicorn just to rule that out. After I asked the question I rebooted the entire production server (which I hate doing) just to see, and now it's working fine.
If anyone can tell me a good reason why simply rebooting the unicorn process wasn't enough, I'll mark their answer as the accepted answer.

Change rails text_field form builder type

I've been looking at the new options available in HTML5 forms, such as declaring input types as "email", "url", and "number", as described here.
How can I use these in conjunction with the rails form builders? I have tried
<% form_for #user do |f| %>
<%= f.email :email, {:placeholder => 'user#domain.com'} %>
<% end %>
But that does not work. I've also tried
<% form_for #user do |f| %>
<%= f.text_field :email, {:placeholder => 'user#domain.com', :type => :email} %>
<% end %>
But the type is still "text" and not overridden. Is it possible, or is this something that will need to be addressed in Rails itself?
Looks like there is currently an open ticket and patch for adding the HTML5 form input types. If you can't wait until the patch is accepted, you could apply the patch locally by freezing the actionpack gems and applying the patch or making an initializer that add the extra methods.
Of course the other option is adding the fields manually without a form helper:
<% form_for #user do |f| %>
<%= tag(:input, {:type => :email, :value => f.object.email} %>
<% end %>
There is now an email_field tag.

Resources