Rails Rspec IntegrationTest Capybara - ruby-on-rails

I have started to test my app via Rspec (Capybara). This is how I am doing it:
require 'rails_helper'
RSpec.describe "Homepages", type: :request do
describe "GET / without login" , js: true do
before(:all) do
Employee.create(username: "username", password: "12345", password_confirmation: "12345")
end
it "works!" do
visit root_path
fill_in "loginname", with: "username"
fill_in "password", with: "12345"
click_button('sign_in')
end
end
end
Because of env namely "TEST-ENV" I have to create an employee at first.
the problem is, if I run 'rake spec:requests', I get this errors:
1) Homepages GET / without login works!
Got 0 failures and 2 other errors:
1.1) Failure/Error:
def initialize(template, original_exception)
super(original_exception.message)
#template, #original_exception = template, original_exception
#sub_templates = nil
set_backtrace(original_exception.backtrace)
end
ArgumentError:
wrong number of arguments (1 for 2)
#/.rvm/gems/ruby-2.1.1/gems/actionview-4.2.7/lib/action_view/template/error.rb:64:in `initialize'
# /.rvm/gems/ruby-2.1.1/gems/capybara-2.10.1/lib/capybara/session.rb:128:in `exception'
# /.rvm/gems/ruby-2.1.1/gems/capybara-2.10.1/lib/capybara/session.rb:128:in `raise'
# /.rvm/gems/ruby-2.1.1/gems/capybara-2.10.1/lib/capybara/session.rb:128:in `rescue in raise_server_error!'
# /.rvm/gems/ruby-2.1.1/gems/capybara-2.10.1/lib/capybara/session.rb:125:in `raise_server_error!'
# /.rvm/gems/ruby-2.1.1/gems/capybara-2.10.1/lib/capybara/session.rb:113:in `reset!'
# /.rvm/gems/ruby-2.1.1/gems/capybara-2.10.1/lib/capybara.rb:334:in `block in reset_sessions!'
# /.rvm/gems/ruby-2.1.1/gems/capybara-2.10.1/lib/capybara.rb:334:in `reverse_each'
# /.rvm/gems/ruby-2.1.1/gems/capybara-2.10.1/lib/capybara.rb:334:in `reset_sessions!'
# /.rvm/gems/ruby-2.1.1/gems/capybara-2.10.1/lib/capybara/rspec.rb:21:in `block (2 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# Capybara::CapybaraError:
# Your application server raised an error - It has been raised in your test code because Capybara.raise_server_errors == true
# /.rvm/gems/ruby-2.1.1/gems/capybara-2.10.1/lib/capybara/session.rb:126:in `raise_server_error!'

I'm not sure but I think better if type = feature
Sample
require "rails_helper"
RSpec.feature "Homepages", type: :feature do
before do
Employee.create(username: "username", password: "12345", password_confirmation: "12345")
end
context "GET / without login" do
scenario "works!", js: true do
visit root_path
fill_in "loginname", with: "username"
fill_in "password", with: "12345"
click_button('sign_in')
end
end
end
Please make sure your input name is correct by inspect element to get the input name
I think
fill_in "loginname", with: "username"
maybe be
fill_in "user[loginname]", with: "username"

As others have stated, Capybara tests should be of type 'feature' not 'request', however that's not the primary cause of your error. Your apps code is raising an exception during template rendering, and then you're running into a bug in the current version of Capybara with handling exceptions whose initializers take multiple parameters. As long as you're not using jRuby you can lock your Capybara version to 2.10.0 and you should see the correct error your app is raising. If you are using jRuby, or if you prefer to not lock to an older version, you can specify to use the master branch of Capybara
gem 'capybara', github: 'teamcapybara/capybara'
which has the bug fixed.
As a side-note, you've tagged this question with capybara-webkit when you're not actually using the capybara-webkit driver (since it only supports up to Capybara 2.7.1 currently), so you might want to change the tag to just capybara.

Related

