Here's my request spec:
require 'spec_helper'
describe "Password pages" do
describe "user views his passwords" do
let(:user) { create(:user) }
sign_in(:user)
end
end
spec_helper.rb
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
config.include Capybara::DSL
config.include LoginMacros
end
support/login_macros.rb
module LoginMacros
def sign_in(user)
visit new_user_session_path
fill_in 'Email', with: user.email
fill_in 'Password', with: user.password
click_button 'Sign in'
end
end
When running spec I get error:
/spec/requests/account_pages_spec.rb:9:in `block (2 levels) in <top (required)>': undefined method `sign_in' for #<Class:0x007fd4f97183f8> (NoMethodError)
I use this cool technics but another way:
Create page class:
class PageObject
include Capybara::DSL
def visit_page(page)
visit(page)
self
end
def login(user)
fill_in 'Email', with: user.email
fill_in 'Password', with: user.password
click_button 'Sign in'
end
end
create feature instead describe:
require 'spec_helper'
feature 'test authozire page' do
let(:login_page) { PageObject.new }
let(:user) { create(:user) }
scenario 'login page have field' do
page = login_page.visit_page(new_user_session_path)
expect(page.have_field?('email')).to be_true
expect(page.have_field?('password')).to be_true
end
scenario "user can login" do
login_page.visit_page(new_user_session_path).login(user)
# more awesome test
end
end
Related
I created a macro for my create_post_spec.rb
rails v-5.2
ruby v-2.5.1
capybara v-3.2'
my macro
spec/support/features/session.rb
module Features
def sign_in(user)
visit new_user_session_path
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_on "Log in"
end
end
then include in my rails_helper
Rspec.confifure do |config|
config.include Feature, type: feature
end
in my
spec/feature/create_post_spec.rb
require "rails_helper"
RSpec.describe "Create post" do
let(:user){ User.create(email: "example#mail.com", password: "password",
password_confirmation: "password")}
scenario "successfuly creating post" do
sign_in user
visit root_path
click_on "Create post"
fill_in "Title", with: "Awesome title"
fill_in "Body", with: "My rspec test"
click_on "Publish"
expect(page).to have_current_path root_path
end
scenario "unsuccessful creating post" do
sign_in user
visit root_path
click_on "Create post"
fill_in "Title", with: "Awesome title"
fill_in "Body", with: ""
click_on "Publish"
expect(page).to have_css ".error"
end
scenario "non-logged in user cant create post" do
end
end
i get an undefined method sign_in,
But if i use "feature" in my block
RSpec.feature "Create post....." do
it works
i wonder why it won't work if i use "describe"
RSpec.describe "Create post....." do
The difference between RSpec.feature and Rspec.describe is that RSpec.feature adds type: :feature and capybara_feature: true metadata to the block. The important thing there is the type: :feature metadata since it's what you're using to trigger the include of your module. You can use describe by adding your own metadata
RSpec.describe "Create post", type: :feature do
...
end
or you can have RSpec automatically add the type based on the directory the spec file is in by changing the file directory to spec/features/xxx.rb (note the plural features) and ensuring
RSpec.configure.do |config|
config.infer_spec_type_from_file_location!
end
is enabled in your rails_helper - see https://relishapp.com/rspec/rspec-rails/docs/directory-structure
I cannot get rspec to load support files, have tried:
config.include SessionHelper, :type => :controller
In the spec_helper file, Which gives me
NameError: uninitialized constant SessionsSpecHelper
Adding:
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
Gives me:
NoMethodError: undefined method `join' for nil:NilClass
Adding:
require 'support/session_helpers.rb'
Provides no difference
support/session_helper.rb:
module SessionHelpers
def sign_up_with(email, password)
visit sign_up_path
fill_in 'Email', with: email
fill_in 'Password', with: password
click_button 'Sign up'
end
def sign_in
user = create(:user)
visit sign_in_path
fill_in 'Email', with: user.email
fill_in 'Password', with: user.password
click_button 'Sign in'
end
end
Have you noticed the error config.include SessionsHelper, :type => :controller
has Sessions
while your module module SessionHelpers has Session
I just started using factory_girl and I tried using:
user = FactoryGirl.create(:user)
but that doesn't seem to work. Here is my code:
RSpec.feature "Send a message" do
scenario "Staff can send a message" do
visit "/"
group = Group.create!(name: "Group A")
user = FactoryGirl.create(:user)
fill_in "Email", with: "staff#example.com"
fill_in "Password", with: "password"
click_button "Sign in"
person = Person.create!(groups: [group], phone_number: "+161655555555")
message = Message.create(body: "Test Message", group_ids: [group.id])
fill_in "Enter a Message:", with: "Test Message"
check "message_group_#{group.id}"
click_button "Send Message"
expect(page).to have_content("Messages on their way!")
expect(page).to_not have_content("Body can't be blank")
expect(page).to_not have_content("Group ids can't be blank")
end
Here is my factory:
FactoryGirl.define do
factory :user do
email "cam#example.com"
password "password"
end
end
Simple right? What could be going wrong?
user = FactoryGirl.create(:user)
fill_in "Email", with: user.email
fill_in "Password", with: user.password
Also, if you use devise, you can add next lines to spec/support/warden.rb and use method login_as(user) instead of submitting login form.
RSpec.configure do |config|
config.include Warden::Test::Helpers, type: :feature
config.include Warden::Test::Helpers, type: :request
config.before :suite do
Warden.test_mode!
end
config.after :each do
Warden.test_reset!
end
end
I am using Rspec, Capybara and Devise. I need to be able to sign in.
My test:
describe "POST #create" do
context "with valid params" do
it "creates a new Poll" do
#user = FactoryGirl.create(:user)
visit new_user_session_path
fill_in "user_email", :with => #user.email
fill_in "user_password", :with => "qwerty"
click_button "commitSignIn"
visit '/'
expect(page).to have_selector('.signin_username') # OK
binding.pry
end
end
end
In the Pry console, I tried to output current_user:
[1] pry(#<RSpec::ExampleGroups::PollsController::POSTCreate::WithValidParams>)> put current_user
NameError: undefined local variable or method `current_user' for #<RSpec::ExampleGroups::PollsController::POSTCreate::WithValidParams:0x00000008011c08>
from /home/kalinin/.rvm/gems/ruby-2.0.0-p598/gems/rspec-expectations-3.3.0/lib/rspec/matchers.rb:966:in `method_missing'
For further tests I need the current_user set.
Here's how I have included the Devise::TestHelpers:
# spec/spec_helper.rb
RSpec.configure do |config|
config.include Devise::TestHelpers, type: :controller
config.include Devise::TestHelpers, type: :helper
config.include ApplicationHelper
end
I moved mine into a shared_context:
shared_context 'login' do
def log_in_with_user(user, options={})
email = options[:email] || user.email
password = options[:password] || user.password
# Do login with new, valid user account
visit new_user_session_path
fill_in "user_email", with: email
fill_in "user_password", with: password, exact: true
click_button "Log In"
end
end
Then in your test you can do:
describe "POST #create" do
include_context 'login'
let(:current_user) { FactoryGirl.create(:user) }
before do
log_in_with_user current_user
end
context "with valid params" do
it "creates a new Poll" do
visit '/'
expect(page).to have_selector('.signin_username') # OK
binding.pry
end
end
end
I am trying to test a feature spec for a user who needs to edit their account model settings. I am new to testing so not sure if my issue is due to how I am setting up my Factory girl associations or if a problem with my database cleaner configurations.
FactoryGirl.define do
factory :user do
first_name "John"
last_name "Smith"
sequence(:email) { |n| "John#{n}#example.com" }
password "pw"
end
end
FactoryGirl.define do
factory :account do
association :owner, factory: :user
name "Account One"
end
end
My spec_helper.rb:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'shoulda/matchers'
require 'database_cleaner'
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = false
config.infer_base_class_for_anonymous_controllers = false
config.order = 'random'
config.include FactoryGirl::Syntax::Methods
config.include Devise::TestHelpers, type: :controller
OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[:twitter] = OmniAuth::AuthHash.new({
:provider => 'twitter',
:uid => '12345'
})
OmniAuth.config.add_mock(:google, {:uid => '12345'})
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, :js => true) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
My spec/features/account_spec.rb
require 'spec_helper'
feature 'Account' do
before :each do
#account = create(:account)
#user = #account.owner
sign_in
end
scenario 'a signed in user updates the account settings' do
expect(current_path).to eq edit_account_path(#account.id)
expect(page).to have_content('Edit Account')
fill_in 'Company Name', with: 'New XYZ Co.'
click_button 'Update Account'
expect(page).to have_content('Settings were successfully updated.')
end
scenario 'a signed in user receives an error message when deletes company name' do
fill_in 'Company Name', with: nil
click_button 'Update Account'
expect(page).to have_content("Can't be blank")
end
def sign_in
visit root_path
click_link 'Sign in'
fill_in 'Email', with: #user.email
fill_in 'Password', with: #user.password
click_button 'Sign in'
click_link 'Account'
end
end
If I run just the one spec I get passing tests:
Account
a signed in user updates the account settings
a signed in user receives an error message when deletes company name
Finished in 1.71 seconds
2 examples, 0 failures
But when I run the entire test suite I get errors:
1) Account a signed in user updates the account settings
Failure/Error: expect(current_path).to eq edit_account_path(#account.id)
expected: "/accounts/11/edit"
got: "/accounts/33/edit"
(compared using ==)
# ./spec/features/account_spec.rb:11:in `block (2 levels) in <top (required)>'
Finished in 6.85 seconds
88 examples, 1 failure, 7 pending
Failed examples:
rspec ./spec/features/account_spec.rb:10 # Account a signed in user updates the account settings