为什么我的Capybara / Poltergeist测试不能从jQuery自动完成字段中选择?
更新:经过我自己的大量艰苦工作后,我解决了这个问题。 我很高兴成为任何需要帮助的人的资源。 这是我工作设置的要点。
我已经尝试了所有可以找到Google和SO的解决方案。 以下是我尝试过的一些不同的事情:
page.execute_script %Q{$('#{selector}').val('#{value}').trigger('keydown')}
和
fill_in field, with: options[:with] page.execute_script %Q{ $('##{field}').trigger('focus') } page.execute_script %Q{ $('##{field}').trigger('keydown') }
这是失败的:
page.should have_selector('ul.ui-autocomplete li.ui-menu-item a')
但是当我在Firebug中查看并在浏览器中测试它时,它肯定存在。
以下是所有细节,包括上述内容的重述。 请记住,自动填充字段在浏览器中正常工作。
listing_integration_spec.rb
require "spec_helper" describe "Listing Integration" do let!(:user) { login_user } it "lets a user add information listing", js: true do listing = create(:listing, user: user) click_link('Additional Information') click_link('Create') fill_autocomplete('listings_search', with: listing.item_id) end end
spec/support/feature_helper.rb
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[:with]}')} page.should have_selector('ul.ui-autocomplete li.ui-menu-item a') page.execute_script %Q{ $("##{selector}").trigger('mouseenter').click() } end
ERB from view template
和Coffeescript:
$("#listings_search").autocomplete source: (request, response) -> options = term: request.term $.get "/search_listings", options, (data) -> if data.length == 0 alert "No listings found." response data minLength: 2 select: (event, ui) -> add_listing_hash = type: "GET" url: "/add_listing" data: { id: ui.item.id } success: () -> $.ajax(add_listing_hash)
JS驱动程序通常都是meh,它们很慢而且没有一个单独覆盖100%的function,而且它们通常很古怪而且难以调试,但我相信你现在已经弄明白了。
我有类似的代码片段工作在rails 3.2,minitest和poltergeist 1.3.0(一个ajaxed下拉列表)但是它有一种周期性的断裂没有充分的理由(有人可能会说它有一个恶作剧者?我已经使用了切换测试到目前为止,在selenium和poltergeist之间的几次),不确定为什么autocompleter对你不起作用但感觉就像一个bug,
提交问题到https://github.com/jonleighton/poltergeist (你已经有了? https://github.com/jonleighton/poltergeist/issues/439 ),尝试更改为selenium或webkit,看看它是否有效,你可以如果它让你走出困境,那么在这一个测试中使用不同的驱动程序(它会因为工作的小部件而失去工作时间)。
我在网上找到了几种解决方案,但这些解决方案都不适用于当前版本的Poltergeist,Capybara和Autocomplete。 但是我从他们那里学到了足够的东西来制作一个有效的辅助方法,没有睡眠呼叫。
def fill_autocomplete(css_id, page, 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
用法示例:
fill_autocomplete( '#contact_filter_company', listing_page, with: 'acm', select: 'Acme' )
我有一个page
参数,因为我正在使用SitePrism – 如果你不是,你可以将其删除。
我正在使用它:
- jQuery UI自动完成1.11.2
- 恶作剧者1.5.1
- 水豚2.4.4
- rspec 3.1.0
我能够用Poltergeist测试我的自动填充文本字段而不会有太多麻烦。 要了解的主要内容是Poltergeist的.native.send_keys
方法。
将这些代码行实际存在于我的项目中的Cucumber步骤中的摘要汇总在一起:
find('#username').native.send_keys "the" # this field autocompletes usernames wait_until { all('a', text: "the_username").any? } find('a', text: "the_username").click
然后我以通常的方式提交表单并在下一页上声明预期结果。
wait_until
( 从Capybara 2中删除的方法的重新实现 )需要一个块,当我们应该停止等待时它返回true。 它比等待5秒或者每次都要快。
def wait_until(delay = 1) seconds_waited = 0 while ! yield && seconds_waited < Capybara.default_wait_time sleep delay seconds_waited += 1 end raise "Waited for #{Capybara.default_wait_time} seconds but condition did not become true" unless yield end
我想也许您需要混合触发KEYDOWN,还要将键码设置为DOWN。
例如
var keyEvent = $.Event("keydown"); keyEvent.keyCode = $.ui.keyCode.DOWN; $("#autocomplete").val("j"); $("#autocomplete").trigger(keyEvent);
这是一个工作jsfiddle示例,显示自动完成选择的项目: http : //jsfiddle.net/alexkey/74BST/我不确定为什么需要两次触发keydown,但这是一个单独解决的问题(如果有问题)在所有)。
但是我不熟悉你正在使用的unit testing框架,但我希望上面有所帮助。
信用转到JQuery AutoComplete,手动选择第一个搜索项并绑定点击
我正在使用示例代码表单: http : //api.jqueryui.com/autocomplete/#entry-examples
自动完成unit testingjquery-ui团队使用可能对灵感有用: https : //github.com/jquery/jquery-ui/tree/master/tests/unit/autocomplete
也是对密钥的引用: http : //api.jqueryui.com/jQuery.ui.keyCode/
我有这个问题,没有提出的解决方案可以解决它。 尝试查找ul.ui-autocomplete
元素时,我的测试总是失败。 我终于注意到,jQuery自动完成将ul
附加到html页面的末尾而不是有问题的输入字段。 在我的规范中,我遵循within my_form do
明确定位表单的做法,并执行此块中的所有fill_in
内容:
within my_form do fill_autocomplete … end
当然,这可能永远不会找到附加OUTSIDE这个表单元素的ul
。 我的解决方案很简单:在初始化自动完成时使用jQuery autocomplete的属性appendTo: '#id_of_input_field'
。 现在它可以找到我的ul
,一切正常。