Rails3-jquery-autocomplete: how to check with RSpec and Capybara?

I am using Rails 3.2.8 with

  • gem 'jquery-rails', '2.1.2'
  • gem 'rails3-jquery-autocomplete', '1.0.9'
  • gem 'rspec-rails', '2.11.4'
  • gem 'capybara', '1.1.3'
  • gem 'capybara-webkit', '0.12.1'

I recently converted a dropdown to autocomplete (using rails3-jquery-autocomplete) and am trying to update query specifications to populate autocomplete.

My approach was to create an assistant, as shown in this value :

def fill_autocomplete(field, options = {}) fill_in field, :with => options[:with] selector = "ul.ui-autocomplete a:contains('#{options[:select]}')" page.should have_selector selector page.execute_script "$(\"#{selector}\").mouseenter().click()" end 

If I test that using Webkit, the test fails with this message:

 expected css "ul.ui-autocomplete a:contains('Firstname Lastname')" to return something. 

If I test Selenium, as I watch the test continue in Firefox, I donโ€™t see a drop-down list. Adding sleep 3 to wait for a popup menu does not help.

I see here that there is a related, but somewhat old problem with capybara-webkit, something about when the field is filled, it is immediately blurred, which of course is so that the autocomplete list does not appear. But this does not seem to be bold with others who got it to work.

Can I currently validate a form containing a rails3-jquery-autocomplete field with RSpec and Capybara? How? If not, is there a way to manually fill in the corresponding hidden id field so that I can still verify that the form is creating the correct data?

+7
source share
5 answers

Finally, autocomplete tests were obtained that work with at least the Selenium driver.

The solution is to focus on the field and fire a keydown event.

I confirmed this first with manual testing in the browser. If I use a mouse (not Ctrl-V) to insert a search query into the autocomplete field, nothing happens - not a single drop-down list is displayed. This seems to be equivalent to what happens when Capybara sends the fill_in command. However, after the term is in the field, while the focus is still in the field, if I touch any key, for example. Shift key appears selection list. Thus, it is obvious that the selection list appears only 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 , basically the rails3-jquery-autocomplete gem, uses the standard fill_in followed by this select_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 took the second approach for my tests. This seems pretty reliable with Selenium, but it doesnโ€™t work with webkit, which is too bad since the Selenium tests are rather slow compared. A solution that works under webkit is welcome!

+9
source

I myself faced the same pain spot. After spending several hours on this, I have one good helper that works with both selenium and polstergeist plus without using sleep() . The following code has been tested with Capybara 2.1.0:

  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 = %Q{ul.ui-autocomplete li.ui-menu-item a:contains("#{options[:select]}")} page.should have_selector('ul.ui-autocomplete li.ui-menu-item a') page.execute_script %Q{ $('#{selector}').trigger('mouseenter').click() } end 

Basically, I tell Capybara to fill in the input field, then use JS to fire the keydown event to activate autocomplete. However, instead of sleep() I use page.should have_selector('ul.ui-autocomplete li.ui-menu-item a') , which are waiting for a drop-down list to appear. Then I use JS to fire the mouseenter event, and then click. I'm sorry that there is a better way than doing things with JS eval, but this is the most reliable solution I could come up with.

+3
source

If someone needs some kind of code for inspiration (took some time even after reading this topic), this works:

  context "with 5 items results" do before do 5.times { FactoryGirl.create(:item, title: "chinese " + random_string(5) ) } page.execute_script("$('input#search_param').val('chinese')") page.execute_script("$('input#search_param').trigger('focus')") page.execute_script("$('input#search_param').trigger('keydown')") end specify { page.evaluate_script("$('input#search_param').val()").should == 'chinese' } specify { page.should have_css "#autocomplete-menu li", count: 5 } end 

Thanks, Mark Berry, for the inspiration.

+2
source

Another option is the capybara send_keys method:

find('#my_object_id').send_keys 'bob'

I prefer this option for javascript input to trigger keydown / focus / mouseenter events.

+1
source

Instead of using page.execute_script, I filled the input blank after my input so that the event would fire.

 fill_in("query", :with => "ma") fill_in("query", :with => "") # autocomplete suggestions will come up all('.autocomplete div').first.should have_content("mango") # other assertions 
0
source

All Articles