RoR: Wrong Number of Arguments - ruby-on-rails

I am trying to call a method in my Rails 3 code but am getting:
Failure/Error: integration_sign_in wrong_user
ArgumentError:
wrong number of arguments (0 for 1)
Here is the calling code (in an RSpec helper):
before(:each) do
wrong_user = Factory(:user, :email => "test#test.com", :password=>"hellohello", :password_confirmation => "hellohello")
integration_sign_in wrong_user
end
So it is clearly passing one argument. If the argument is null for some reason, would that make it consider it not a parameter?
RELEVANT BACKSTORY: For testing, I just switched from webrat to capybara. As suggested in Railscast 257, I also installed the launchy and database_cleaner gems. When I was using webrat, the code above worked as expected, but now (I believe related to database_cleaner) something is going wrong.
Possibly relevant: In my spec_helper.rb I changed to:
config.use_transactional_fixtures = false (even though 'true' has the same problem)
Any ideas? Thanks.

It looks like the argument error was not actually in this function (even though the top of the stack makes it look like it is. The actual error is inside of the integration_sign_in function:
def integration_sign_in(user)
visit signin_path
fill_in :email, :with => user.email
fill_in :password, :with => user.password
click_button
end
It looks like click_button needs an argument in capybara, but it does not in webrat.

integration_sign_in(wrong_user)

Related

getting past authentication with capybara in rails application

I'm trying to use capybara on a ruby on rails application to do some content testing, as well I'm using the devise gem to implement user authentication. I'm having trouble logging into my application to perform my test cases.
Initially, my scenario was as follows:
scenario "User arrives at main page" do
visit "purchase_orders#index"
page.should have_content("All")
# some more tests and checks
end
Where purchase_orders#index is the authenticated root, where a user's purchase orders are shown.
But when I was running the tests, I was getting the following error :
expected to find text "All" in "Log in to manage your orders * Email * Password Forgot your password? Remember me Sign up • Didn't receive confirmation instructions? About Us • Contact Us •
which tells me that its not getting past the log in page. I next tried adding the following to my scenario, before running the tests, to make it log in:
visit "purchase_orders#index"
fill_in('Email', :with => 'username#gmail.com')
fill_in('Password', :with => 'password')
click_button('Log in')
where username and password are actual created accounts, but again it fails and doesn't get past the sign in page. Finally, I tried adding a before(:each) method, as follows, to attempt to sign users in for test cases:
before(:each) do
visit "users/sessions#new"
fill_in('Email', :with => 'nico.dubus17#gmail.com')
fill_in('Password', :with => 'password')
click_button('Log in')
end
which, again, did not work for me. So my question is: What is the best practice and syntax for getting past the sign in page, and into the actual application? I've looked for documentation and answers on this, but haven't found anything.
Thank you!
Found an answer. I installed the warden gem to (gem 'warden') and factory girl gem (gem "factory_girl_rails", "~> 4.0") and ran a bundle install. I then created a user fixture with factory girl as follows in a factory.rb file in the spec folder:
# This is a user factory, to simulate a user object
FactoryGirl.define do
factory :user, class: User do
first_name "John"
last_name "Doe"
email "nico_dubus#hotmail.com"
encrypted_password "password"
end
end
in my rails helper file, I added this line to be able to use FactoryGirl's methods without calling it on the class every time:
config.include FactoryGirl::Syntax::Methods
Afterwards, I added these lines to the top of my capybara test page:
include Warden::Test::Helpers
Warden.test_mode!
Finally, I built a user object to use within the scope of the test:
user = FactoryGirl.build(:user)
And whenever I need to log in, I use warden's log in method
login_as(user, :scope => :user)
And voila!

Why does an rspec feature spec with javascript not do test teardown?

I have several non-javascript specs that use the ui to create and edit records.
When I run these specs the test database records are automatically removed for me by the rspec teardown for each test.
However the test below which is the first one to have :js => true for some ajax stuff isn't doing tear down of the records afterwards and then tests start to break because the database is no longer empty correctly when they start. The link and the group rows still exist in the test database.
# spec/features/verifying_link_spec.rb
require 'spec_helper'
describe "verification", :js => true, :type => :feature do
before :all do
User.create(:username => 'r#google.com', :password => 'esceptio')
end
before :each do
visit '/ladmin/login'
fill_in 'username', :with => 'r#google.com'
fill_in 'password', :with => 'esceptio'
find('input[value="Login"]').click
end
it "lets me verify a link" do
find('div#side div a', text: 'New Group').click
fill_in 'group[group_name]', with: 'Group Add'
click_button 'Save'
find('div#side div a', text: 'New Link').click
fill_in 'link[url_address]', with: 'http://www.a.com/newtest9876link'
fill_in 'link[alt_text]', with: 'abcd9876'
click_button 'Save'
this_year=Time.now.strftime('%Y')
l=Link.first
l.update_attribute(:verified_date, nil)
expect(Link.count).to eq 1
visit links_path
find('a', text: "verify")
click_link("verify", match: :first)
sleep(3)
expect(page).to have_content(this_year)
end
end
Right now I am using a workaround solution of using the ui to delete the records (below) but this should not be necessary
# added at bottom of spec
click_link('Details')
click_link('Delete')
page.driver.browser.switch_to.alert.accept
click_link('Groups')
click_link('Delete')
page.driver.browser.switch_to.alert.accept
None of my other unit tests or feature tests (except this one with js) have this problem. They all create records that get removed automatically.
I highly recommend using the database_cleaner gem to clean your database out between tests. Rspec wraps everything in a transaction and rolling it back once the example is finished. However, when you start using javascript you might be saving the data outside of the rspec transaction and then the database never reverts to its original state.
Truncation is slower than the transaction strategy. However you may only need the truncation strategy with JS tests. You could follow this guide to setup the database cleaner gem in that manner: http://devblog.avdi.org/2012/08/31/configuring-database_cleaner-with-rails-rspec-capybara-and-selenium/
If you find your tests taking eons, you might want to investigate some time looking at a gem that preloads your environment. I highly recommend zeus

Rake test not picking up capybara tests in minitest

I am setting up a basic template for having a capybara feature test in a rails application. I'm also using MiniTest instead of RSPEC.
Running Rake Test does not seem to be picking up my feature tests. I have one test in the file, running rake test does not change the number of assertions. Skipping the test does not show up either when I run rake test.
Here is a link to the repository: https://github.com/rrgayhart/rails_template
Here are the steps that I followed
I added this to the Gemfile and ran bundle
group :development, :test do
gem 'capybara'
gem 'capybara_minitest_spec'
gem 'launchy'
end
I added this to the test_helper
require 'capybara/rails'
I created a folder test/features
I created a file called drink_creation_test.rb
Here is the code from that feature test file
require 'test_helper'
class DrinkCreationTest < MiniTest::Unit::TestCase
def test_it_creates_an_drink_with_a_title_and_body
visit drinks_path
click_on 'new-drink'
fill_in 'name', :with => "PBR"
fill_in 'description', :with => "This is a great beer."
fill_in 'price', :with => 7.99
fill_in 'category_id', :with => 1
click_on 'save-drink'
within('#title') do
assert page.has_content?("PBR")
end
within('#description') do
assert page.has_content?("td", text: "This is a great beer")
end
end
end
I think I am having an issue with not connecting something correctly.
Please let me know if there is anything else I can provide which may help with diagnosing this issue.
Multiple things going on here. First, the default rake test task won't pick up tests not in the default test directories. So you need to either move the test file or add a new rake task to test files in test/features.
Since you are using capybara_minitest_spec you need to include Capybara::DSL and Capybara::RSpecMatchers into your test. And because you aren't using ActiveSupport::TestCase or one of the other Rails test classes in this test, you may see inconsistencies in the database because this test is executing outside of the standard rails test transactions.
require 'test_helper'
class DrinkCreationTest < MiniTest::Unit::TestCase
include Capybara::DSL
include Capybara::RSpecMatchers
def test_it_creates_an_drink_with_a_title_and_body
visit drinks_path
click_on 'new-drink'
fill_in 'name', :with => "PBR"
fill_in 'description', :with => "This is a great beer."
fill_in 'price', :with => 7.99
fill_in 'category_id', :with => 1
click_on 'save-drink'
within('#title') do
assert page.has_content?("PBR")
end
within('#description') do
assert page.has_content?("td", text: "This is a great beer")
end
end
end
Or, you could use minitest-rails and minitest-rails-capybara to generate and run these tests.
$ rails generate mini_test:feature DrinkCreation
$ rake minitest:features
I believe minitest has it's own gem for rails when using capybara: minitest-rails-capybara
Following the instructions over there might help, but I've never set up capybara with mini test before.

Trying to test omniauth with rspec & Capybara, failing

Using Rails 3.2 and the latest Rspec and Capybara, which means my Capybara specs live in spec/features.
I'm really new to Rails and testing, but I want to get used to testing. I ended up implementing OAuth before testing it. I finally got it working, and now I'm trying to retroactively test it (so I at least know if it breaks in the future). I'm trying to follow this tutorial, but things aren't working. Here's what I did:
1) Created spec/support/integration_spec_helper.rb with:
module IntegrationSpecHelper
def login_with_oauth(service = :google)
visit "/auth/#{service}"
end
end
2) Modified spec/spec_helper to include config.include IntegrationSpecHelper, :type => :request inside the Rspec.configure do block.
3) Created spec/features/omniauth_spec.rb with:
require 'spec_helper'
feature 'testing oauth' do
scenario 'should create a new tiger' do
login_with_oauth
visit new_tiger_path
fill_in 'tiger_name', :with => 'Charlie'
fill_in 'tiger_blood', :with => 'yes'
click_on 'Create Tiger'
page.should have_content("Thanks! You are a winner!")
end
end
Of course it's going to fail (I don't have tigers in my app) but I want it to fail on visit new_tiger_path. Instead, running the spec, I get:
1) testing oauth should create a new tiger
Failure/Error: login_with_oauth
NameError:
undefined local variable or method `login_with_oauth' for #<RSpec::Core::ExampleGroup::Nested_3:0x83355d8>
# ./spec/features/omniauth_spec.rb:4:in `block (2 levels) in <top (required)>'
So basically, it says there's no such thing login_with_oauth. This must be a really basic error, as my code isn't included for some reason.
I'm not using spork (trying to keep things simple).
Any idea what the problem might be? Thanks in advance!
If you are trying to use oauth from google, you'll want to change:
def login_with_oauth(service = :google)
to:
def login_with_oauth(service = :google_oauth2)
:google_oauth2 should also be the first argument to OmniAuth.config.add_mock, i.e.:
OmniAuth.config.add_mock(
:google_oauth2,
{
:info => {
:email => 'test#some_test_domain.com',
:name=>'Test User'
}
})
Don't forget to change:
config.include(IntegrationSpecHelper, :type => :request)
to:
config.include(IntegrationSpecHelper, :type => :feature)
inside the RSpec.configure block, as Christoph noted above.
A little late, but maybe I can help.
Got the same problem. It's caused by
config.include IntegrationSpecHelper, :type => :request
The paramater ':type' needs to be changed to ':feature' because you write a rspec feature test.
Solution:
config.include IntegrationSpecHelper, :type => :feature
Unfortunately this causes further problems, I couldn't solve yet.
Regards,
C-

