I'm currently writing a test for a form using RSpec, and I was wondering how I'd go about selecting a radio button, given the form below:
<%=form_for(#whatever) do|f|%>
<%=f.label :option, "TRUE" %>
<%=f.radio_button :option, true %>
<%=f.label :option, "FALSE" %>
<%=f.radio_button :morning, false %>
<%=f.submit "SAVE" %>
<% end %>
I want my test to look something like:
describe "with valid options selected" do
before do
#CODE TO SELECT A RADIO BUTTON
click_button "SAVE"
end
end
describe "with valid info" do
before do
choose('True')
click_button "Create Setlist"
end
...
end
I had to assign an ID to the radio button for this to work as well
Doc for additional reference: http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions
Related
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 ?
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 :)
I have the following form and I want to check if the text field is present or not. How can I do that ?
<%= form_for(ownership, remote: true) do |f| %>
<div>
<%= f.text_field :confirm, value: nil %>
<%= f.hidden_field :start_date, value: Time.now %>
</div>
<%= f.submit t('button.ownership.take.confirmation'), class: "btn btn-small"%>
<% end %>
Here my test :
describe "for not confirmed ownership" do
before do
FactoryGirl.create(:agreed_ownership, user: current_user, product: product)
be_signed_in_as(current_user)
visit current_page
end
# it { should_not have_text_field(confirm) }
it { should_not have_button(t('button.ownership.take.confirmation')) }
end
You'd use a has_css? expectation:
it "should have the confirm input field" do
visit current_page
expect(page).to have_css('input[type="text"]')
end
You can use additional jQuery-style selectors to filter for other attributes on the input field, too. For example, 'input[type="text"][name*="confirm"]' would select for confirm appearing in the input field's name attribute.
To set an expectation the field isn't present, you'd use to_not on your expectation: expect(page).to_not have_css('input[type="text"]')
Bonus: Here's the older, should-style syntax:
it "should have the confirm input field" do
visit current_page
page.should have_css('input[type="text"]')
end
it "shouldn't have the confirm input field" do
visit current_page
page.should_not have_css('input[type="text"]')
end
I keep getting this error:
Capybara::ElementNotFound:
cannot fill in, no text field, text area or password field with id, name, or label 'Morning' found.
I've reset spork, done a full db reset, tried assigning an ID to the form element, etc. What could possibly be the issue here?
days_controller_spec.rb
require 'spec_helper'
describe DaysController do
describe "New" do
describe "with valid information" do
it "should create a new entry" do
visit 'days#new'
fill_in "Morning", with: "Test"
click_button "Submit"
end
end
end
end
days_controller.rb
<%= form_for #day do |f| %>
<%= f.label :morning %>
<%= f.text_field :morning %>
<%= f.button :submit %>
<% end %>
Looks like you app is using JavaScript. With capybara you need to add :js => true option to the block that's dealing with JS pages.
Try:
it "should create a new entry", :js => true do
You may also need to way for the form to be rendered before trying to fill_in the field.
Also, I recommend you check out capybara's integration DSL. Read more about it here
Turns out that syntax was all correct, but the issue was that the test was in the wrong RSpec spec file. When I swapped this test into an integration_test file, it worked perfectly.
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.