I am facing this error when running an rspec test. I have tried click_link "Title 1" and assigning Article.create to a variable but the same error appears.
Failure/Error: click_link article.title
Capybara::ElementNotFound:
Unable to find link "Title 1"
comment_spec.rb
require "rails_helper"
describe 'navigate' do
let(:user) { FactoryGirl.create(:user) }
let(:article) do
Article.create(title: "Title 1", description: "Some description", user_id: user.id)
end
before do
login_as(user, :scope => :user)
end
describe 'create' do
before do
visit articles_path
end
it"permits a signed in user to write a review" do
click_link article.title
fill_in "Content", with: "An awesome article"
click_button "Post"
expect(page).to have_content("An awesome article")
expect(current_path).to eq(article_path(article.id))
end
end
end
spec/factories/user.rb
FactoryGirl.define do
sequence :email do |n|
"test#{n}#example.com"
end
factory :user do
name 'Tester'
email { generate :email }
password "asdfasdf"
password_confirmation "asdfasdf"
end
EDIT:
article/index.html.erb
<div class="tab-pane active" id="tab1">
<% #articles.each do |article| %>
<%= render 'article', article: article %>
<% end %>
</div>
_article.html.erb
<%= link_to article.title, article_path(article) %>
let is lazy loading which means that the block is not evaluated until you call it.
before do
article # calls the block
visit articles_path
end
An alternative is to use let! which is not lazy loading:
require "rails_helper"
describe 'navigate' do
let(:user) { FactoryGirl.create(:user) }
let!(:article) do
Article.create(title: "Title 1", description: "Some description", user_id: user.id)
end
before do
login_as(user, :scope => :user)
end
describe 'create' do
before do
visit articles_path
end
it"permits a signed in user to write a review" do
click_link article.title
fill_in "Content", with: "An awesome article"
click_button "Post"
expect(page).to have_content("An awesome article")
expect(current_path).to eq(article_path(article.id))
end
end
end
Related
I am getting errors while doing integration tests with rspec and the problem here lies with the fill_in , can anyone explain me why this is happening??
require 'rails_helper'
describe 'navigate' do
describe "index" do
before do
#user = User.create(email:"test#test.com", password:"test123", password_confirmation:"test123", first_name:"Umair", last_name:"Ahmed")
end
it "can be reached successfully" do
visit posts_path
expect(page.status_code).to eq(200)
end
end
describe "new and create" do
before do
user = User.create(email:"test#test.com", password:"test123", password_confirmation:"test123", first_name:"Umair", last_name:"Ahmed")
login_as(user, scope: user)
visit new_post_path
end
it "has a new form" do
expect(page.status_code).to eq(200)
end
it "will fill in details of form" do
fill_in "post[date]", with: Date.today
fill_in "post[rationale]", with: "something rationale"
click_on "Save"
expect(page).to have_content("something rationale")
end
it "will have a user associated with it" do
fill_in "post[date]", with: Date.today
fill_in "post[rationale]", with: "User Association"
click_on "Save"
expect(User.first.posts.first.rationale).to eq("User Association")
end
end
end
post.rb (model)
class Post < ApplicationRecord
belongs_to :user, optional: true
validates_presence_of :date, :rationale
end
views/posts/new.html.erb
<%= form_for #post do |f| %>
<%= f.date_field :date %>
<%= f.text_area :rationale %>
<%= f.submit "Save" %>
<% end %>
I can't seem to understand what is wrong here, can anyone point out what rubbish I am doing here?
UPDATE: I fixed the issue by just changing login_as(user, scope: user) to
login_as(user, scope: :user) , or we can type like this if you like this type of syntax
login_as(user, :scope => :user)
I have this integration test that is giving me errors that seem to have to do with fill_in
require 'rails_helper'
describe 'navigate' do
let(:user) {FactoryGirl.create(:user)}
let(:post) do
Post.create(date: Date.today, rationale: "Rationale", user_id: user.id)
end
before do
login_as(#user, :scope => :user)
end
describe 'index' do
before do
visit posts_path
end
it 'can be reached successfully' do
expect(page.status_code).to eq(200)
end
it 'has a title of Posts' do
expect(page).to have_content(/Posts/)
end
it 'has a list of posts' do
post1 = FactoryGirl.build_stubbed(:post)
post2 = FactoryGirl.build_stubbed(:second_post)
visit posts_path
expect(page).to have_content(/Rationale|content/)
end
it 'has a scope so that only post creators can see their posts' do
other_user = User.create(first_name: 'Non', last_name: 'Authorized', email: 'nonauth#example.com',
password: "password", password_confirmation: "password")
post_from_other_user = Post.create(date: Date.today, rationale: "This post shouldn't be seen",
user_id: other_user.id)
visit posts_path
expect(page).to_not have_content(/This post shouldn't be seen/)
end
end
describe 'new' do
it "has a link from the homepage" do
visit root_path
click_link("new_post_from_nav")
expect(page.status_code).to eq(200)
end
end
describe 'delete' do
it 'can be deleted' do
logout(:user)
delete_user = FactoryGirl.create(:user)
login_as(delete_user, :scope => :user)
post_to_delete = Post.create(date: Date.today, rationale: 'rationale', user_id: delete_user.id)
visit posts_path
click_link("delete_post_#{post_to_delete.id}_from_index")
expect(page.status_code).to eq(200)
end
end
describe 'creation' do
before do
visit new_post_path
end
it 'has a new form that can be reached' do
expect(page.status_code).to eq(200)
end
it 'can be created from a new form page' do
fill_in 'post[date]', with: Date.today
fill_in 'post[rationale]', with: "Some rationale"
click_on "Save"
expect(page).to have_content("Some rationale")
end
it 'will have a user associated with it' do
fill_in 'post[date]', with: Date.today
fill_in 'post[rationale]', with: "User Association"
click_on "Save"
expect(User.last.posts.last.rationale).to eq("User Association")
end
end
describe 'edit' do
it "can be edited" do
visit edit_post_path(post)
fill_in 'post[date]', with: Date.today
fill_in 'post[rationale]', with: "Edited content"
click_on "Save"
expect(page).to have_content("Edited content")
end
it "cannot be edited by a non authorized user" do
logout(:user)
non_authorized_user = FactoryGirl.create(:non_authorized_user)
login_as(non_authorized_user, :scope => :user)
visit edit_post_path(post)
expect(current_path).to eq(root_path)
end
end
end
I review the views/post/_form.html.erb file:
<%= form_for #post, class: "form-horizontal" do |f| %>
<% if #post.errors.any? %>
<% #post.errors.full_messages.each do |error| %>
<%= js add_gritter(error, title: "Overtime App Notification", sticky: false, image: :notice) %>
<% end %>
<% end %>
<div class="form-group">
<%= f.label :date, class: "col-sm-2 control-label" %>
<%= f.date_field :date, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :rationale, class: "col-sm-2 control-label" %>
<%= f.text_area :rationale, class: "form-control" %>
</div>
<%= render partial: 'status', locals: {f: f} if current_user.type == 'AdminUser' %>
<%= f.submit 'Save', class: 'btn btn-primary btn-block' %>
<% end %>
I can't tell what is going wrong here. If I inspect element, it's there:
This is my post.rb model file:
class Post < ActiveRecord::Base
enum status: {submitted: 0, approved: 1, rejected: 2}
belongs_to :user
validates_presence_of :date, :rationale
scope :posts_by, ->(user) {where(user_id: user.id)}
end
The tests were passing yesterday, not sure what happened.
You're calling login_as with #user, but #user is never defined, you probably want login_as(user).
Always try to retrace your steps, if something was working before, think about what code you introduced between the last time it worked and when it began failing.
Checking status codes is generally a bad smell for feature tests, just check for things the user can see.
Don't use the eq matcher with current_path instead use the have_current_path matcher provided by Capybara.
I have a Rspec Test im trying to run. It did the test manually and once you click Create Size it definitely goes to sizes_path. Why is it going to root url?
Error is
Failure/Error: expect(current_path).to eql(sizes_path)
expected: "/sizes"
got: "/"
(compared using eql?)
Test is
require "rails_helper"
require "when_authenticated.rb"
RSpec.feature "adding size" do
let(:size01) { FactoryGirl.build :size01 }
let(:user) { FactoryGirl.build :user }
let(:admin) { FactoryGirl.create(:user, admin: true, password: "Password18") }
scenario "allow a admin user to add a size" do
admin_logged_in
visit new_size_path
fill_in 'Title', with: 'example'
click_button 'Create Size'
expect(current_path).to eql(sizes_path)
expect(page).to have_content("example")
expect(page).to have_content("You have created a new size")
end
scenario "user can't add size" do
user_logged_in
visit sizes_path
expect(current_path).to eql(root_path)
end
scenario "vistor can't add size" do
visit sizes_path
expect(current_path).to eql(root_path)
end
end
Here is my Create Method in Sizes controller
def create
#size = Size.new(size_params)
if #size.save
redirect_to sizes_path
flash[:success] = "You have created a new size"
else
render 'new'
end
end
New View
<center><h1>Create A New Size</h1></center>
<div class="container">
<div class=“row”>
<div class="col-md-6 col-md-offset-3">
<div class="panel panel-primary">
<div class="panel-body">
<%= simple_form_for #size do |f| %>
<%= f.input :title %>
<%= f.button :submit, "Create Size", class: "btn btn-primary" %>
<% end %>
</div>
</div>
</div>
</div>
</div>
The problem was with the way my admin
Here is the fix in total
require "rails_helper"
# require "when_authenticated.rb"
RSpec.feature "adding size" do
let(:size01) { FactoryGirl.build :size01 }
let(:user) { FactoryGirl.build :user }
let(:admin) { FactoryGirl.create(:user, admin: true, password: "Password18" ) }
def admin_logged_in
visit login_path
fill_in 'Email', with: admin.email
fill_in 'Password', with: admin.password
click_button 'Log In'
end
def user_logged_in
visit login_path
fill_in 'Email', with: user.email
fill_in 'Password', with: user.password
click_button 'Log In'
end
scenario "allow a admin user to add a size" do
admin_logged_in
visit new_size_path
fill_in 'Title', with: 'example'
click_button('Create Size')
expect(current_path).to eql(sizes_path)
expect(page).to have_content("List Of Sizes")
expect(page).to have_content("You have created a new size")
end
scenario "user can't add size" do
user_logged_in
visit sizes_path
expect(current_path).to eql(root_path)
end
scenario "vistor can't add size" do
visit sizes_path
expect(current_path).to eql(root_path)
end
end
I have a Rspec Test im trying to run. It did the test manually and once you click Create Size it definitely goes to sizes_path. Why is it going to root url?
Error is
Failure/Error: expect(current_path).to eql(sizes_path)
expected: "/sizes"
got: "/"
(compared using eql?)
Test is
require "rails_helper"
require "when_authenticated.rb"
RSpec.feature "adding size" do
let(:size01) { FactoryGirl.build :size01 }
let(:user) { FactoryGirl.build :user }
let(:admin) { FactoryGirl.create(:user, admin: true, password: "Password18") }
scenario "allow a admin user to add a size" do
admin_logged_in
visit new_size_path
fill_in 'Title', with: 'example'
click_button 'Create Size'
expect(current_path).to eql(sizes_path)
expect(page).to have_content("example")
expect(page).to have_content("You have created a new size")
end
scenario "user can't add size" do
user_logged_in
visit sizes_path
expect(current_path).to eql(root_path)
end
scenario "vistor can't add size" do
visit sizes_path
expect(current_path).to eql(root_path)
end
end
Here is my Create Method in Sizes controller
def create
#size = Size.new(size_params)
if #size.save
redirect_to sizes_path
flash[:success] = "You have created a new size"
else
render 'new'
end
end
New View
<center><h1>Create A New Size</h1></center>
<div class="container">
<div class=“row”>
<div class="col-md-6 col-md-offset-3">
<div class="panel panel-primary">
<div class="panel-body">
<%= simple_form_for #size do |f| %>
<%= f.input :title %>
<%= f.button :submit, "Create Size", class: "btn btn-primary" %>
<% end %>
</div>
</div>
</div>
</div>
</div>
For some reason admin wasn't being created properly. Here is the fix.
require "rails_helper"
RSpec.feature "adding size" do
let(:size01) { FactoryGirl.build :size01 }
let(:user) { FactoryGirl.build :user }
let(:admin) { FactoryGirl.create(:user, admin: true, password: "Password18" ) }
def admin_logged_in
visit login_path
fill_in 'Email', with: admin.email
fill_in 'Password', with: admin.password
click_button 'Log In'
end
def user_logged_in
visit login_path
fill_in 'Email', with: user.email
fill_in 'Password', with: user.password
click_button 'Log In'
end
scenario "allow a admin user to add a size" do
admin_logged_in
visit new_size_path
fill_in 'Title', with: 'example'
click_button('Create Size')
expect(current_path).to eql(sizes_path)
expect(page).to have_content("List Of Sizes")
expect(page).to have_content("You have created a new size")
end
scenario "user can't add size" do
user_logged_in
visit sizes_path
expect(current_path).to eql(root_path)
end
scenario "vistor can't add size" do
visit sizes_path
expect(current_path).to eql(root_path)
end
end
I ran rspec on some tests I created and here is the output I received.
Failures:
1) User pages signup with valid information should create a user
Failure/Error: fill_in "Name", with: "Example User"
Capybara::ElementNotFound:
Unable to find field "Name"
# ./spec/requests/user_pages_spec.rb:18:in `block (4 levels) in <top (required)>'
2) User pages signup with invalid information should not create a user
Failure/Error: expect { click_button submit }.not_to change(User, :count)
Capybara::ElementNotFound:
Unable to find button "Create my account"
# ./spec/requests/user_pages_spec.rb:12:in `block (5 levels) in <top (required)>'
# ./spec/requests/user_pages_spec.rb:12:in `block (4 levels) in <top (required)>'
Here is my rspec code for user_pages_spec.rb
require 'spec_helper'
describe "User pages" do
subject { page }
describe "signup" do
let(:submit) { "Create my account" }
describe "with invalid information" do
it "should not create a user" do
expect { click_button submit }.not_to change(User, :count)
end
end
describe "with valid information" do
before do
fill_in "Name", with: "Example User"
fill_in "Email", with: "user#example.com"
fill_in "Password", with: "foobar"
fill_in "Confirmation", with: "foobar"
end
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
end
end
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
before { visit user_path(user) }
it { should have_content(user.name) }
it { should have_title(user.name) }
end
describe "signup page" do
before { visit signup_path }
it { should have_content('Sign up') }
it { should have_title(full_title('Sign up')) }
end
end
Now, to show you my html page
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(#user) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.text_field :password %>
<%= f.label :password_confirmation %>
<%= f.text_field :password_confirmation %>
<%= f.submit "Create my account", class: "btn btn-large btn-primary" %>
<% end %>
</div>
</div>
In this example, clearly you can find a text-field named "Name" and a button "Create my account". I'm baffled at how rspec saw errors.
Can anyone help me?
Edit: Maybe it didn't work because I haven't defined a create method in my UsersController
class UsersController < ApplicationController
def new
#user = User.new
end
def show
#user = User.find(params[:id])
end
end
You are not actually going to any page before you start trying to fill in the form.
At the beginning of the test you will need a visit statement. Something like:
describe "User pages" do
subject { page }
describe "signup" do
before { visit new_user_path }
...