Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

autocomplete method refuses to fire in RSpec test

I am on Day 4 of trying to get an autocomplete field to fire in an RSpec test. Works super in the browser, it is just incredibly resistant to running in my request specs.


UPDATE: It looks like my RSpec/Capy scripts are running against the dev db instead of the test db. I'm using Pow, so I don't know what to set default_url_options[:host] or Capybara.app_host and Capybara.server_port to. I have a feeling if I fix this, it may work.


The stack is:

  • Rails 3.2.16
  • Capybara
  • RSpec
  • Poltergeist/PhantomJS
  • Pow
  • Zeus
  • Factory Girl

Click links, click buttons, fill_in fields all work great. But when it comes time to get this autocomplete to work, it absolutely refuses to work.

I am using this method:

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

which I found here. The screenshot line is my own. But the line above:

  page.should have_selector('ul.ui-autocomplete li.ui-menu-item a')

returns false. It works like a charm in the browser. I just can't for the life of me figure out why it won't work. I have tried everything I know how. How can I debug this?

The screenshot just shows the page I am expecting, with the field filled in appropriately. I even tested this with a "hello" alert that I inserted into the autocomplete call. Works flawlessly in the browser, but no result at all in the test.

In short, it looks like the following two lines are having no effect:

  page.execute_script %Q{ $("##{field}").trigger('focus') }
  page.execute_script %Q{ $("##{field}").trigger('keydown') }
like image 423
AKWF Avatar asked Dec 29 '13 03:12

AKWF


Video Answer


1 Answers

I had a similar problem and even though Capybara's documentation says that have_selector will wait for the AJAX call to complete, it did not work for me.

The following worked in my case:

def fill_in_autocomplete(field_label, field_class, options = {})
  field_id = "##{page.evaluate_script("$('#{field_class}').attr('id')")}"

  selector = "ul.ui-autocomplete li.ui-menu-item a"

  fill_in(field_label, with: options[:with])
  page.execute_script("$('#{field_id}').trigger('focus')")
  page.execute_script("$('#{field_id}').trigger('keydown')")

  sleep(2) # Hack! not sure why the line below isn't working...
  #expect(page).to have_selector(selector, text: options[:with])

  page.execute_script("$('#{selector}').click()")
end

You can call the method above like this:

fill_in_autocomplete('Some label', '.js-some-field', with: 'Some value'

I didn't want to pass the field ID and opted for a class instead, which is why the first line in the helper gets the ID based on the element's class.

like image 144
Xaid Avatar answered Oct 10 '22 19:10

Xaid