trailblazer / rspec-cells

Spec your Cells.
http://cells.rubyforge.org
MIT License
62 stars 48 forks source link

Cannot use Capybara finders #21

Closed PikachuEXE closed 9 years ago

PikachuEXE commented 11 years ago

I am trying to write a test for a link for its attributes

Currently I am using

it {should have_css("a.btn[data-method='post'][href='#{some_path)}']")}

But it's too long and hard to read

So I have this:

subject do
  find_link(name)
end

it {should exist}

specify {subject[:href].should eq some_path}
specify {subject[:class].should eq '.btn'}
specify {subject['data-method'].should eq 'post'}

specify {subject[:rel].should eq :tooltip}
specify {subject[:title].should eq "Some Action"}

But find_link method is not defined

Actually I want to use have_link but the option only supports href

PikachuEXE commented 11 years ago

Now I am using some custom matcher:

# Source:
# https://groups.google.com/forum/?fromgroups=#!topic/ruby-capybara/v1h4npzN6OI

# Check for any <css> tag with _all_ of the specified attributes.
# Does _not_ check the text after the tag.
# Still returns true even if the tag has more attributes than those specified.
# Example:
#   it { should have_css_tag_and_attributes('div',
#        id: "left_sidebar", class: "span2") }
def has_selector_with_attributes?(selector, attributes = {})

  raise ArgumentError.new "attributes must be a hash with at least one element" if
      !attributes.is_a?(Hash) || attributes.empty?
  attr_string =  attributes.map{|k,v| "@#{k}='#{v}'"}.join(' and ')
  xpath = "//#{selector}[#{attr_string}]"
  has_xpath?(xpath, nil)

end

def has_link_with_attributes?(attributes = {})
  has_selector_with_attributes?(:a, attributes)
end

But I cannot use it with locator (id or link text)

alexandru-calinoiu commented 11 years ago

I ma having the same issues also

apotonick commented 11 years ago

Sorry guys, I don't get it - can you please reduce your issue to the minimum and give me that example? Thahanks!

PikachuEXE commented 11 years ago

Cannot use capybara finders such as find_link in rspec-cells I want to use it since I want to test some attributes of a link, not just href

alexandru-calinoiu commented 11 years ago

Or the following code sample fails with "no method defined have_link ..."

subject { cell }
visit user_path(user)
it { should have_link('Settings', href: edit_user_path(user)) }
alexandru-calinoiu commented 11 years ago

I got it, I had capybara only in the cucumber test group in the gemfile, once I've put it in test group also all was good, clue was in cell_example_group#15

PikachuEXE commented 11 years ago

I have capybara in test group all the time... Let me check it later :/

therealjasonkenney commented 10 years ago

If you do this first:

subject { Capybara::Node::Simple.new(render_cell(:cell_name, 'stuff')) }

You can use matchers with the subject

I noticed after updating rspec-cells, I had to do that for my tests. My suggestion is... a method that wraps either one in a capybara::node::simple if capybara is loaded.

therealjasonkenney commented 10 years ago

Found it!

You have to order the Gemfile so capybara is first! This is because ruby evaluates the module before Capybara is loaded at load time!

therealjasonkenney commented 10 years ago

I was going to try and do a patch and PR, however loading capybara causes everything to 'splode due to Rails.root being undefined. :( Am I doing something wrong? How do people test for WebRat and Capybara in gems like these?

seuros commented 10 years ago

the subject should be a capybara session, not a simplenode.

apotonick commented 10 years ago

Should we offer an alternative ::subject?

therealjasonkenney commented 10 years ago

subject is NOT something that should be specified in the lib. After all sometimes a subject is a cell, a node, a session, it's whatever is defined in the specific test as subject.

The current problem was render_cell was returning ActiveSupport::SafeBuffer rather than a Capybara::Simple::Node. (You can't return a session in a unit test without invoking a full browser emulation, which I thought is the domain of feature and request specs).

And this is mostly tied to the fact that the decision to include Capybara code in the gem is based on capybara being loaded first.

I think that route should be, just put the capybara code in rspec/cells/capybara and webrat respectively, then have people require it in the rspec helper.

I could make a PR, but again for the life of me I have no idea how to get capybara working in the test without stubbing out Rails.root, which seems wrong.

apotonick commented 10 years ago

Absolutely not, as long as it's only Rails.root this is totally fine.

Alternatively, you can use a dummy Rails app, I do this in all my gems that provide support for Rails. Here's an example of how that would work, it's really easy once you got the code: https://github.com/apotonick/kaminari-cells/blob/master/test/fake_app/rails_app.rb

Please PR - I personally do not use Rspec and am happy to merge your stuff. What do you think, @seuros ?

seuros commented 10 years ago

I will look into this today.

apotonick commented 9 years ago

Rspec-cells 0.3 always returns a Capybara::Node::Simple instance from ViewModel#call when Capybara is loaded, this should be fixed.