Do I need a custom Devise controller if only changing the Sign Up view?

I have the following steps in a capybara/rspec integration test, that is simply trying to sign up a new member.
visit new_member_registration_path
fill_in('Name:', :with => 'Rob Doe' )
fill_in('member_email', :with => 'rob#smith.com' )
fill_in('member_email_confirmation', :with => 'rob#smith.com' )
fill_in('member_password', :with => 'secret')
fill_in('Company or Venue Name:', :with => 'Rob Inc.')
fill_in('Contact Number:', :with => '040544404440')
click_button('Sign up')
save_and_open_page
For some reason the 'email' and 'password' data is not being passed to the DeviseRegistrations controller (it is blank when viewing the test log) and therefore causing the validation to fail. However up until the save_and_open_page there is no rspec errors (so those fields are being filled in).
What am I missing? Do I need to subclass the DeviseRegistrations controller?
Tested on Rails 3.0.7 with rack-test 0.5.7 and rails 3.1rc1 and rack-test 0.6.0
Assuming you have debugger in your Gemfile, here's how you can use it. (This assumes you're using the Rack driver for Capybara.)
# test.rb
visit new_member_registration_path
fill_in('Name:', :with => 'Rob Doe' )
debugger
The terminal will stop your script and wait for you to do something.
# Terminal
/file/path/to/you/test.rb:12
fill_in('Name:', :with => 'Rob Doe' )
(rdb:1)
Open up an IRB session here:
(rdb:1) irb
You can do any RSpec or Capybara method here:
>> current_path.should == 'foo/bar'
Try submitting the form at this point:
>> click_button "Sign Up"
>> save_and_open_page
See what error messages Devise gave to you on the resulting page. With the Rack driver, you won't see the fields being filled in. In that case, you might want to try using the Selenium driver
# test.rb
Capybara.default_driver = :selenium
visit new_member_registration_path
However, you can't drive Capybara from IRB using the Selenium driver. You will, though, be able to see what form values Selenium is putting into your form. Since things happen quickly with Selenium, you can use debugger to pause the test, while you inspect the page that Selenium opened up in your browser.
The problem was in the application layout file. I had another (albeit hidden) form that was posting the blank form fields.
After I created a blank project and saw that it worked perfectly, I peeled back all the potential parts of my app until I found the culprit.
So the answer to the question is, no, a custom devise controller is not required when you are using custom devise views.

Resources