Capybara::Element Not Found - capybara

I'm working along with the Rspec book as it develops a 'showtime' rails application, which provides information about films. As far as I can tell, I've copied the code exactly (the book's not that great at letting readers know every step to take), but I'm getting this error.
Unable to find select box "Release Year" (Capybara::ElementNotFound)
./features/step_definitions/movie_steps.rb:6:in `/^I create a movie Caddyshack in the Comedy genre$/'
My movie_steps.rb file has this code, which provides users a select box to select the release year, which is the element Capybara can't find.
#---
When /^I create a movie Caddyshack in the Comedy genre$/ do
visit movies_path
click_link "Add Movie"
fill_in "Title", :with => "Caddyshack"
select "1980", :from => "Release Year"
check "Comedy"
click_button "Save"
end
Then /^Caddyshack should be in the Comedy genre$/ do
visit genres_path
click_link "Comedy"
response.should contain("1 movie")
response.should contain("Caddyshack")
end
In the movies view, I have this code, which is, as far as I can tell, all i need to implement the select box.
<%= form_for #movie do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :release_year %>
<%= f.select :release_year, (1900..2009).to_a.map(&:to_s) %>
<% #genres.each do |genre| %>
<label>
<%=h genre.name %>
<%= check_box_tag "genres[]", genre.id %>
</label>
<% end %>
<%= f.submit "Save" %>
<% end %>
I'd be grateful for any suggestions you could provide.

Try select "1980", :from => "Release year" instead. If you want it to display as "Release Year", then change your label to show as follows:
f.label :release_year, "Release Year"
Rails automatically formats the label for you using the humanize method, but you can change it to anything you like.

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

Uncheck check_box only not working with rspec / capybara tests

I have a nested form that has 4 checkboxes. Currently, everything is working in browser, but I can't get the capybara tests to uncheck the checkbox and save.
Using Rails 4.2.2 and latest versions of capaybara-webkit and rspec
settings.html.erb
<%= f.fields_for :preferences do |f| %>
<div class="email-notifications-holder">
<div class="email-holder">
<%= f.label :new_match, "Getting a new match each week" %>
<%= f.check_box :new_match, class: "checkbox new_match_email" %>
</div>
<div class="email-holder">
<%= f.label :match_reminder, "New matches Thursday reminder", class: "match_reminder_email" %>
<%= f.check_box :match_reminder, default: true, class: "checkbox" %>
</div>
<div class="email-holder">
<%= f.label :accepted_match, "A Glassbreakers accepted a match", class: "accepted_match_email" %>
<%= f.check_box :accepted_match, default: true, class: "checkbox" %>
</div>
<div class="email-holder">
<%= f.label :new_message, "Received a new message", class: "new_message_email" %>
<%= f.check_box :new_message, default: true, class: "checkbox" %>
</div>
</div>
<% end %>
edit_account_spec.rb
it "allows the user to opt out of new match email", :js do
user = create(:user)
preferences = create(:preference, user: user)
sign_in(user)
visit edit_user_path(user)
click_tab(t("edit_user.tabs.settings"))
find(:css, "#user_preferences_attributes_0_new_match").set(false)
within "#button-container" do
page.find('.save.main-save-button-edit').trigger('click')
end
visit edit_user_path(user)
click_tab(t("edit_user.tabs.settings"))
user.preferences.reload
new_match_email_checkbox = find(".new_match_email")
expect(new_match_email_checkbox.checked?).to be_falsey
end
I've tried clicking it, unchecking it, checking it, trigger clicking it, wrapping it around a within block, reloading the db, etc.
new_match_email_checkbox = find(".new_match_email")
within(".email-notifications-holder") do
page.uncheck('Getting a new match each week')
end
new_match_email_checkbox.set(false)
Right now when you save a user's profile, you must have onboard skills saved or else it will throw an error message when you're trying to click the save button.
part of the user controller
def update
if update_current_user?(user_params)
redirect_to user_path(current_user)
else
flash["notice"] =
"Please choose 3 industries, fields and years of experience."
redirect_to edit_user_path(current_user)
end
end
private
def update_current_user?(update_params)
skills_chosen?(update_params[:user_onboard_skills_attributes]) &&
current_user.update(update_params)
end
Using save_and_open_page, the error alert wasn't appearing so it was unclear what was happening. I was able to debug this by trailing the logs while running the tests using:
tail -f log/test.log
Just using this will uncheck the checkbox
within(".email-notifications-holder") do
page.uncheck('Getting a new match each week')
end
But you then have to grab the element to test it.
new_match_email_checkbox = find(".new_match_email")
expect(new_match_email_checkbox.checked?).to be_falsey
Note:
One thing I am unclear about. Are you trying to make this line work?:
find(:css, "#user_preferences_attributes_0_new_match").set(false)
or are you trying to uncheck the checkbox after you call user.preferences.reload ?

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 !

Checkboxes in Rails - Value chosen not displaying in 'Show', undefined method `merge' for "a":String

I'm having a set of problems that are doing my head in! Kind of a Rails newb so I'm having trouble figuring this out.
I've got a field for my 'Question' model that's called 'Answers_expected', which I want to have two options for, 'One' or 'Multiple', rather than just a normal text input.
My Questions_controller.rb (relevant lines):
before_action :set_answers_expected
private
# Use callbacks to share common setup or constraints between actions.
def set_question
#question = Question.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def question_params
params.require(:question).permit(:title, :brief, :idea_id, :user_id, :answers_expected)
end
def set_answers_expected
#answers_expected = [
"One",
"Multiple"
]
end
Questions.rb (relevant line):
validates :answers_expected, presence: true
_form.html.erb:
<%= form_for(#question) do |f| %>
<% if #question.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#question.errors.count, "error") %> prohibited this question from being saved:</h2>
<ul>
<% #question.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field form-group">
<%= f.label :title, "Question" %><br>
<%= f.text_area :title, class:"form-control" %>
</div>
<div class="field form-group">
<%= f.label :brief, "Description" %><br>
<%= f.text_area :brief, class:"form-control" %>
</div>
<div class="field form-group">
<%= f.label :answers_expected %><br>
<% #answers_expected.each do |a| %>
<%= f.label :a, class: 'checkbox' do %>
<%= f.check_box :answers_expected, "a" %>
<%= a %>
<% end %>
<% end %>
</div>
My Questions show.html.erb:
div class="question">
<p>
<strong>Question:</strong>
<%= #question.title %>
</p>
<p>
<strong>Brief:</strong>
<%= #question.brief %>
</p>
<p>
<strong>Answers expected:</strong>
<%= #question.answers_expected %>
</p>
For some reason on my server, I get an error undefined methodmerge' for "a":Stringpointing to line<%= f.check_box :answers_expected, "a" %>in _form.html.erb, but it works when I changef.check_boxtof.radio_button`; why?
Even with radio_button, however, the Answers Expected display on the server continuously shows zero, despite what I click, which I also don't understand.
Also wrote specs hoping to point me in the right direction here:
question_spec.rb:
scenario 'with valid params' do
click_link 'Create a question'
fill_in 'Question', with: 'Valid question'
fill_in 'Description', with: 'This is valid description for the question.'
check 'One'
click_button 'Create Question'
page.should have_content 'One'
expect(page).to have_content('Question was successfully created.')
end
With my session_helper.rb having:
def submit_question(title = 'valid title', brief = 'valid brief')
click_link 'Create a question'
fill_in 'Question', with: title
fill_in 'Description', with: brief
check 'One'
click_button 'Create Question'
end
And my failed spec:
1) Visitor submits a question with valid params
Failure/Error: page.should have_content 'One'
expected to find text "One" in "Toggle navigation Labthi.ng Home Explore Recent Activity Example User Sign out × Question was successfully created. 0 Title: Valid Title Phase: 1 Brief: Valid brief for an idea Image: Active: true Components: App Categories: Other User: Example User Direct Define Reputation Activity Question was successfully created. Question: Valid question Brief: This is valid description for the question. Answers expected: 0 Idea: Valid brief for an idea User: Example User No comments. Add comment No answers yet. Why don't you add one ? Add answer Edit | Back"
# ./spec/features/question_spec.rb:16:in `block (2 levels) in <top (required)>'
Very confused! This is messing with my understanding of Rails a bit.
Thanks.
Edit:
Changed the syntax to <%= f.check_box :answers_expected, value: "a" %> , but the answers expected on the show page is still displaying as zero?
The correct way to set a value with the the check_box form helper is:
<%= f.check_box :answers, {}, "a" %>
:answers is the field name
{} is where you would put html attributes like class or id
"a" will be the value :)

