capybara + selenium + rspec + element not found - selenium

I m using capybara + selenium + rspec to test my application. I have a page, none of whose elements are manipulated by ajax or javascript(hide/show/toggle). When ever i try to submit the form on the page using
click_button 'Save'
it gives me an error stating element not found. i used 'save_and_open_page' to view the html contents and everything looks fine. the page needs to be scrolled down the access the button. Just for curiosity, i changed the button position so that i dont need to scroll the page and can directly access the button when the page is loaded. In the later case, my capybara spec runs fine. I m not able to derive the root of the problem behind this weird behavior of capybara. The issue is, in most of my views, my submit buttons can be accessed after scrolling the page. How do i avoid the above problem?
the gem versions are
capybara 2.1.0
selenium 0.2.10
selenium-client 1.2.18
selenium-webdriver 2.33.0
the capybara code
fill_in 'user_name', :with => 'Abc Xyz'
fill_in 'user_phone', :with => '58743653'
fill_in 'user_password', :with => 'prasad'
fill_in 'user_password_confirmation', :with => 'prasad'
fill_in 'user_designation', :with => 'Programmer'
page.execute_script "window.scroll(0,10000)"
#find_by_id('save_user').native.send_key(:enter)
sleep 20
page.execute_script("$('form.of-setup').submit()") #current hack to make it work
#click_button 'save my profile'
current_url.include?("registrations/terms/#{#user.invitation_token}").should == true
if i uncomment the 'save my profile' button, it gives error as
Failure/Error: click_button 'save my profile'
Capybara::ElementNotFound:
Unable to find button "save my profile"
and if i uncomment the 'send key' line, it gives error as
Failure/Error: find_by_id('save_user').native.send_key(:enter)
Capybara::ElementNotFound:
Unable to find id "save_user"
the haml code is as
...# additional view code
.optional-area
.container
.row
.span2
.span14
%fieldset
= f.text_field :designation, :help => 'Type a job title', :placeholder => "(optional; like Senior Design Engineer)", :label => "Title"
= f.text_area :street, :rows => "2", :help => "Type the company's street number and name", :placeholder => "(optional; like 1111)", :label => "Street Address"
= f.text_field :city, :help => 'Type a city name', :placeholder => "(optional; like San Jose)"
= f.text_field :state, :help => 'Type a stae or province name or abbreviation', :placeholder => "(optional; like CA)", :label => "State/Province"
= f.text_field :postal_code, :help => 'Type a postal code', :placeholder => "(optional; like 95131)"
.row
.span12.offset4
= f.submit "save my profile", :class => "btn primary verylarge toUpperCase", :disable_with => "SAVE MY PROFILE", :id => 'save_user'
= link_to 'cancel', root_path, :class => "cancel-link of-link of-cancel toUpperCase quickhelp", 'data-placement' => "above", :title => "Abandon the action"
...#additional view code

Related

capybara testing unable to sign in

describe "create post", :js => true do
before :each do
a = User.create!(:email => 'any#gmail.com', :password => 'admin123', :password_confirmation => 'admin123', :firstname => "black")
a.confirm!
end
it "signs me in" do
get root_path
visit '/'
within(".form-inline") do
fill_in 'Email', :with => 'any#gmail.com'
fill_in 'Password', :with => 'admin123'
end
click_button 'Sign in'
save_and_open_page
end
end
when i execute with rake spec:requests
i'm unable to login, i'm getting invalid email or password error in browser.
please tell me what to do?

Rails 3.2.8 Remote Form Not Working

I have this form, which is not bound to any model, that I want to ajaxify. I've tried to figure out how to get it to submit via ajax, but I must be doing something wrong because it is not working (it just does a regular POST).
I can confirm that the form tag renders with a 'remote' attribute, but there is not js added anywhere to the form. I also added the :confirm just to see if that would work as well. It does not.
jquery and jquery_ujs are both loaded on the page.
%form{ :action => "/newsletter", :confirm => "Are you sure?", :remote => true, :method => "post", :id => "newsletterForm"}
%p
= label_tag(:q, "Subscribe to our newsletter:")
%p
= text_field_tag(:q, nil, :placeholder => "Your email address")
= button_to("Subscribe", :remote => true)
I just wrote this doing something similar with a form get:
= form_tag('/signup', :method => "get", :remote => true, :id=> 'signup-form') do
%label{:id => 'signup-label', :for=> 'signup-box'}
Enter your email address
= text_field_tag "signup-box", params[:signup], :class => 'text', :required => true, :id => 'signup-box'
= submit_tag "Sign Up", :id => 'signup'
Controller:
class SignupController < ApplicationController
def index
puts "***************************************************"
puts "email sign up"
puts "***************************************************"
render :nothing => true
end
end

How to display only the value in edit page in Active Admin

