Cucumber,Capybara and ElementNotFound - ruby-on-rails

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.

Related

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::Element Not Found

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.

Detecting multiple submit_tag click in Rails [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Ruby on Rails: How to have multiple submit buttons going to different methods (maybe with with_action?)
In a form I have some submit_tags and on server side I have to detect which one was clicked.
This is that I've tried, not working: on server side I only get an action name in params:
<%= form_tag controller_action_path(:id => #project.id), :method => :post do %>
<% if #project_is_synced %>
<%= submit_tag 'Update synchronization', :name => 'update' %>
<%= submit_tag 'Stop synchronization', :name => 'stop' %>
<% else %>
<%= submit_tag 'Start synchronization', :name => 'start' %>
<% end %>
<% end %>
I have only params[:action] with a current action name which is always the same
The easiest way to debug this is to run it locally and look at the parameters as they come through, or log parameters in your action:
if request.post?
logger.warn "POST #{params}"
end
You have named the submit_tags, so instead of the default name 'commit', each button has a different name, and you'll have to check for params named 'start', 'stop', or 'update'.
Simplest is just to remove the names and check params[:commit] for a varying value, however if you don't want to change the view, use this (replacing the render code obviously):
if params[:start]
render :text => "start"
elsif params[:update]
render :text => "update"
else
render :text => "stop"
end
The comments to the answer in the linked post do deal with this, but I can see why you missed it.

2 submit buttons in a form

I have a question about forms. I have a fairly standard form that saves a post (called an eReport in my app) with a title and body. The table also has a "published" field, which is boolean. The saved eReport only shows on the public site if this field is set to true, with false being the default.
Rather than the default check box, I would like to display two buttons at the end of the form: a "Publish Now" button and a "Save as Draft" button. If the user presses the former, the published field would be set to true. If the latter, then false. In PHP, I used to display 2 submit fields with different name values, then handle the input with an if/else statement to determine the proper SQL query to build. In Rails, I'm assuming I would place this logic in the controller, under the appropriate action, but I'm not sure how to manipulate the name or id values of buttons.
For the record, I'm using Formtastic, but if someone could show me how to do this with the default Rails form tags, that's OK too. Here's the code for my form as it stands right now:
<% semantic_form_for #ereport do |form| %>
<% form.inputs do %>
<%= form.input :title %>
<%= form.input :body %>
<% end %>
<% form.buttons do %>
<%= form.commit_button :label => "Publish Now" %>
<%= form.commit_button :label => "Save as Draft" %>
<% end %>
<% end %>
Thanks in advance for the help!
I don't know about formtastic, but with the default rails form builder, you could do it like this:
<%= form.submit "Save with option A", :name => "save_option_a" %>
<%= form.submit "Save with option B", :name => "save_option_b" %>
Then in the controller, you can pick those up in params:
if params[:save_option_a]
# do stuff
end
in addition to #iddlefingers answer, here is a view of the log of the application (striping some useless params due to explanation purposes)
Parameters: {"utf8"=>"✓", ..., "comentar"=>"Confirmar"}
where we can see that comentar is the name of the parameter, and "Confirmar" is it's value, which is the button's text too.
which was obtained by submit_tag "Confirmar", :name => 'comentar'
So in general you could have (if you want to reduce the number of params you are working with) several submit_tag "onevalue", :name => 'SAMEname', submit_tag "othervalue", :name => 'SAMEname'...
and retrieve them in your controller
if params[:SAMEname] == "onevalue"
# do stuff
elsif params[:SAMEname] == "othervalue"
#do different stuff
end
I think you need to use jQuery.
You can bind the button click event and submit the form for specified location.

rails image_submit_tag with cucumber/webrat

I've the following search form with image_submit_tag instead of submit_tag.
Now I get the obvious fail when cucumber runs:
When I fill in "q" with "sachin" # features/step_definitions/web_steps.rb:33
And I press "submit" # features/step_definitions/web_steps.rb:21
Could not find button "submit" (Webrat::NotFoundError)
(eval):2:in `click_button'
./features/step_definitions/web_steps.rb:22:in `/^(?:|I )press "([^\"]*)"$/'
features/search.feature:20:in `And I press "submit"'
It fails coz its looking for the submit button.
Since I'm using image_submit_tag, what will be the webrat/cuke step for this tag to make the form submit?
I tried this and it works using the id option:
<%= image_submit_tag "image_file_name", :id => "submit" %>
and in the feature:
And I press "submit"
Note that :title => "submit" did not work (even though the Webrat docs says that it checks for both :id and :title)
I'm not sure if this will work or not, but try adding a title attribute to your image button:
image_submit_tag ..., :title => "submit"

Resources