Signing In and Todo Ownership


This is a companion discussion topic for the original entry at https://thoughtbot.com/upcase/videos/signing-in-and-todo-ownership

Failure/Error: expect(page).not_to_have_css ā€œliā€, text: ā€œBuy milkā€
NoMethodError:
undefined method `not_to_have_cssā€™ for #RSpec::Expectations::ExpectationTarget:0x007fa42d82f860

Does anyone know how to solve this? Thanks!

Looks like you may have a stray underscore (instead of a space) between not_to and have_css.

Instead, try: expect(page).not_to have_css "li", text: "Buy milk"

1 Like

Thanks, that solved it

Showing ā€“ uninitialized constant Features (NameError). Did everything as like workshop.
in spec_helper added
config.include Features, type: :feature
created spec/support/features/sign_in.rb
module Features
def sign_in
end
end

can anybody help me why showing this message while running rake?

I found that the issue is a result of the ā€˜spec/support/features/sign_in.rbā€™ not being loaded, with two ways to fix.

In file ā€˜spec/rails_helper.rbā€™ either:

Uncomment the line (which has a warning right above it to read!)

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

or add:

require 'support/features/sign_in'
3 Likes

I had the same error but instead of uncommenting I had to comment out the line:

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

and also add:

require 'support/features/sign_in'
1 Like

Same error here. Added:

  require 'support/features/sign_in'

into the rails_helper.rb just under the line

require 'rspec/rails'

and it seems to work.

2 Likes

To tack on to this discussion, I couldnā€™t get database_cleaner to work until I added:

require 'support/database_cleaner'

to rails_helper.rb.

1 Like

Had the same errorā€¦ read this article by Thoughtbot and fixed it in a slightly different wayā€¦ but as we all have found outā€¦

ā€œModules must be explicitly included to share the common code between integration tests.ā€ ā€“ from the post

per the article, I created a file "spec/support/features.rb and put the configure block in it:

RSpec.configure do |config|
   config.include Features, type: :feature
end

Rather than

expect(page).not_to have_css ".todos li", text: "Buy milk"

I went with

expect(page).not_to have_content "Buy milk"

as otherwise if someone changed the structure of the HTML then even if the scoping was broken the assertion would always report that the ā€œBuy milkā€ todo was not present, even if it was.

When Joshua runs rake at 13:45 his suite passes but Iā€™m getting a failure in user_visits_homepage_spec.rb:

Failures:

  1) user visits homepage successfully
     Failure/Error: expect(page).to have_css('h1', text: 'Todos')
       expected to find css "h1" with text "Todos" but there were no matches
     # ./spec/features/user_visits_homepage_spec.rb:7:in `block (2 levels) in <top (required)>'

Finished in 0.21215 seconds (files took 1.47 seconds to load)
2 examples, 1 failure

This is because now that I have before_filter :authenticate in TodosController, the test is resulting in a redirect to the login page. When I added sign_in at the top of the scenario in usere_visits_homepage_spec.rb the test passed, but I donā€™t understand how Joshuaā€™s passed without it.

when i run rspec spec/features/user_sees_own_todos_spec.rb. i now get cannot load errors

