Creating the First Todo


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

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ā€¦

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.

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!

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.

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

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?

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: upcase_tdd_trail/user_creates_todo_spec.rb at working-branch Ā· uncl3-b3nny/upcase_tdd_trail Ā· GitHub

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

Check this out

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

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

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.

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

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

1 Like

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?

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.

Hey, when you have an ERB tag with an equal sign, i.e. <%= @foo %>, it displays something to the screen. As you saw in your example, if you donā€™t include it within the opening form tag, then the form wonā€™t be shown.

Check this out: https://stackoverflow.com/questions/7996695/what-is-the-difference-between-and-in-erb-in-rails.

Right, but why do I get an error when the ā€œendā€ tag has an =?

Itā€™s a syntax error ā€“ end tags just arenā€™t supposed to have equal signs.