I have a edit form in Active Admin. I need some field as read only.
My current edit page is like
I need the page look like this
How can this be done. My code for the edit form page is like
form :html => { :enctype => "multipart/form-data" } do |f|
f.inputs "Users" do
f.input :device, :label => 'Device', :as => :select, :collection => DEVICE, :include_blank => false
f.input :current_address, :label => 'Current Address', :as => :string
end
end
Please help.
As Alex said, set to disabled. You could then use css to get the visual you wanted, if you can live with the semantics of that.
The syntax was slightly different for me to get this to work.
in your admin form:
f.input :finish_position, input_html: { disabled: true }
in your CSS active_admin.css
input[disabled="disabled"],
input[disabled] {
background-color: #F4F4F4;
border: 0px solid #F4F4F4 !important;
}
For a cleaner form definition within your ActiveAdmin.register{} block you may as well want to define a "readonly" input type to be used within active admin using formtastic:
Form block syntax is for activeadmin version 1.0.0.pre at 0becbef0918a.
# app/admin/inputs/readonly_input.rb
class ReadonlyInput < Formtastic::Inputs::StringInput
def to_html
input_wrapping do
label_html <<
template.content_tag('div', #object.send(method))
end
end
end
# app/admin/your_model.rb
ActiveAdmin.register YourModel do
# ...
form do |f|
# ...
input :current_address, as: :readonly
# ...
end
end
I was facing the same issue and tried using :disabled but it did not solve my problem as I wanted field value to be included in params object while sending it to the server. When you mark a form input as :input_html => {:disabled => true} , it does not include this field value in params.
So, instead I used :input_html => {:readonly => true} which solved both of my problems:
Does not allow user to edit
Includes the value in params
I hope this will help.
How about this?
form :html => { :enctype => "multipart/form-data" } do |f|
f.inputs "Users" do
f.input :device, :label => 'Device', :as => :select, :collection => DEVICE, :include_blank => false
f.li do
f.label :current_address
f.span f.object.current_address
end
end
end
Try to add , :disabled => true for address input field.
The trick is to use "object". Here is how you should code it:
form :html => { :enctype => "multipart/form-data" } do |f|
f.inputs "Users" do
f.input :device, :label => 'Device', :as => :select, :collection => DEVICE, :include_blank => false
f.label :current_address, f.object.current_address
end
end

devise rails - error messages in different view?

I'm trying to show my errors (both flash and devise) in one of my layout files (_header.html.erb):
<div id="alerts">
<% flash.each do |name, msg| %>
<%= content_tag :div, msg, :id => "flash_#{name}" if msg.is_a?(String) %>
<% end %>
<%= devise_error_messages! %>
</div>
but I'm getting an error: undefined local variable or method `resource', because the error message is no longer in the devise form. I tried the method suggested here: http://pupeno.com/2010/08/29/show-a-devise-log-in-form-in-another-page/ by pasting that code into the application_controller.rb file. No luck. Ideas?
oh. I forgot to mention... The pages work without error, but my tests are failing... Here's a failing test:
it 'succeeds with a valid email and password' do
user = Factory.create(:user)
visit sign_in_path
fill_in 'user_email', :with => user.email
fill_in 'user_password', :with => user.password
click_button 'Sign in'
page.should have_content("hi #{user.username}")
end
This is Rails3, fyi.
I was getting errors like this and solved using :partial and :locals when using the render method:
<%= render :partial => 'header', :locals => { :flash => flash } %>
See Rails 3: "undefined local variable or method" if I put content in a partial
turns out the code needed to be in the application_helper instead of the controller, but the code at pupeno.com works!

User signed out halfway through cucumber test

I'm in the process of splitting change-password functionality off into its own page on my site. The whole process works fine when I run through it manually as a real user, but I can't get my Cucumber tests to pass, the reason being that on the final call to the controller, the current_user is mysteriously returning nil.
I've having a serious WTF moment because the user DEFINITELY is being logged in at the beginning of the tests, and I'm following all the same steps as other passing tests, and as I said the whole thing works fine when stepping through it by hand.
Here's the test in question:
Scenario: The user should be able to change their password
Given I have a signed in user with email = "test#mycompany.com" and password = "password"
When I am on the change-password page # this hits registrations_controller#change_password
And I fill in "Current password" with "password"
And I fill in "New password" with "new_password"
And I fill in "Re-enter new password" with "new_password"
And I press "Update"
Then I should see "You updated your account successfully"
And the login step:
Given /^I have a signed in user with email\s*=\s*"([^"]*)" and password\s*=\s*"([^"]*)"$/ do |email, password|
#user = User.new
#user.email = email
#user.password = password
#user.confirm!
#user.save!
visit '/sign_in'
fill_in("Email", :with => #user.email)
fill_in("Password", :with => #user.password)
click_button("Sign in")
end
Controller actions, from "registrations_controller.rb":
def change_password
# calling "current_user" here retuns the logged-in user as expected
#user = current_user
end
def update_password
# calling "current_user" here returns nil
# error occurs at call to nil.update_with_password
#user = current_user
if #user.update_with_password( params["user"] )
redirect_to after_update_path_for( #user )
else
clean_up_passwords( #user )
render_with_scope :change_password
end
end
Now, we are using devise (1.1.8), and my best guess is that I've done something wrong with the devise routes, which look like this in "routes.rb"
devise_for :users, :controllers => {:confirmations => "confirmations", :sessions => "sessions", :registrations => "registrations"} do
# ...other routes here...
get "/change_password", :to => "registrations#change_password"
put "/update_password", :to => "registrations#update_password"
end
Finally, for completeness, here is "change_password.html.haml"
= render :partial => "shared/stats"
#main
= form_for(resource, :as => resource_name, :url => "update_password", :html => { :method => :put, :autocomplete => "off" }) do |f|
= devise_error_messages!
.edit-account-hold
%span Your password
= f.label :current_password, "Current password"
= f.password_field :current_password
= f.label :password, "New password"
= f.password_field :password
= f.label :password_confirmation, "Re-enter new password"
= f.password_field :password_confirmation
= f.submit "Update", :class => "orange-button border-radius"
= link_to "Cancel", account_path, :id => "cancel-link"
:javascript
$(document).ready( function() {
$("#user_current_password").focus();
});
Try running it through Selenium. Watching the test run can often give clues about what's going wrong.