I could not resolve this issue. Please help me. It gives me element not found error.
spec/features/todos/create_spec.rb
require 'spec_helper'
describe "Creating todos" do
let(:user) { FactoryGirl.create(:user)}
before(:each) do
visit root_path
click_link "Login"
fill_in "Email", with: "user#gmail.com"
fill_in "Password", with: "password"
click_button "Sign in"
end
it "redirects to the todos index page" do
visit "/todos"
fill_in "title", with: "MyString"
click_button "Create"
expect(page).to have_title("MyString")
end
my view code.
_new_form.html.erb
<%= form_for current_user.todos.new, remote:true do |f| %>
<div class="input-group">
<%= f.text_field :title, class: "form-control", placeholder: "title" %>
<span class="input-group-btn">
<%= f.submit "Create", class: "btn btn-success" %>
</span>
</div>
<% end %>
spec_helper.rb
def sign_in
#user = FactoryGirl.create(:user)
controller.stub(:authenticate_user!).and_return(true)
#user
end
If you have the code running on a server locally, inspect the element and the name of the field is what Capybara needs to run. Generally, if the form is nested, the name rails will come up with (in this case) is something like todos[title].
So, spec/features/todos/create_spec.rb should look something like:
require 'spec_helper'
...
it "redirects to the todos index page" do
visit "/todos"
fill_in "todos[title]", with: "MyString"
click_button "Create"
expect(page).to have_title("MyString")
end
Found my answer.
In the view file I've a text_field with title with an id. The id = todo_title in the console
But am calling title in the test . Here the capybara not been able to find title. It was todo_title
After using
fill_in "todo_title"
It worked like charm.
In your form, there must be an element with the name as "title". From the docs:
fill_in(locator, options = {}) ⇒ Object
Locate a text field or text area and fill it in with the given text The field can be found via its name, id or label text.
Related
I'm trying to solve a challenge, but I received an error message from Cabybara saying:
`Failure/Error: fill_in 'Name', with: 'Vostro 2017'
Capybara::ElementNotFound: Unable to find visible field "Name" that is not disabled`
My new.html.erb is:
<%= form_for #item, url: {action: "create"} do |f|%>
<%= f.label 'Name' %>
<%= f.text_field :name %>
<%= f.label 'Description' %>
<%= f.text_field :description %>
<%= f.label 'Features' %>
<%= f.text_field :features %>
<%= f.label 'Asset number' %>
<%= f.text_field :assetNumber %>
<%= f.submit%>
<% end %>
And my item_controller.rb is:
class ItemController < ApplicationController
def show
#items = Item.find(params[:id])
end
def new
#item = Item.new
end
def create
#item = Item.new(item_params)
#item.save
redirect_to #item
end
private
def item_params
params.require(:item).permit(:name, :description, :features, :assetNumber)
end
end
The rspec file that is being used to do the test is:
require 'rails_helper'
feature 'User creates a new inventory item' do
scenario 'successfully' do
visit new_item_path
fill_in 'Name', with: 'Vostro 2017'
fill_in 'Description', with: 'Dell Notebook'
fill_in 'Features', with: '16gb, 1Tb, 15.6"'
fill_in 'Asset number', with: '392 DLL'
click_button 'Create Item'
expect(page).to have_content 'Vostro 2017'
expect(page).to have_content 'Dell Notebook'
expect(page).to have_content '16gb, 1Tb, 15.6"'
expect(page).to have_content '392 DLL'
end
end
I'm using ruby-2.3.5 and rails 4.1.0.
I'm beginner in ruby/rails and I can't figure out what's wrong with my code.
Could somebody help me to solve that?
I appreciate in advance.
You could do this, assuming your input has an id of name:
find("input[id$='name']").set "Vostro 2017"
or:
find("#name").set "Vostro 2017"
You might also try lower-casing Name:
fill_in 'name', with: "Vostro 2017"
Capybara will target the name or the id attribute, so the second example should work.
Rails generates form input names with using form object.
fill_in 'item[name]', with: "Vostro 2017"
fill_in 'item[description]', with: 'Dell Notebook'
fill_in 'item[features]', with: '16gb, 1Tb, 15.6"'
fill_in 'item[assetNumber]', with: '392 DLL'
If you look at the actual HTML of the page instead of the erb template (always better to include the HTML unless your question is specifically about the erb) you'll notice your labels aren't actually associated with the input elements (no matching for attribute to the id of the input). Obviously for Capybara to find the element by label text ('Name' in your case) the label would have to be correctly associated with the element. To fix that you need to use f.label - http://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-label - correctly. If you want to specify the text of the element (vs using text extracted from i18n translation) that would be
f.label :name, 'Name'
I realized what I was doing wrong, so let's go:
I changed the instance variable items inside def show action to item (not pluralized) and I changed an atribute from assetNumber to asset_number, so this way the Cabybara test could understand correctly.
Thanks guys.
I tried setting the id in various parts of the form, as well as wrapping the form in a div with id set to search. The result is always the same.
spec/features/02_post_spec.rb
scenario 'search for post title' do
fill_post_form(post3)
fill_in "search", with: post3.title
click_button("Search")
expect(page).to_not have_content(post1.title)
expect(page).to_not have_content(post2.title)
expect(page).to have_content(post3.title)
end
spec/spec_helper.rb
def fill_post_form(post)
visit new_post_path
fill_in 'Title', with: post.title
fill_in 'Body', with: post.body
click_button 'Create Post'
end
This will redirect_to post_path(post)
views/posts/index.html.erb
<%= form_tag(posts_path, method: :get, class: "block") do %>
<div class="form-group">
<div class="input-group">
<%= text_field_tag :search, params[:search], class: "form-control", id: "search" %>
<span class="input-group-btn">
<%= submit_tag "Search", name: nil, class: "btn btn-default" %>
</span>
</div>
</div>
<% end %>
Capybara output
Failure/Error: fill_in "search", with: post3.title
Capybara::ElementNotFound:
Unable to find field "search"
The command fill_in "search", with: post3.title you're using should work, assuming you are on the page rendering the shown partial, and the output of that partial is actually visible on the page (not hidden via CSS). Your scenario doesn't show visiting an actual page, and you don't show what fill_post_form is doing so it's tough to know exactly what is going wrong. First step would be to do something like
fill_post_form(post3) # already in your tests
sleep 2 # wait a few seconds to make sure above method has completed whatever actions it does
puts page.html # output the current page and take a look to see if your 'search' element is actually on the page
I have multiple email fields in a form. None of them have an id on them intentionally. How can I differentiate each element in the test if they don't have an id? I'll show code for clarity.
TEST
it "sends an invitation to multiple users" do
click_on "Invite"
click_link "Invite Another Team Member"
fill_in "", with: "user#example.com"
fill_in "", with: "user2#example.com"
expect { click_button "Invite" }
.to change(ActionMailer::Base.deliveries, :count).by(1)
.and change(Invitation, :count).by(2)
expect(current_path).to eq(account_users_path)
expect(page).to have_content("user#example.com")
expect(page).to have_content("user2#example.com")
end
This actually creates one object, the bottom field. How can I give the text fields individuality?
FORM
<%= form_tag account_invitations_url do %>
<label class="email-label">
<%= email_field_tag "emails[]", "", placeholder: "Email Address", data: { invitation_modal_email: "" }, id: "" %>
</label>
<%= link_to '✚ Invite Another Team Member', "#email", data: { invitation_modal_add: "" } %>
<div class="form-actions invitation">
<span class="button-text"><%= link_to 'Cancel', account_users_path %></span>
<%= submit_tag "Invite", class: "button button--invitation" %>
</div>
<% end %>
## Browser HTML
I think you can use Capybara's method all for finding all elements with same name:
emails = ["user#example.com", "user2#example.com"]
all('input[name="emails[]"]').each_with_index do |field, i|
field.set(emails[i])
end
Or:
all('input[name="emails[]"]')[0].set("user#example.com")
all('input[name="emails[]"]')[1].set("user2#example.com")
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.
~~~~~~~~~~~~~~~
Edit/Update
~~~~~~~~~~~~~~~
Ok, I fixed the tests that were failing to pass by appending a ".to_s" to each user.password_digest in the change blocks. I assume this is working because before user.password_digest was sort of like a pointer, and calling "to_s" forces the test to compare the string values. If anyone can explain why the test compares the pointer and not the value, please enlighten me.
After adding the .to_s calls (added everywhere I was expecting a user attribute to change), Failure #3 is still occurring (and a new failure, actually, but I'm sure it's caused by the same issue causing Failure #3). Any ideas why the test "correct user with correct password should change email" isn't catching the change action that happens correctly in the browser?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I'm trying to validate behavior of a form to update a user's profile (change email and/or password). 3 of my tests are failing, and I can't figure out why. Take a look at the console output when I run the tests...
Failures:
1) User Pages Edit page correct user updates password with incorrect password should not change password
Failure/Error: expect { click_button "Save" }.not_to change{ user.password_digest }
result should not have changed, but did change from "$2a$10$Xrg1SHSyDmK5Of9HrjgYAuzkJzKk7HeaVjj4ZT9Ldz2R9BNji3D2S" to "$2a$10$Xrg1SHSyDmK5Of9HrjgYAuzkJzKk7HeaVjj4ZT9Ldz2R9BNji3D2S"
# ./spec/requests/user_pages_spec.rb:135:in `block (6 levels) in <top (required)>'
2) User Pages Edit page correct user updates password with confirmation mismatch should not change password
Failure/Error: expect { click_button "Save" }.not_to change{ user.password_digest }
result should not have changed, but did change from "$2a$10$bm2viuIuNCRIEEWe/qYVAOVl0r0EW7Y/1CqalKUwgR.ht/wVtQ8Zi" to "$2a$10$bm2viuIuNCRIEEWe/qYVAOVl0r0EW7Y/1CqalKUwgR.ht/wVtQ8Zi"
# ./spec/requests/user_pages_spec.rb:147:in `block (6 levels) in <top (required)>'
3) User Pages Edit page correct user updates email with correct password should change email
Failure/Error: expect { click_button "Save" }.to change{ user.email }.to(new_email)
result should have been changed to "new_email#example.com", but is now "person_7#example.com"
# ./spec/requests/user_pages_spec.rb:121:in `block (6 levels) in <top (required)>'
Finished in 2.99 seconds
8 examples, 3 failures
Failures #1 & 2 should be passing, right? The before and after strings match, and they're expected not to change! What could be going on here?
Furthermore, I can't figure out why failure #3 is happening.
The code works as expected in the browser. Could it have something to do with AJAX? The update action the form is hitting doesn't redirect_to anything -- it just renders the page again with flash notices. I'm a Rails newbie so I'm probably missing something obvious.
The form:
<%= form_tag user_path(params[:id]), method: :put do %>
<%= label_tag :email %>
<%= text_field_tag :email, params[:email] || #user.email %>
<%= label_tag :new_password %>
<%= password_field_tag :new_password %>
<%= label_tag :new_password_confirmation, "Confirm new password" %>
<%= password_field_tag :new_password_confirmation %>
<%= label_tag :password %>
<%= password_field_tag :password %>
<%= submit_tag "Save", class: "btn btn-primary pull-down" %>
<% end %>
The tests spec (unrelated tests removed for clarity):
require 'spec_helper'
describe "User Pages" do
subject { page }
describe "Edit page" do
let(:user) { FactoryGirl.create(:user) }
describe "correct user" do
before do
log_in user # helper method that logs the user in, a la Michael Hartl tutorial
visit edit_user_path(user)
end
it { current_path.should == edit_user_path(user) }
it { should have_selector('title', text: 'Edit') }
it { should_not have_content('not authorized') }
describe "updates email" do
let(:new_email) { "new_email#example.com" }
before { fill_in 'Email', with: new_email }
describe "with incorrect password" do
it "should not change email" do
expect { click_button "Save" }.not_to change{ user.email }
end
end
describe "with correct password" do
before { fill_in 'Password', with: user.password }
it "should change email" do
expect { click_button "Save" }.to change{ user.email }.to(new_email)
end
end
end
describe "updates password" do
describe "with incorrect password" do
before do
fill_in 'New password', with: 'newpassword'
fill_in 'Confirm new password', with: 'newpassword'
end
it "should not change password" do
expect { click_button "Save" }.not_to change{ user.password_digest }
end
end
describe "with confirmation mismatch" do
before do
fill_in 'New password', with: 'newpassword'
fill_in 'Confirm new password', with: 'password'
fill_in 'Password', with: user.password
end
it "should not change password" do
expect { click_button "Save" }.not_to change{ user.password_digest }
end
end
describe "with correct password" do
before do
fill_in 'New password', with: 'newpassword'
fill_in 'Confirm new password', with: 'newpassword'
fill_in 'Password', with: user.password
end
it "should change password" do
expect { click_button "Save" }.to change{ user.password_digest }
end
end
end
end
end
end
Relevant gem versions: Rails 3.2.9, Capybara 1.1.2, FactoryGirl 4.1.0