出于某种原因,我在使用Geckodriver的Select2和Firefox时遇到了问题。
我曾经只能说page.select 'Text', from: 'Label'
的Select2字段,但是不再起作用了,我只是得到了Element <option> could not be scrolled into view
(尽管被滚动到视图中)。现在我正在做类似的事情:
select2Fields = page.all('.select2-selection')
select2Fields[0].click
page.find('.select2-search__field').set('Text To Set')
within('.select2-results') do
page.find('li', text: 'Text To Click').click
end
这很丑陋,不适合我的Page Object Model方法,因为我必须先知道它是哪个select2字段。似乎不是带有标签的。
有什么想法吗?自从它与Chrome一起使用以来,这非常令人沮丧,但是最新的chromedriver在最新的水豚版本中存在问题。
答案 0 :(得分:1)
不确定使用的内容是否可以将select
与select2小部件一起使用,它永远都不应该起作用,事实上它确实是一个错误。原因是实际的<select>
元素(Capybaras select
方法使用的元素)在页面上不可见,而select2
则用JS驱动的小部件替换了它。您需要做的正是用户将要执行的操作,即单击以显示小部件,然后单击代表正确条目的<li>
元素。所有这些都可以移到一个辅助方法中,并可能包含一些自定义选择器,这些选择器可以归结为类似
Capybara.add_selector(:select2) do
xpath do |locator, **options|
xpath = XPath.descendant(:select)
xpath = locate_field(xpath, locator, options)
xpath = xpath.next_sibling(:span)[XPath.attr(:class).contains_word('select2')][XPath.attr(:class).contains_word('select2-container')]
xpath
end
end
Capybara.add_selector(:select2_option) do
xpath do |locator|
# Use anywhere to escape from the current scope since select2 appends
# the choices to the end of the document
xpath = XPath.anywhere(:ul)[XPath.attr(:class).contains_word('select2-results__options')][XPath.attr(:id)]
xpath = xpath.descendant(:li)[XPath.attr(:role) == 'treeitem']
xpath = xpath[XPath.string.n.is(locator.to_s)] unless locator.nil?
xpath
end
end
def select_from_select2(value, from: nil, **options)
select2 = if from
find(:select2, from, options.merge(visible: false))
else
select = find(:option, value, options).ancestor(:css, 'select', visible: false)
select.find(:xpath, XPath.next_sibling(:span)[XPath.attr(:class).contains_word('select2')][XPath.attr(:class).contains_word('select2-container')])
end
select2.click
find(:select2_option, value).click
end
这应该让您调用select_from_select2
,就像调用select
一样,它将找到与给定<select>
元素相关联的select2小部件(被select2隐藏)并选择正确的条目从它。
答案 1 :(得分:0)
我已经测试了托马斯的答案,但对我来说不起作用。当水豚单击所需的选项时,select2框将自身关闭并设置为0选项。最终,我做了一个遍历,因为我选中了我想要的选项并触发了change.select2事件。我知道我并没有真正测试select2框。
def self.select2 (page, datos)
page.execute_script("$('##{datos[:from]}').select2('open')")
if page.find(".select2-results li", text: datos[:texto]).click
page.execute_script("$('##{datos[:from]} option[value=\"#{datos[:valor]}\"]').prop('selected', true)")
page.execute_script("$('##{datos[:from]}').trigger('change.select2')")
end
page.find(:css, '#' + datos[:from]).value
end
由于我的模块助手不包含在测试中,因此我需要在方法名称中包含self,并将capybaratest中的“ page”作为参数。 变量“ datos”是包含选择器,选项文本及其值的哈希。
在单击水豚时,关闭select2框,我将遍历内容包裹在if子句中,以确保select2框的某些部分正常工作。
最后,我返回了select的当前值以对其进行测试(确实,当我将该选项的值设置为'selected'时并不需要它)
我希望它会帮助任何人。