Не уверен, что вы использовали, что вы когда-либо могли использовать 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
, и он найдет виджет select2, связанный с данным элементом <select>
(скрытый select2), и выберет из него правильную запись.