← Back to Upcase

Creating the First Todo


(Upcase ) #1

This is a companion discussion topic for the original entry at https://thoughtbot.com/upcase/videos/creating-the-first-todo

(Greg Zentkovich) #2

That was frustrating! Just spent 30 minutes trying to finish my first todo (rails testing) and capybara was not giving it to me…

----| index.html.erb snippet |------

    <% @todos.each do |todo| %>
  • <%= todo.title %>
  • <% end %>

    --------| user_create_todo_spec.rb snippet |------
    expect(page).to have_css “.todos li”, text: “Buy Milk”


    which gave me: 1) User creates Todo Successfully
    Failure/Error: expect(page).to have_css “li”, text: "Buy Milk"
    expected to find css “li” with text “Buy Milk” but there were no matches. Also found “Buy milk”, “Buy milk”, “Buy milk”, “Buy milk”, “Buy milk”, “Buy milk”, “Buy milk”, “Buy milk”, “Buy milk”, “Buy milk”, “Buy milk”, “Buy milk”, which matched the selector but not all filters.
    # ./spec/features/user_creates_todo_spec.rb:11:in `block (2 levels) in <top (required)>’

    Finished in 0.19207 seconds (files took 1.67 seconds to load)
    1 example, 1 failure


    I tried:
    expect(page).to have_css “.todos li”, text: “Buy Milk”, visible: "false"
    this gave me the same test fail message…

    expect(page).to have_css “li”, text: "Buy Milk"
    removed the class from ul, still same message

    expect(page).to have_selector “.todos li”, text: "Buy Milk"
    no dice… same fail…

    finally had to just put

  • Buy Milk
  • and it passed… kind of defeats the purpose… I am running capybara 2.44 probably some kind of bug but too tired to research…


(Robert Eshleman) #3

A little hard to read your post, because it’s not formatted with markdown code blocks, but it looks like your trouble may be with case-sensitivity.

Note your error message (which I’ve de-duplicated for readability):

This failure says that there were no exact matches for css "li" with text "Buy Milk", but there were items on the page which matched the selector but not all filters.

In other words, there are li elements on the page, but none with the filter you specified. (In this case, your filter is text "Buy Milk"). Based on the other selectors that were Also found, it looks like the page only has li selectors with the text "Buy milk".

Notice the lowercase m in milk compared with the capital M in Milk in your expectation. Capybara is case-sensitive when matching this kind of text.


(Greg Zentkovich) #4

Wow! the was so simple to fix… and so easily missed… I guess it takes a experienced and trained eye… Buy milk and Buy Milk. Case-sensitive…hmm. Thanks for going the extra mile (i.e. deciphering my spaghetti code)… I had to have that green! :grinning:
Thanks!


(Thomas Nys) #5

I installed the last versions of both capybara and RSpec and I’m not getting the same warnings when interacting trough the feauture. For example when altering the view I should get a warning of a non existing path. I seems like I am only getting warnings about a view elements.


(Thomas Nys) #6

Nevermind I restarted config from scratch and everything was working as expected. :slight_smile:


(Ben Akroyd) #7

When I run

rspec spec/features/user_creates_todo_spec.rb

I get

/usr/lib/ruby/vendor_ruby/bundler/runtime.rb:34:in `block in setup’: You have already activated rspec-support 3.4.1, but your Gemfile requires rspec-support 3.0.4. Prepending “bundle exec” to your command may solve this. (Gem::LoadError)

Indeed, when I prepend the command with “bundle exec” it works. However, when I went to correct the gemfile, there wasn’t an obvious place to correct. Any insight as to what I should change so that my initial command will execute cleanly?


(Ben Linville) #8

My test passes when it shouldn’t. (I fill_in “Buy milk” and expect “Buy bread”) Anybody care to help me understand why rspec isn’t checking the li’s text to make sure its a match?
Here’s my code: https://github.com/bjlinville1/upcase_tdd_trail/blob/working-branch/spec/features/user_creates_todo_spec.rb


(Joseph Crocetta) #10

I hit the wrong reply button.
Are you clearing out your database after every test?


(Joseph Crocetta) #11

Check this out


(Ben Linville) #12

That would make sense. I originally had them matching, so the db would have a few objects that pass. Thanks!


(Daniel Uribe) #13

Great explanation. I had a similar issue to and cleared it up with after thinking the problem was something else.


(Denis Hovart) #14

Thanks for this serie.
I am nitpicking a bit, but the HTTP spec requires a fully qualified URL when doing 302 redirects. For this reason DHH recommends using model_url instead of model_path with redirect_to in Agile Web Development with Rails.


(Wade Carlson) #15

Not sure why I am getting this error when I run bundle exec rspec I’ve tried to google it but can’t seem to find the solution. Any guidance would be great! Just signed up today, thanks!

Failure/Error: click_on “Add a new todo”

 Capybara::ElementNotFound:
   Unable to find link or button "Add a new todo"

Test Code - /spec/features/user_creates_todo_spec.rb

require "rails_helper"

feature "User creates todo" do
  scenario "succesfully" do
    click_on "Add a new todo"
    fill_in "Title", with: "Buy milk"
    click_on "Submit"

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

Index - app/views/index.html.erb

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

Routes are good to go - config/routes.rb

Rails.application.routes.draw do
root to: "todos#index"
resources :todos, only: [:new, :create]

end

Controller looks good to go -

class TodosController < ApplicationController
def index
end

def new
  @todo = Todo.new
end
end

Gem file -

group :development, :test do
gem 'rspec-rails', '~> 3.5'
gem 'byebug', platform: :mri
end

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

(Joseph Crocetta) #16

Just skimmed over your issue but looks like you never visited the page in your test.


(mciul) #17

My new template is not rendering for some reason. I got an error that it was ‘Unable to find field “Title”’, so I ran the rails server and looked at the new page myself. Sure enough, it has the Application layout header but nothing from the new template.

app/views/layouts/application.html.erb:

<!DOCTYPE html>
<html>
<head>
  <title>Todos</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>
<body>

  <h1>Todos</h1>
  <%= yield %>

</body>
</html>

app/views/todos/new.html.erb:

<% form_for @todo do |form| %>
  <%= form.label :title %>
  <%= form.text_field :title %>
<% end %>

What am I doing wrong?


(mciul) #18

I think I figured it out. It was the wrong choice of erb tags in the new page - the “form_for” line needs an =, while the “end” tag will throw an error if it has an =. I don’t really understand why, though.