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 %>
- Buy Milk
--------| 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
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
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
Notice the lowercase
milk compared with the capital
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!
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.
When I run
/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: https://github.com/bjlinville1/upcase_tdd_trail/blob/working-branch/spec/features/user_creates_todo_spec.rb
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]
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.
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.
<% 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.
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.