Search code examples
jqueryruby-on-railsrspeccapybarapoltergeist

Capybara/Poltergeist can't select from a jQuery autocomplete field


I have a problem with selecting from autocomplete field with Capybara.

I have next code:

def choose_autocomplete_result(text, input_id="input[data-autocomplete]")
  page.execute_script %Q{ $('#{input_id}').trigger("focus") }
  page.execute_script %Q{ $('#{input_id}').trigger("keydown") }
  sleep 1
  page.execute_script %Q{ $('.ui-menu-item a:contains("#{text}")').trigger("mouseenter").trigger("click"); }
end

And I have next test:

scenario 'Check autocomplete', js: true do
  find('.prop_address').native.send_keys 'lond'
  choose_autocomplete_result 'London', '.commercial_property_addresses_attributes_0_address'
  expect(page).to have_text('Some text')
end

And the error is:

Failure/Error: find('#output').find('div').trigger('click')

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

Also I tried next test:

scenario 'Check autocomplete', js: true do
  fill_autocomplete('.prop_address', with: 'lond', select: 'London')
  expect(page).to have_text('Some text')
end

With next method:

def fill_autocomplete(css_id, options = {})
  find("#{css_id}").native.send_keys options[:with]
  page.execute_script %{ $('#{css_id}').trigger('focus') }
  page.execute_script %{ $('#{css_id}').trigger('keydown') }
  selector = %{ul.ui-autocomplete li.ui-menu-item:contains("#{options[:select]}")}
  expect(page).to have_selector('ul.ui-autocomplete li.ui-menu-item')
  page.execute_script %{ $('#{selector}').trigger('mouseenter').click() }
end

In this way error is:

Failure/Error: expect(page).to have_selector('ul.ui-autocomplete li.ui-menu-item')
       expected to find css "ul.ui-autocomplete li.ui-menu-item" but there were no matches

In both variants the form is filled in with 'lond', but no one of the available variants is not selected.

Thanks!


Solution

  • I'm not sure what you're trying to accomplish with all the execute_script stuff. Assuming you're using the jQueryUI autocomplete all that should be required is to send keys to the text input and then click on the shown choice. So your method should just be

    def fill_autocomplete(css_selector, options = {})
      find(css_selector).send_keys options[:with]   # No .native. needed
      find("ul.ui-autocomplete li.ui-menu-item", text: options[:select]).click()
    end
    

    Here's a gist you can run showing it working - https://gist.github.com/twalpole/a12aeef278c9c714b9e078ce2adfda99