usr/local/rvm/gems/ruby-2.0.0-p247/gems/rspec-core-3.0.4/lib/rspec/core/configuration.rb:1058:in load': cannot load such file -- /Users/neilpatel/Desktop/Rails/todos/spec/features/user_sees_own_todos_spec.rb (LoadError) from /usr/local/rvm/gems/ruby-2.0.0-p247/gems/rspec-core-3.0.4/lib/rspec/core/configuration.rb:1058:in block in load_spec_filesā€™
from /usr/local/rvm/gems/ruby-2.0.0-p247/gems/rspec-core-3.0.4/lib/rspec/core/configuration.rb:1058:in each' from /usr/local/rvm/gems/ruby-2.0.0-p247/gems/rspec-core-3.0.4/lib/rspec/core/configuration.rb:1058:in load_spec_filesā€™
from /usr/local/rvm/gems/ruby-2.0.0-p247/gems/rspec-core-3.0.4/lib/rspec/core/runner.rb:97:in setup' from /usr/local/rvm/gems/ruby-2.0.0-p247/gems/rspec-core-3.0.4/lib/rspec/core/runner.rb:85:in runā€™
from /usr/local/rvm/gems/ruby-2.0.0-p247/gems/rspec-core-3.0.4/lib/rspec/core/runner.rb:70:in run' from /usr/local/rvm/gems/ruby-2.0.0-p247/gems/rspec-core-3.0.4/lib/rspec/core/runner.rb:38:in invokeā€™
from /usr/local/rvm/gems/ruby-2.0.0-p247/gems/rspec-core-3.0.4/exe/rspec:4:in <top (required)>' from /usr/local/rvm/gems/ruby-2.0.0-p247/bin/rspec:23:in loadā€™
from /usr/local/rvm/gems/ruby-2.0.0-p247/bin/rspec:23:in `ā€™

worked normally before adding the database cleaner

group :test do
  gem 'capybara', '~> 2.3.0'
  gem 'database_cleaner'
end

rails_helper

ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'support/database_cleaner'

user_sees_own_todos.rb
require ā€œrails_helperā€

    feature "User sees own todos" do
      scenario "doesn't see others todos" do
        Todo.create!(title: "Buy milk", email: "someone_else@example.com")
    
        sign_in_as "someone@example.com"
    
        expect(page).not_to have_css ".todos li", text: "Buy milk"
      end
    end

database cleaner.rb

RSpec.configure do |config|
  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

Apologies!

should be user_sees_own_todos_spec.rb

not

user_sees own_todos_spec.rb

missed the _

which is why its not loading

I get the following error:

NoMethodError:
     #   undefined method `each' for nil:NilClass
     #   ./app/views/todos/index.html.erb:4:in `_app_views_todos_index_html_erb__361575219782891095_70096114210620'

class TodosController < ApplicationController
  before_filter :authenticate

  def index
    @todos = Todo.where(email: session[:current_email])
  end

  def new
    @todo = Todo.new
  end

  def create
    Todo.create(todo_params.merge(email: session[:current_email]))
    redirect_to todos_path
  end

  private

  def todo_params
    params.require(:todo).permit(:title)
  end
end

views/todos/index.html.erb

<%= link_to "Add a new todo", new_todo_path %>

<ul class="todos">
  <% @todos.each do |todo| %>
    <li><%= todo.title %></li>
  <% end %>
</ul>

routes.rb

Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  root to: "todos#index"

  resources :todos, only: [:index, :new, :create]

  resource :session, only: [:new, :create]
end

rails_helper.rb

require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
require 'support/features/sign_in'
require 'support/database_cleaner'

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|

  config.use_transactional_fixtures = false

  # RSpec Rails can automatically mix in different behaviours to your tests
  # based on their file location, for example enabling you to call `get` and
  # `post` in specs under `spec/controllers`.
  #
  # You can disable this behaviour by removing the line below, and instead
  # explicitly tag your specs with their type, e.g.:
  #
  #     RSpec.describe UsersController, :type => :controller do
  #       # ...
  #     end
  #
  # The different available types are documented in the features, such as in
  # https://relishapp.com/rspec/rspec-rails/docs
  config.infer_spec_type_from_file_location!

  # Filter lines from Rails gems in backtraces.
  config.filter_rails_from_backtrace!
  # arbitrary gems may also be filtered via:
  # config.filter_gems_from_backtrace("gem name")
  config.include Features, type: :feature
end

Change before_filter to before_action and it should work, I guess you are using a newer version of Rails than the one he is using on the vid.

Thanks this really worked well for me

at 22:10 they run the feature test and they get a failure. mine passes, not sure if this is an issue with me using a newer version of rails or if i have something written out wrong, but from what i can tell all of the code is the same.

iā€™m happy to have passing tests, but i think that defeats the purpose of this video!

For anyone doing this in 2020, instead of using ā€˜before_filterā€™ (introduced at 6.05 in video) you must use ā€˜before_actionā€™ instead. ā€˜before_filterā€™ has been removed from Rails and your application will crash otherwise. (Must likely youā€™ll get an undefined ā€˜eachā€™ method)