Cucumber,Capybara and ElementNotFound

In my rails application, I have a page with a link that execute a javascript function :
<%= link_to_function("Add an address", "add_fields(this)".html_safe) %>
In my cucumber feature I have :
And I press "Add an address"
And the message I get is :
Capybara::ElementNotFound: no button with value or id or text 'Add an address' found
I'm probably missing something, but I can't find what it is..
You should do one, and only one, of the following:
Rename your submit button to 'Create'
Change your test to 'And I press "Save"'
Add to your button an id, and also change the test, like this:
view
= f.submit 'Save', :id => :foo
test
And I press "foo"
Solved by joaomilho:
You should do one, and only one, of the following:
Rename your submit button to 'Create'
Change your test to 'And I press "Save"'
Add to your button an id, and also change the test, like this:
view
= f.submit 'Save', :id => :foo
test
And I press "foo"
1 scenario (1 passed)
3 steps (3 passed)
0m2.510s
Same behavior here, I'm using:
Rails 3 Cucumber/Capybara/Haml
Feature: Manage posts
In order to [goal]
[stakeholder]
wants [behaviour]
#wip
Scenario: Register new post # features/manage_posts.feature:6
Given I am on the new post page # features/step_definitions/web_steps.rb:19
When I fill in "Title" with "title 1" # features/step_definitions/web_steps.rb:40
And I fill in "Body" with "body 1" # features/step_definitions/web_steps.rb:40
And I uncheck "Published" # features/step_definitions/web_steps.rb:83
And I press "Create" # features/step_definitions/web_steps.rb:27
Then I should see "title 1" # features/step_definitions/web_steps.rb:108
And I should see "body 1" # features/step_definitions/web_steps.rb:108
And I should see "false" # features/step_definitions/web_steps.rb:108
Step:
When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector| with_scope(selector) do
click_button(button)
selenium.wait_for_page_to_load
end
end
View New:
%h1 New post
= render 'form'
= link_to 'Back', posts_path
Error:
no button with value or id or text 'Create' found (Capybara::ElementNotFound)
./features/step_definitions/web_steps.rb:29
./features/step_definitions/web_steps.rb:14:in `with_scope'
./features/step_definitions/web_steps.rb:28:in `/^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/'
features/manage_posts.feature:11:in `And I press "Create"'
_form:
= form_for #post do |f|
-if #post.errors.any?
#errorExplanation
%h2= "#{pluralize(#post.errors.count, "error")} prohibited this post from being saved:"
%ul
- #post.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :title
= f.text_field :title
.field
= f.label :body
= f.text_area :body
.field
= f.label :published
= f.check_box :published
.actions
= f.submit 'Save'
I believe you want
And I follow "Add an Address"
Sebastian: Try to add an id to your link, and reference it in your test.
Wasn't the original problem that you were creating a link but trying to press a button?
Read the capybara docs carefully, and you'll see the methods are different.

Resources