Harish
Harish

Reputation: 1519

Capybara::ElementNotFound: Unable to find any css element

I am writing Capybara tests and one of the test case is to "Delete" a post and I am getting this error constantly. Any help?

 Failure/Error:
   within "#post_#{post.id}" do
    click_link 'Delete'
   end

 Capybara::ElementNotFound:
   Unable to find css "#post_8"

Code

require 'rails_helper'

feature "Deleting a Post" do
    let(:user) { FactoryGirl.create(:user) }
    let(:blog) { FactoryGirl.create(:blog, user: user) }
    let(:post) { FactoryGirl.create(:post, blog: blog) }

    before do
        visit new_user_session_path

        fill_in('Email', with: user.email)
        fill_in('Password', with: user.password)

        click_on("Log in")
    end

    scenario "should delete a post" do

        visit posts_path(blog.url_slug)

        within "#post_#{post.id}" do #### Not able to find this element
            click_link 'Delete'
        end

        expect(page).not_to have_content(page.title)
        expect(Post.count).to eq(0)

    end

end

HTML

<div>
    <% @posts.each do |post| %>
        <div class="well well-lg">
            <div class="row" id="<%= dom_id(post) %>" >
                    <div class="col-md-2">
                        <%= image_tag @blog.user.gravatar(100) %>
                    </div>

                    <div class="col-md-10">
                        <h2>
                            <%= link_to post.title, "#" %>
                        </h2>
                        <p>
                            <%= @redcarpet.render(post.content).html_safe %>
                        </p>
                        <% if @user_have_access %>
                            <%= link_to edit_post_path(@blog.url_slug, post.id), id: post.id do %>
                                Edit
                                <span class="glyphicon glyphicon-pencil space"></span>
                            <% end %>
                            <%= link_to delete_post_path(@blog.url_slug, post.id), method: :delete, 
                                data: { confirm: 'Are you sure?' } do %>
                                Delete
                                <span class="glyphicon glyphicon-trash space"></span>
                            <% end %>
                        <% end %>
                        <%= link_to comments_path(@blog.url_slug, post.id) do %>
                            Comments
                            <span class="glyphicon glyphicon-comment"></span>
                        <% end %>
                    </div>
            </div>
        </div>
    <% end %>
</div>

Gemfile

source 'https://rubygems.org'
ruby "2.3.1"

gem 'rails', '4.2.2'
gem 'mysql2', '~> 0.3.18'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'jquery-rails'
gem 'turbolinks'
gem "figaro"
gem 'bootstrap-sass', '~> 3.2.0'
gem 'devise'
gem 'aws-sdk', '~> 2.3'
gem "paperclip", "~> 5.0.0"
gem 'puma'
gem 'simple_form'
gem 'redcarpet'
gem 'rails_12factor'

group :test do
    gem 'rspec-rails'
    gem 'factory_girl_rails'
    gem 'faker'
    gem 'database_cleaner'
end

group :development do

  gem 'pry'
  gem 'byebug'
  gem 'capybara'

end

When I try to take a screenshot using save_and_open_screenshot, I get the following error

Capybara::NotSupportedByDriverError Exception: Capybara::Driver::Base#save_screenshot

Here is the screenshot of my DOM

enter image description here

Upvotes: 3

Views: 5566

Answers (2)

Thomas Walpole
Thomas Walpole

Reputation: 49880

let lazily defines variables, which means the value isn't actually set (and in this case the Post object) until its first use. In your case the first use isn't until the within statement, which means the record isn't created until after the page is rendered (during the visit call) and therefore the item isn't actually on the page. If you need the record to be available from the time you define it you should use let!.

The reason for the NotSupportedByDriver exception is that you are using the default rack-test driver which has no concept of screen (and no support for JS) and no real CSS support and therefore doesn't implement screenshot

Upvotes: 1

Harish
Harish

Reputation: 1519

So I found what the problem is. The PostsController#index is being called before the creation of post. Hence the DOM is not populated and it was not able to find the elements. After I moved the creation inside the scenario block. It started working as expected.

    require 'rails_helper'

feature "Deleting a Post" do
    let(:user) { FactoryGirl.create(:user) }
    let(:blog) { FactoryGirl.create(:blog, user: user) }
    let(:post) {FactoryGilr.create(:post, blog: blob} ### This doesn't create post yet. I am not sure why.

    before do
        visit new_user_session_path

        fill_in('Email', with: user.email)
        fill_in('Password', with: user.password)

        click_on("Log in")
    end

    scenario "should delete a post" do

        ### If I put my post creation here, it does work though.
        post = FactoryGirl.create(:post, blog: blog)

        visit posts_path(blog.url_slug)

        within "#post_#{post.id}" do
            click_link 'Delete'
        end

        expect(page).not_to have_content(post.title)
        expect(Post.count).to eq(0)

    end

end

Upvotes: 1

Related Questions