rails 5 method not allowed test environment capybara

I have the following capybara feature scenario:
scenario 'user can create an account' do
visit new_user_path
within(:css, "form[action='/users']") do
fill_in 'user[username]', with: 'dummy'
fill_in 'user[email]', with: 'dummy#email.com'
fill_in 'user[password]', with: 'password'
fill_in 'user[password_confirmation]', with: 'password'
fill_in 'user[address]', with: 'brasilia'
find("input[type='submit']").click
end
expect(page).to have_current_path(root_path)
end
When I execute it, I get the following error:
1) CreateAccount user can create an account
Failure/Error: expect(page).to have_current_path(root_path)
expected "/users" to equal "/"
# ./spec/features/create_account_spec.rb:14:in `block (2 levels) in <top (required)>'
So I tested in development environment with the same params, and everything is working. I used save_and_open_screenshot inside the scenario and I get this message:
Method not Allowed
I don't know what's is happening. Thanks in advance for any help!
Edit 1
I inspect the log but I didn't able to see any request being made, but only an error related to database. Here what I found:
SELECT schemaname || '.' || tablename
FROM pg_tables
WHERE
tablename !~ '_prt_' AND
tablename <> 'schema_migrations' AND
schemaname = ANY (current_schemas(false))
I don't know if this will help but the only log snippet thats looks like an error.
Edit 2
I runned rails s -e test and discovered that the hidden_tag authencity token is missing inside the form tag that mades the request. Can this be the cause of method not allowed?

rpsec-rails with apartment Gem and Grape cannot set host with subdomain

