Capybara is unable to find the form fields from Stripe? - ruby-on-rails-3

I´m learning Ruby on Rails and i´m working on an application that use stripe to create premium accounts. Also, i´m using Rspec and Capybara to do the integration tests.
require 'spec_helper'
feature "user upgrade account to a premium plan" do
scenario "user upgrade account", :js => true do
user = FactoryGirl.create :user
visit new_user_session_path
fill_in 'Email', :with => user.email
fill_in 'Password', :with => user.password
click_button 'Sign in'
visit new_charge_path
click_button "Pay with Card"
fill_in 'Email', :with => 'persona#example.com'
fill_in "Card number", :with => "4242424242424242"
fill_in 'CVC', :with => '123'
fill_in 'MM/YY', :with => '11/14'
click_button 'Pay $5.00'
end
I run the test and i get an error message that says:
Failure/Error: fill_in "Card number", :with => "4242424242424242"
Capybara::ElementNotFound:
Unable to find field "Card number"
Anyone knows, what can be the problem?
Thanks.

Depending on how you're integrating Stripe, it might be rendering the form inside an iframe. If that's the case, you'll need to use Capybara.within_frame to target the actions to the correct frame:
scenario "user upgrade account", :js => true do
user = FactoryGirl.create :user
visit new_user_session_path
fill_in 'Email', :with => user.email
fill_in 'Password', :with => user.password
click_button 'Sign in'
visit new_charge_path
click_button "Pay with Card"
Capybara.within_frame 'stripe_checkout_app' do
fill_in 'Email', :with => 'persona#example.com'
fill_in "Card number", :with => "4242424242424242"
fill_in 'CVC', :with => '123'
fill_in 'MM/YY', :with => '11/14'
click_button 'Pay $5.00'
end
end

Try to use element id instead of field label.
fill_in 'card_number', :with => '4242424242424242'
fill_in 'cvc', :with => '123'
(Being card_number and cvc the ids of input fields.)
= f.text_field :card_number, :class => 'span12', :id => :card_number
= f.text_field :cvc, :class => 'span12', :id => :cvc
I had the same problem and I used this solution, not sure if it's good practice, but works for me.

for capybara with stripe testing:
Capybara.within_frame 'stripe_checkout_app' do
fill_in "Card number", :with => "4242424242424242"
fill_in 'CVC', :with => '123'
fill_in 'Expiry', :with => '11/22'
click_button 'Pay $5.00'
end
edit the exipry date to a month and year of future always.

Related

capybara + selenium + rspec + element not found

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

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?

undefined method `change'

I'm doing the ruby on rails tutorial, I specifically adding listing 8.21 to spec/requests/users_spec.rb
require 'spec_helper'
describe "Users" do
describe "signup" do
describe "signup failure" do
lambda do
it "should not make a new user" do
visit signup_path
fill_in "Name", :with => ""
fill_in "Email", :with => ""
fill_in "Password", :with => ""
fill_in "Password confirmation", :with => ""
click_button
response.should render_template('users/new')
response.should have_selector("div#error_explanation")
end
end.should_not change(User, :count)
end
end
end
as far as I can tell, this is exactly like the listing in 8.21; however, when I run
rspec spec/requests/users_spec.rb -e "Users"
I got the following error ...
#> rspec spec/requests/users_spec.rb -e "Users" No DRb server is running. Running in local process instead ... /Users/bryanjamieson/rails_projects/sample_app/spec/requests/users_spec.rb:17:in `block (3 levels) in ': undefined method `change' for
# (NoMethodError)
any help would be appreciated.
I'd use User.count
end.should_not change(User.count)
Depending on which rails version and rspec version you're using (assuming Rails 3.1, Rspec2) the tutorial may be a little of out date

Can't find field when using symbol reference

I'm playing around with RoR for the first time and hit a weird error. I have the following test code for my navigation links:
describe "when logged in" do
before(:each) do
#user = Factory(:user)
visit login_path
#the line below is the weird one
fill_in "session[user_name]", :with => #user.user_name
fill_in :password, :with => #user.password
click_button
end
it "should have navigation links" do
response.should have_selector("nav")
end
it "should have link to log out" do
response.should have_selector("a", :href => logout_path, :content => "Log out")
end
end
the code above works just fine, but if I would change the line
fill_in "session[user_name]", :with => #user.user_name
to
fill_in :user_name, :with => #user.user_name
it won't work and I can't figure out why. The error I get is
Failure/Error: fill_in :user_name, :with => #user.user_name
Webrat::NotFoundError:
Could not find field: :user_name
The relevant generated html is:
<label for="session_user_name">User name</label><br/>
<input id="session_user_name" name="session[user_name]" size="30" type="text" />
<label for="session_password">Password</label><br/>
<input id="session_password" name="session[password]" size="30" type="password" />
If you look at the code you see I do exactly that for the password, and that works just fine. I would like to use the syntax which is causing the error so am I doing something wrong?
Try this:
fill_in "user name", :with => #user.user_name
I think webrat is being nice, and its able to find your label 'Password' because it is case insensitive and its turning :password into 'Password'.
You could also use the HTML id attribute, i.e.
fill_in :session_user_name, :with => #user.user_name
One gotcha here is if you are thinking of switching to use Capybara rather than Webrat: Capybara is case-sensitive, so it would fail on fill_in "user name".
I'm not sure what the best practice is here, but I have switched to using the HTML id and name attributes rather than the label text in my own code. The reason for this is that it is less brittle because people change the customer-facing text on the site more than they change the semantic elements and names.

Rails Capybara Problems

I am trying to get tests working after switching from Webrat to Capybara. When I try to sign in to the application I am getting a "Invalid username/password" error, despite just having created the user in a Factory using factory_girl. The way I understand it, the user should persist for the entirety of the fixture, right?
factories.rb:
Factory.define :user do |user|
user.firstname "Test"
user.lastname "Test"
user.email "test#test.com"
user.password "testtest"
user.password_confirmation "testtest"
end
layout_links.spec.rb:
describe "LayoutLinks" do
before(:each) do
wrong_user = Factory(:user)
integration_sign_in(wrong_user)
end
it "should have a dashboard page" do
get '/dashboard'
page.should have_css('h1', :text => "Navigation#dashboard")
end
spec_helper.rb
def integration_sign_in(user)
visit signin_path
fill_in :email, :with => user.email
fill_in :password, :with => user.password
click_button "Sign in"
puts page.body
end
Also in spec_helper.rb is the following:
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
Shouldn't the user persist and then be successful in the integration_sign_in function? I can still sign in correctly through the browser in the development environment, which has a user and the sign in was working correctly with webrat before the migration, so I am not sure what to think. Thanks!
UPDATE: It looks like the session isn't going to the server correctly. On the server, when I check the value of email and password in the session, the values are incorrect:
puts "Post Email: " + params[:session][:email]
puts "Post Password: " + params[:session][:password]
the email variable has the password variable, and the password variable has no value. Why would this be? The client integration test maps the fields correctly:
fill_in :email, :with => user.email
fill_in :password, :with => user.password
How can I test this further? Thanks.
So this worked for me
fill_in "Email", :with => user.email
fill_in "Password", :with => user.password
whereas using the symbols failed
It looks like the session wasn't going to the server correctly. I am not sure how to account for this.