rails3-jquery-autocomplete:如何使用RSpec和Capybara进行测试?

Mar*_*rry 7 jquery rspec jquery-ui ruby-on-rails capybara

我正在使用Rails 3.2.8

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

我最近将选择下拉列表转换为自动完成(使用rails3-jquery-autocomplete),并且我正在尝试更新我的请求规范以填写自动完成.

我的方法是创建一个帮助如图这一要点:

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
Run Code Online (Sandbox Code Playgroud)

如果我使用Webkit测试,测试将失败并显示以下消息:

expected css "ul.ui-autocomplete a:contains('Firstname Lastname')" to return something.
Run Code Online (Sandbox Code Playgroud)

如果我用Selenium测试,当我看到在Firefox的测试继续,我也没有看到下拉选择列表中出现.添加sleep 3等待下拉列表无济于事.

我在这里看到capybara-webkit存在一个相关但有点旧的问题,关于何时填充字段,它会立即模糊,这当然会阻止自动完成选择列表出现.但这似乎与那些已经开始工作的人并不相符.

目前是否可以使用RSpec和Capybara测试包含rails3-jquery-autocomplete字段的表单?怎么样?如果没有,有没有办法手动填写相应的隐藏id字段,所以我仍然可以测试表单创建正确的数据?

Mar*_*rry 10

最后,自动完成测试至少使用Selenium驱动程序.

解决方案是将重点放在该领域并发出keydown事件.

我首先在浏览器中通过手动测试确认了这一点.如果我使用鼠标(而非Ctrl-V)将搜索词粘贴到自动填充字段中,则不会发生任何事情 - 不会显示下拉选择列表.这显然等同于Capybara发送fill_in命令时发生的情况.但是,在该字段位于该字段后,当焦点仍然在该字段上时,如果我触摸任何键,例如Shift键,则会出现选择列表.显然,选择列表仅在按下键时出现.

选项1

一种解决方案是将功能从原始问题扩展如下:

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
Run Code Online (Sandbox Code Playgroud)

然后像这样调用它:

fill_autocomplete "to_contact_name", with: "Jone", select: "Bob Jones"
Run Code Online (Sandbox Code Playgroud)

选项2

类似的方法,改编自主rails3-jquery-autocomplete gem中的Steak测试,使用标准fill_in,然后是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
Run Code Online (Sandbox Code Playgroud)

这被称为:

fill_in "to_contact_name", :with => "Jone"
choose_autocomplete_result "Bob Jones", "#to_contact_name"
Run Code Online (Sandbox Code Playgroud)

我采用了第二种方法进行测试.使用Selenium似乎非常可靠,但是不能与webkit一起使用,这太糟糕了,因为相比之下Selenium测试相当慢.在webkit下运行的解决方案将受到欢迎!

  • 你的选项1解决方案无效,因为`:contains`是无效的W3C CSS选择器(这只是jQuery).我用我名下的http://stackoverflow.com/questions/6355586/testing-jquery-autocomplete-ui-with-cucumber中列出的解决方案修复了它 (2认同)