I am using Rails 4.2.6, Ruby 2.2.1, rspec-rails 3.4.2, Grape 0.16.2, grape_token_auth 0.1.0. I installed apartment gem (1.0.2) for multitenancy and trying to write rspec tests for grape requests.
But I am getting the following error from rspec-rails response method every time irrespective of whatever solutions I tried.
#buf=["<!DOCTYPE html>\n<html>\n<head>\n <title>Apartment::TenantNotFound at /content/api/v1/questions</title>\n</head>\n<body>\n
The request is taking the host as 'www.example.com' all time. I tried so many solutions by googling it. But nothing works. you can see that in spec where I commented these lines. I want the url as 'http://g_m.lvh.me:3000' with the subdomain 'g_m'.
I tried this one:
https://github.com/influitive/apartment/wiki/Testing-Your-Application
But not works. I don't know why.
I tried this, but not working:
Rails: Wrong hostname for url helpers in rspec
and tried to set the host by:
host! "g_m.lvh.me:3000"
#request.host = 'g_m.lvh.me:3000'
request.host = 'g_m.lvh.me:3000'
Nothing works!
I created a test case like the following grape link says:
https://github.com/dblock/grape/commit/99bf4b44c511541c0e10f4506bf34ae9abcccd75
require 'rails_helper'
RSpec.describe ContentManager::QuestionAPI, :type => :request do
#before(:each) { Apartment::Tenant.switch!("g_m") }
#after(:each) { Apartment::Tenant.switch!("public") }
#before(:each) do
#begin
#client = FactoryGirl.create(:client, title: 'Sample title', subdomain: 'g_m')
#rescue
#client = Client.create!(title: 'Sample title', subdomain: 'g_m')
#end
#default_url_options[:host] = 'http://g_m.lvh.me:3000'
# request.host = "#{'g_m'}.lvh.me"
#end
#end
#before(:each) do
# if respond_to?(:default_url_options)
# default_url_options[:host] = 'http://g_m.lvh.me:3000'
# end
#end
describe "GET /content/api/v1/questions" do
it "returns an empty array of questions" do
get "/content/api/v1/questions"
#puts "response.inspect: #{response.inspect}"
response.status.should == 200
JSON.parse(response.body).should == []
end
end
end
My configurations:
in spec/rails_helper.rb
config.include RSpec::Rails::RequestExampleGroup, type: :request, file_path: /spec\/requests/
All time this request sent by rspec-rails with
url: '/content/api/v1/questions'
host: 'www.example.com'
My test result shows:
$ rspec spec/requests/
F
Failures:
1) ContentManager::QuestionAPI GET /content/api/v1/questions returns an empty array of questions
Failure/Error: response.status.should == 200
expected: 200
got: 500 (using ==)
# ./spec/requests/question_spec.rb:30:in `block (3 levels) in <top (required)>'
Deprecation Warnings:
Using `should` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax is deprecated. Use the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }` instead. Called from /home/vagrant/gauge-slcsl/spec/requests/question_spec.rb:30:in `block (3 levels) in <top (required)>'.
If you need more of the backtrace for any of these deprecations to
identify where to make the necessary changes, you can configure
`config.raise_errors_for_deprecations!`, and it will turn the
deprecation warnings into errors, giving you the full backtrace.
1 deprecation warning total
Finished in 6.19 seconds (files took 1.93 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/requests/question_spec.rb:26 # ContentManager::QuestionAPI GET /content/api/v1/questions returns an empty array of questions
abhi#ubuntu-trusty-64:~/my-app$
If anyone knows about the error and what I am doing wrong here, please reply/answer.
The error was because of, we have to say the apartment subdomain configuration that just exclude the 'www' word considering as a sub domain.
Add the following:
# config/initializers/apartment/subdomain_exclusions.rb
Apartment::Elevators::Subdomain.excluded_subdomains = ['www']
I was using the better_errors gem in my development and test environment. This causes the rspec output as an better error generated html codes and difficult to understand the rspec failure reason.
I removed better errors from 'test' environment and I got the clue of this error where we have to exclude the 'www' considering as a subdomain.

travis ci and selenium-webdriver unable to obtain stable firefox connection in 60 seconds (127.0.0.1:7055)

I have a blog I'm working on and I added some javascript to make the form for the blog pop up when you click on new post. Everything works fine. I got tests working with minitest and capybara and I installed the gem selenium-webdriver everything works fine when I test it locally. However, when I push up to Github and travis-ci takes in my info and runs my tests it gives me this error
unable to obtain stable firefox connection in 60 seconds (127.0.0.1:7055)
I'm a little confused because I was getting that error locally until I updated to the gem selenium-webdriver to version 2.39.0. I just downloaded firefox so as far as I know everything is up to date. here is some of my files if that helps.
my test
feature "as a student I want a working blog so people can post" do
# this is line 10
scenario "User can make a post", :js => true do
dude_sign_up
dude_log_in
visit posts_path
click_on "New Post"
create_post
page.must_have_content "Post was successfully created"
end
# this is line 19
gemfile
group :development, :test do
gem 'sqlite3'
gem 'minitest-rails'
gem 'launchy'
gem 'coveralls', require: false
gem 'minitest-rails-capybara'
gem 'turn'
gem 'pry'
gem "selenium-webdriver", "~> 2.39.0"
end
.travis.yml file
language: ruby
rvm:
- "2.0.0"
env:
- DB=sqlite
script:
- RAILS_ENV=test bundle exec rake db:migrate --trace
- bundle exec rake db:test:prepare
- rake minitest:features
bundler_args: --binstubs=./bundler_stubs
test helper file
require 'simplecov'
SimpleCov.start 'rails'
ENV["RAILS_ENV"] = "test"
require File.expand_path("../../config/environment", __FILE__)
require "rails/test_help"
require "minitest/rails"
require "minitest/rails/capybara"
require 'selenium-webdriver'
require 'coveralls'
Coveralls.wear!
# To add Capybara feature tests add `gem "minitest-rails-capybara"`
# to the test group in the Gemfile and uncomment the following:
# require "minitest/rails/capybara"
# Uncomment for awesome colorful output
# require "minitest/pride"
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
fixtures :all
# Add more helper methods to be used by all tests here...
end
class ActionDispatch::IntegrationTest
include Rails.application.routes.url_helpers
#include Capybara::RSpecMatchers
include Capybara::DSL
end
Turn.config.format = :outline
def dude_sign_up
visit new_user_path
fill_in "Name", with: "thedude"
fill_in "Email", with: "thedude#cool.com"
fill_in "Password", with: 'password'
fill_in "Bio", with: "the bio"
fill_in "Password confirmation", with: 'password'
click_on "Submit"
end
def dude_log_in
visit new_session_path
fill_in "Email", with: "thedude#cool.com"
fill_in "Password", with: 'password'
click_on "Log In"
end
def create_post
fill_in "Title", with: "this is a test title"
fill_in "Content", with: "oh how this is some crazzzzy content"
click_on "Create Post"
end
travis full error
test_0002_User can make a post 1:00:23.767 ERROR
unable to obtain stable firefox connection in 60 seconds (127.0.0.1:7055)
Exception `Selenium::WebDriver::Error::WebDriverError' at:
/home/travis/.rvm/gems/ruby-2.0.0-p353/gems/selenium-webdriver-2.39.0/lib/selenium/webdriver/firefox/launcher.rb:79:in `connect_until_stable'
/home/travis/.rvm/gems/ruby-2.0.0-p353/gems/selenium-webdriver-2.39.0/lib/selenium/webdriver/firefox/launcher.rb:37:in `block in launch'
/home/travis/.rvm/gems/ruby-2.0.0-p353/gems/selenium-webdriver-2.39.0/lib/selenium/webdriver/firefox/socket_lock.rb:20:in `locked'
/home/travis/.rvm/gems/ruby-2.0.0-p353/gems/selenium-webdriver-2.39.0/lib/selenium/webdriver/firefox/launcher.rb:32:in `launch'
/home/travis/.rvm/gems/ruby-2.0.0-p353/gems/selenium-webdriver-2.39.0/lib/selenium/webdriver/firefox/bridge.rb:24:in `initialize'
/home/travis/.rvm/gems/ruby-2.0.0-p353/gems/selenium-webdriver-2.39.0/lib/selenium/webdriver/common/driver.rb:31:in `new'
/home/travis/.rvm/gems/ruby-2.0.0-p353/gems/selenium-webdriver-2.39.0/lib/selenium/webdriver/common/driver.rb:31:in `for'
/home/travis/.rvm/gems/ruby-2.0.0-p353/gems/selenium-webdriver-2.39.0/lib/selenium/webdriver.rb:67:in `for'
/home/travis/.rvm/gems/ruby-2.0.0-p353/gems/capybara-2.1.0/lib/capybara/selenium/driver.rb:11:in `browser'
/home/travis/.rvm/gems/ruby-2.0.0-p353/gems/capybara-2.1.0/lib/capybara/selenium/driver.rb:43:in `visit'
/home/travis/.rvm/gems/ruby-2.0.0-p353/gems/capybara-2.1.0/lib/capybara/session.rb:193:in `visit'
/home/travis/.rvm/gems/ruby-2.0.0-p353/gems/capybara-2.1.0/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>'
test/test_helper.rb:35:in `dude_sign_up'
test/features/blog_system_works_test.rb:12:in `block (2 levels) in <top (required)>'
does anyone understand why this works locally but not with travis-ci?
hey Reck you pointed me in the right direction; however, I found that the problem was in my .travis.yml file
if you go to
http://karma-runner.github.io/0.8/plus/Travis-CI.html
they will tell you that to set up travis to use firefox you need to add
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
to your travis file.
after changing my .travis.yml file to
language: ruby
rvm:
- "2.0.0"
env:
- DB=sqlite
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
script:
- RAILS_ENV=test bundle exec rake db:migrate --trace
- bundle exec rake db:test:prepare
- rake minitest:features
bundler_args: --binstubs=./bundler_stubs
everything worked fine with travis
Try setting transactional_fixture to false in your rspec_spec.rb:
config.use_transactional_fixtures = false

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-

Resources