unable to test rails3-bootstrap-devise-cancan with capybara - ruby-on-rails-3

I'm using https://github.com/RailsApps/rails3-bootstrap-devise-cancan with default test-suit setting. I have a simple spec in my spec/requests folder
require 'spec_helper'
describe "Feedbacks" do
describe "guest must be denied to visit index path" do
before { visit feedbacks_path }
page.should have_selector ".alert", text: "Denied"
end
end
and I run into and error "undefined local variable or method `page' for.....", trying to run this test.
I have
require 'capybara/rails'
and
RSpec.configure do |config|
.....
.......
config.include(Capybara::DSL)
in my spec_healper
and in gemfile "gem "capybara", ">= 2.0.3", :group => :test"
Please help me get rid of this annoying error....

Related

Unable to use Capybara, Not sure where I am going wrong 'background' and 'it' etc is not working

Hi I am learning capybara, and i ve tried various answers in SO I am not able to proceed. I am trying to test a application with capybara. Visit is not working, errors out saying it needs to be within 'it' or example/executable block etc. but with below code , background and scenario etc is not working, execution is not going inside.
Results::
C:\Ruby223\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) C:/Users/xxx/RubymineProjects/xxx-app/spec/features/xxxxx.rb
"aaa"
Process finished with exit code 0
i dont want to mess up the Rails application, so I want a standalone file from where i can execute tests and then integrate with rails app with developers help.
require 'capybara/dsl'
require 'capybara'
require 'capybara/rspec'
require 'rspec'
feature "Signing in" do
p 'aaa'
background do
p 'aaa1'
Capybara.register_driver :selenium_chrome do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
Capybara.run_server = false
Capybara.current_driver = :selenium_chrome
Capybara.app_host = 'http://www.google.com'
end
scenario "Signing in with correct credentials" do
p 'aaa2'
visit '/q=?alkjaaa'
within("#session") do
fill_in 'email', with: 'user#example.com'
fill_in 'password', with: 'caplin'
end
click_button 'Signin'
expect(page).to have_content 'results'
end
given(:other_user) { User.make(email: 'other#example.com', password: 'rous') }
scenario "Signing in as another user" do
p 'aaa'
visit '/sessions/new'
within("#session") do
fill_in 'Email', with: other_user.email
fill_in 'Password', with: other_user.password
end
click_button 'Signin'
expect(page).to have_content 'Invalid email or password'
end
end
Running that file alone with ruby isn't going to do anything because all it does is define tests, it doesn't execute them. If you run that file with rspec then it will run the tests defined in the file.
rspec your_file.rb

Feature specs fail only on CircleCI or Codeship continuous integration services

