I think you can do this with rack-test
https://github.com/brynary/rack-test
in your Gemfile:
gem 'rack-test'
in your env.rb file
module CapybaraApp
def app; Capybara.app; end
end
World(CapybaraApp)
World(Rack::Test::Methods)
step defintions somewhere:
When /^I send a POST request to "([^"]*)"$/ do |path|
post path
end
Most of what I learned came from here: http://www.anthonyeden.com/2010/11/testing-rest-apis-with-cucumber-and-rack-test
UPDATE: I think you can skip the changes to your env.rb file with newer versions of Rails and/or Cucumber (not sure which, I just don't do that part on my newer projects and it works fine)
Finally got autocomplete tests working at least with the Selenium driver.
The solution is to put focus on the field and issue a keydown event.
I confirmed this first with manual testing in a browser. If I use the mouse (not Ctrl-V) to paste a search term into an autocomplete field, nothing happens--no drop-down pick list is displayed. This is apparently the equivalent of what happens when Capybara sends a fill_in command. However, after the term is in the field, while focus is still on the field, if I touch any key, e.g. the Shift key, the pick list appears. So apparently the pick list only appears when a key is pressed.
Option 1
One solution is to extend the function from the original question as follows:
def fill_autocomplete(field, options = {})
fill_in field, :with => options[:with]
page.execute_script %Q{ $('##{field}').trigger("focus") }
page.execute_script %Q{ $('##{field}').trigger("keydown") }
selector = "ul.ui-autocomplete a:contains('#{options[:select]}')"
page.should have_selector selector
page.execute_script "$(\"#{selector}\").mouseenter().click()"
end
and then call it like this:
fill_autocomplete "to_contact_name", with: "Jone", select: "Bob Jones"
Option 2
A similar approach, adapted from the Steak test in the main rails3-jquery-autocomplete gem, uses the standard fill_in, followed by this choose_autocomplete_result:
def choose_autocomplete_result(item_text, input_selector="input[data-autocomplete]")
page.execute_script %Q{ $('#{input_selector}').trigger("focus") }
page.execute_script %Q{ $('#{input_selector}').trigger("keydown") }
# Set up a selector, wait for it to appear on the page, then use it.
item_selector = "ul.ui-autocomplete li.ui-menu-item a:contains('#{item_text}')"
page.should have_selector item_selector
page.execute_script %Q{ $("#{item_selector}").trigger("mouseenter").trigger("click"); }
end
which is called like this:
fill_in "to_contact_name", :with => "Jone"
choose_autocomplete_result "Bob Jones", "#to_contact_name"
I've adopted the second approach for my tests. It seems pretty reliable with Selenium but doesn't work with webkit, which is too bad, since the Selenium tests are quite slow by comparison. A solution that works under webkit would be welcome!
Best Answer
I like this much better.
https://github.com/jnicklas/capybara/blob/415e2db70d3b19b46a4d3d0fe62f50400f9d2b61/spec/rspec/matchers_spec.rb