我在页面上有一个Select2元素,可以通过ajax加载结果。想用capybara / rspec(使用poltergeist驱动程序)来测试这个,但是因为Select2元素实际上是作为隐藏字段开始的,然后在处理完结果后填充<ul>
,没有正常的{{1 }},select
或fill_in
助手可以使用。
我现在拥有的是像
choose
上面第4行,显然capybara可以找到元素,但值不会改变,Select2永远不会进行ajax调用。 (不能在那里使用普通 it "should have a search field for events" do
click_link "Select an Event" # this works as expected
within('.select2-container') do # works
find('.select2-search input').set(event.description[0,5]) # won't work!
find(:xpath, "li[text()='#{event.description}']").click
end
click_button "Search"
page.should have_content("Displaying all 2 photos")
end
因为搜索字段元素没有标签,id或名称属性)
答案 0 :(得分:8)
我创建了一个可以与Cucumber一起使用的帮助器,它没有sleep
所以它比上面的方法更快。如果您使用Select2提供的createSearchChoice
,这也适用。
将其放入features/support/select2_helper.rb
module Select2Helper
def select2(value, attrs)
first("#s2id_#{attrs[:from]}").click
find(".select2-input").set(value)
within ".select2-result" do
find("span", text: value).click
end
end
end
World(Select2Helper)
像这样使用:
Then(/^I select2 "([^"]*)" from "([^"]*)"$/) do |value, select_name|
select2 value, from: select_name
end
使用Rails 4.1.1和Cucumber 1.3.15进行测试。
答案 1 :(得分:7)
不要挠挠头,这样做会有效
select "option_name_here", :from => "Id Of Your select field"
我尝试了每一个模块和每一个该死的东西,最后只是通过简单的代码行完成了没有任何助手和这样的事情。
答案 2 :(得分:4)
对于页面上的多个select2组件,我创建了以下适合我的帮助方法:
def select2(id, value)
page.execute_script %Q{
i = $('#s2id_#{id} .select2-input');
i.trigger('keydown').val('#{value}').trigger('keyup');
}
sleep 2
find('div.select2-result-label').click
end
def remove_all_from_select2(id)
page.execute_script %Q{
$('#s2id_#{id} .select2-choices a').click();
}
end
def remove_from_select2(id, value)
page.execute_script %Q{
$('#s2id_#{id} .select2-choices div:contains("#{value}")').closest('li').find('a').click();
}
end
答案 3 :(得分:3)
我可以使用page.execute_script
手动将所需的值和keyup
事件破解到搜索字段中来解决此问题。
it "should have a search field for events" do
click_link "Select an Event"
page.execute_script("i = $('.select2-container input').first();
i.val('#{event.description[0,4]}').trigger('keyup');");
sleep 2
find('.select2-results li:first-child').click
click_button "Search"
page.should have_content("Displaying all 2 photos")
end
答案 4 :(得分:2)
对于那些苦苦挣扎Select2 多重的人:
奇怪的是我发现select_tag有多个:true似乎热衷于为每个条目生成html,如:
<div class="select2-result-label">
<span class="select2-match"></span>
value
</div>
而不是
<div class="select2-result-label">
<span class="select2-match">value</span>
</div>
无益地将内容放在跨度之外。
为了用水豚来测试它我有两种方法:
# for most select2s
def select2_select(value, id)
# This methods requires @javascript in the Scenario
first("#s2id_#{id}").click
find(".select2-input").set(value)
within ".select2-result" do
if !find("span").text.empty?
find("span", text: value).click
elsif !find("div").text.empty?
find("div", text: value).click
else
fail 'neither span nor div within this select2, did you get the id of the select2 right?'
end
end
end
# for select_tag select2s which are multiple:true
def select2_select_multiple(select_these, id)
# This methods requires @javascript in the Scenario
[select_these].flatten.each do | value |
first("#s2id_#{id}").click
found = false
within("#select2-drop") do
all('li.select2-result').each do | result |
unless found
if result.text == value
result.click
found = true
end
end
end
end
end
end
后者因我的喜好而过于苛刻,所以我尽可能使用第一个,并希望最终取代后者。
使用HAML:
= select_tag "some_id", options_for_select(['hello','world']), multiple: true, include_blank: true
JS:
$("#some_id").select2();
答案 5 :(得分:2)
受益于这个答案和Capybara select2 helper的答案我想出了同一页面上单选和多选的多个select2字段看起来很健壮的东西:
def select2(value, attrs)
s2c = first("#s2id_#{attrs[:from]}")
(s2c.first(".select2-choice") || s2c.find(".select2-choices")).click
find(:xpath, "//body").all("input.select2-input")[-1].set(value)
page.execute_script(%|$("input.select2-input:visible").keyup();|)
drop_container = ".select2-results"
find(:xpath, "//body").all("#{drop_container} li", text: value)[-1].click
end
答案 6 :(得分:2)
这适用于带有远程数据源的下拉样式select2:
def select2(value, from:)
execute_script("$('##{from}').select2('open')")
find(".select2-search__field").set(value)
find(".select2-results li", text: /#{value}/).click
end
from
必须是构建select2的常规select标记的ID。
答案 7 :(得分:1)
我有两个远程select2。我在第一个中搜索一个字符串,根据找到的结果,第二个字符串被填充。 在尝试了capybara-select2 gem以及此处列出的所有解决方案后,我不得不提出自己的解决方案,因为它们都没有用于搜索。 在我的情况下,我选择的并不重要,因此没有尝试选择具有特定值的结果标签。希望这可以帮助处理我的情况。
Given(/^I have selected "(.*?)" category$/) do |arg1|
page.find(:css, ".select2-choice.select2-default").click
page.find(:css, "#s2id_autogen1_search").set "Dip Boya"
sleep 2
page.all(:css, '.select2-result-label')[1].click
end
Given(/^I have selected "(.*?)" variation$/) do |arg1|
page.find(:css, ".select2-choice.select2-default").click
page.all(:css, '.select2-result-label')[1].click
end
答案 8 :(得分:0)
嘿,我不确定是否还有人关心,但我也有这个问题,我找到了一个简单的方法来处理它。
首先,我不会将这个类添加到每个下拉选择中,而是像全局那样添加:
class CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput
def input_html_classes
super.push('chosen-select')
end
end
因此,当我开始遇到capybara无法使用select2下拉列表的问题时,我的解决方案是仅在测试环境中使用全局推送:
class CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput
unless Rails.env.test?
def input_html_classes
super.push('chosen-select')
end
end
end
我曾经使用过capybara-select2宝石,但好像它不再被维护了:(
答案 9 :(得分:0)
简单回答:
page.find('.select2-drop-active .select2-input').set('foo')
page.find('.select2-drop-active .select2-input').native.send_keys(:return)
答案 10 :(得分:0)
def select2(id, value)
find("##{id} ~ span.select2").click
within ".select2-results" do
find("li", text: value).click
end
end
答案 11 :(得分:0)
这是针对更新版本的select2的解决方案 - 特别是select2-rails(4.0.0)gem:
将其放在features/support/feature_helpers.rb
中,然后将其包含在spec_helper.rb
文件中,config.include FeatureHelpers
块中包含RSpec.configure do |config|
。
module FeatureHelpers
def fill_in_select2(container_selector, with: '')
page.execute_script %Q{
i = $('#{container_selector} .select2-search__field');
i.trigger('keydown').val('#{with}').trigger('keyup');
}
sleep 2
find('.select2-results__option--highlighted').click
end
end
然后像在Capybara中使用fill_in_select2
一样使用fill_in
,但是包含具有适当前缀符号的容器元素的类或id。 (例如fill_in_select2 '.actions_list', with: 'bob@testmaster1000.com'
)。
注意:这会在输入文字后选择下拉列表中的第一个元素。
在Rails 4.2.5.2,Capybara 2.7.1和Capybara-Webkit 1.11.1中测试
答案 12 :(得分:0)
花了更长的时间比我更喜欢,我终于通过建立Brandon McInnis&#39;使用xpath选择器回答。
module Select2Helper
def fill_in_select2(container_selector, with: '')
page.execute_script %Q{
i = $('#{container_selector} .select2-search__field');
i.trigger('keydown').val('#{with}').trigger('keyup');
}
sleep 2
find(:xpath, "//body").all("#{container_selector} li", text: with)[-1].click
end
end
答案 13 :(得分:0)
js: true
的
答案 14 :(得分:0)
这对我有用,即使使用select2 AJAX自动完成:
find('#user_id').sibling('span.select2').click
find('.select2-search__field').set('ABCDEF')
find('.select2-results li', text: 'ABCDEF').click
答案 15 :(得分:0)
您可以使用capybara-select-2 gem来完成所有工作。只需将search: true
传递到帮助器选项即可进行Ajax调用:
select2 'Marriage', from: 'Event', search: true
答案 16 :(得分:0)
此助手为我工作(使用占位符):
# Add this helper
def select2(placeholder, option)
find("select[data-placeholder='#{placeholder}'] + .select2").click
within '.select2-results' do
find('span', text: option).click
end
end
并这样称呼它:
select2 'Placeholder', 'some option'