My very basic feature specs are passing just fine locally but failing on CircleCI and Codeship. The tests that are failing:
require 'spec_helper'
describe 'Authentication' do
describe "sign in" do
it "is the landing page for non-authenticated users" do
user = create(:user)
visit root_path
expect( page ).to have_content 'LOG IN' # On sign-in page
fill_in 'Email', with: user.email
fill_in "Password", with: user.password
click_button 'Sign in'
expect( current_path ).to eq user_path(user)
end
end
describe 'registration' do
it "allows new users to register" do
visit root_path
click_link 'Sign up'
fill_in 'Email', with: 'myfake#email.com'
fill_in 'Password', with: 'password'
fill_in 'Password confirmation', with: 'password'
fill_in 'First name', with: 'John'
fill_in 'Last name', with: 'Doe'
click_button "Sign up"
expect( current_path ).to include '/users/'
expect( page ).to have_content "Welcome! You have signed up successfully."
end
end
end
The tests both fail on the first lines where they set expectations of the pages (expect( page ).to have_content "LOG IN" and click_link "Sign up", respectively), with errors suggesting the page HTML is completely blank:
expected to find text "LOG IN" in ""
I saved screenshots on CircleCI, and they indeed show a completely blank page.
Here's where it gets interesting. I tried debugging the problem by running/watching the specs on Circle using a VNC. When I a) set driver: :selenium for the tests, b) add a sleep 1 or two to the tests before testing the page expectations, and c) manually run the test after SSHing into their servers with the VNC, I can see the tests run in Selenium (they open a browser in the VNC) and they pass perfectly.
Outside of the VNC, however, the tests fail consistently in both CI servers. With or without tons of sleeps and driver: :selenium. Any ideas what could be causing this discrepancy between the regular CircleCI/Codeship servers and their VCN/my local test environment? I got in touch with the folks at CircleCI, but they're stumped for the moment.
If relevant, I'm running Ruby 2.2.0, Rails 4.2, Capybara 2.4.4, Capybara-Webkit 1.4.1, and Selenium-Webdriver 2.44.0
Some potentially relevant files:
spec_helper.rb
ENV["RAILS_ENV"] = "test"
require File.expand_path("../../config/environment", __FILE__)
require "rspec/rails"
require "shoulda/matchers"
require "webmock/rspec"
require 'vcr'
Dir[Rails.root.join("spec/support/**/*.rb")].each { |file| require file }
module Features
include Warden::Test::Helpers
Warden.test_mode!
def sign_in(user)
login_as(user, scope: :user)
end
end
module Controllers
# Pre-parse controller responses for easy access
def response_body
body = JSON.parse(response.body)
body.is_a?(Hash) ? body.to_sh : body.map(&:to_sh)
end
end
module Mock
def disable_webmock(&block)
WebMock.disable!
yield
WebMock.enable!
end
end
RSpec.configure do |config|
config.expect_with :rspec do |c|
c.syntax = :expect
end
# Save a screenshot to CircleCI when a feature test fails
config.after(:each, :type => :feature) do |example|
if example.exception
artifact = save_page
puts "\"#{example.description}\" failed. Page saved to #{artifact}"
end
end
config.include Features, type: :feature
config.include Controllers, type: :controller
config.include Mock
config.include Formulaic::Dsl, type: :feature
config.infer_spec_type_from_file_location!
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
config.use_transactional_fixtures = false
end
RSpec::Matchers.define :hash_eq do |expected|
match do |actual|
actual.recursive_symbolize_keys == expected.recursive_symbolize_keys
end
end
VCR.configure do |c|
c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
c.hook_into :webmock
c.allow_http_connections_when_no_cassette = true
c.configure_rspec_metadata!
c.ignore_hosts '127.0.0.1', 'localhost:3000'
end
ActiveRecord::Migration.maintain_test_schema!
Capybara.javascript_driver = :webkit
if ENV['CIRCLE_ARTIFACTS']
Capybara.save_and_open_page_path = ENV['CIRCLE_ARTIFACTS']
end
WebMock.disable_net_connect!(allow_localhost: true)
database_cleaner.rb
RSpec.configure do |config|
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
end
I can think of a couple of things to try:
If you want to get your specs to run headless, try using poltergeist rather than capybara-webkit. poltergeist has several advantages which I described here: https://stackoverflow.com/a/24108439/634576
Selenium might just be a distraction, but, if you want to get it to work, be sure that your CI environment has the right version of Firefox. Each version of selenium-webdriver seems to need a narrow range of versions of Firefox. On CircleCI, you can configure circle.yml to install a specific version of Firefox. Right now we use selenium-webdriver 2.46.2 and Firefox 39.0.3, installed with the following in circle.yml:
dependencies:
pre:
- sudo apt-get update; sudo apt-get install firefox=39.0.3+build2-0ubuntu0.12.04.1
I don't know about Codeship.
I have experienced instability of my Selenium tests on CircleCI until I came across this post https://discuss.circleci.com/t/selenium-tests-timing-out/7765/2
After adding:
machine:
environment:
DBUS_SESSION_BUS_ADDRESS: /dev/null
to my circle.yml, my tests have become stable.

Request spec with Devise + Rspec2 + Spork/Guard

I have setup Rspec2 + Spork + Guard + Devise
My files are as follows
#spec_helper.rb
Spork.prefork do
#code
Dir[Rails.root.join('spec/support/**/*.rb')].each {|f| require f}
RSpec.configure do |config|
config.extend ControllerMacros, :type => :controller
end
end
Spork.each_run do
# This code will be run each time you run your specs.
FactoryGirl.reload
include ControllerMacros
end
#spec/support/controller_macros.rb
module ControllerMacros
def login_user
before(:each) do
#request.env["devise.mapping"] = Devise.mapping[:user]
user = FactoryGirl.create(:user)
sign_in user
end
end
end
#spec/support/devise.rb
Spec.configure do |config|
config.include Devise::TestHelpers, :type => :controller
end
in my request spec
#spec/features/documents_spec.rb
require 'spec_helper'
describe "Documents" do
login_user
describe "GET /documents" do
it "should display document name as sameera CV" do
#spec code
end
end
end
and when I run bundle exec guard, I get
1) Documents GET /documents should display document name as sameera CV
Failure/Error: Unable to find matching line from backtrace
NoMethodError:
undefined method `env' for nil:NilClass
# ./spec/support/controller_macros.rb:4:in `block in login_user'
So far I have done lots of fixes via google and nothing seems to be working, can someone help me :)
I'm on
rails 3.2.9
rspec 2.12.0
devise 2.2.3
any help would be greatly appreciated
Try changing #request.env["devise.mapping"] = Devise.mapping[:user] to request.env["devise.mapping"] = Devise.mapping[:user] in spec/support/controller_macros.rb
Here I'm answering my own question, and I was able to find a workaround for the question I asked.
Following are the steps I did
1) removed the controller_macros.rb and devise.rb from support directory
2) removed the ControllerMacros references from spec_helper.rb
3) Added the following code to
#spec/features/documents_spec.rb
before(:each) do
user = FactoryGirl.create(:user)
visit root_path
fill_in 'user_email', :with => user.email
fill_in 'user_password', :with => user.password
click_button 'Sign in'
end
I'm sure there should be a more elegant way (as describe in devise wiki), but this WORKS :)

rspec2 acceptance testing with capybara

I'm trying to implement a feature with rspec2 and rails3 , basically I have a Post model which I'm trying to test by creating a Post (I'm using device for authentication)
this is my feature
spec/acceptance/new_post_feature_spec.rb
require 'spec_helper'
require 'rspec/example_steps'
feature "Creating a new post" do
include Devise::TestHelpers
before(:each) do
#request.env["devise.mapping"] = Devise.mappings[:user]
user = FactoryGirl.create(:user)
sign_in user
end
Steps "Add a new post" do
page.visit "/posts"
page.should have_content("New Post")
end
end
But I'm getting this error
undefined method `env' for nil:NilClass
Following are the gems I'm using
gem "rspec-rails", "~> 2.0"
gem 'database_cleaner'
gem 'capybara'
gem "factory_girl_rails", ">= 4.1.0"
gem 'rspec-example_steps'
with Guard/Spork
any help would be appreciated
#request is a controller test variable. It's not what you want here. In fact, in capybara specs you don't need to specify the devise mapping and you cant use sign_in.
Capybara fires up a browser, you must tell it to go to your login page and sign in through the same steps that you would do in a browser.
Try this: (you may need to change some input and button names)
let(:user) { FactoryGirl.create(:user) }
before(:each) do
page.visit new_user_session_path
# note: use the email/password input names below if yours are different
page.fill_in "user[email]", :with => user.email
page.fill_in "user[password]", :with => user.password
page.click_button "Sign in"
end

Testing a Rails App using Devise with Capybara and Rspec causes no Method Error

I just started some tests on my Rails application in which I use Devise for authentication. I just generated rspec and only added
RSpec.configure do |config|
config.include Devise::TestHelpers, :type => :controller
end
to my spec/support/devise.rb file.
I also added Capybara to the test group in my gemfile, run the bundle command, etc. But as I do visit in my tests, I get a no method error. Here an example of my user_spec.rb:
require 'spec_helper'
describe "Club" do
before(:each) do
#club ||= FactoryGirl.create(:club)
FactoryGirl.create(:membership)
User.all.each{|x| x.delete}
end
describe "privacy" do
it "shouldn't be shown any tournament if the user is private" do
attributes = FactoryGirl.attributes_for(:user)
user = User.create!({private: true}.merge(attributes))
assert(user.private)
visit "/user/#{user.id}/tournaments"
page.should have_no_selector(".tournament-list")
end
end
end
As I run rspec there comes an error like this:
Failures:
1) Club privacy shouldn't be shown any tournament if the user is private
Failure/Error: visit "/user/#{user.id}/tournaments"
NoMethodError:
undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_3::Nested_1:0x007ff0ea113108>
# ./spec/user_spec.rb:14:in `block (3 levels) in <top (required)>'
For capybara specs I use:
describe "Club", :type => :feature, :js => true do
include Capybara::DSL
it "..."
end
And instead User.all.each{|x| x.delete}, use DatabaseCleaner
You can easily add the Capybara::DSL to RSpec config spec_helper.rb
RSpec.configure do |config|
.....
.......
config.include(Capybara::DSL)
end