Справка по Capybara Select2 с Firefox - PullRequest
0 голосов
/ 02 июля 2018

Почему-то у меня проблемы с Select2 и Firefox с Geckodriver.

Поля Select2, которые я раньше мог просто сказать page.select 'Text', from: 'Label', однако, что больше не работает, я просто получаю 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

Это уродливо и не соответствует моему методу объектной модели страницы, так как я должен знать, какое это поле select2. Похоже, что это не так при поиске с ярлыком.

Есть идеи? Это очень неприятно, так как он работал с Chrome, но у последней версии chromedriver есть проблемы с новейшими версиями капибары.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2019

Я проверил ответ Томаса, но он не работает для меня. Когда Capybara щелкает нужную опцию, окно 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

Поскольку я держу свой модуль Helper без включения его в тесты, мне нужно было включить self в название метода и взять в качестве параметра «страницу» из capybara´test. Переменная datos - это хеш с селектором, текстом опции и ее значением.

Когда окно select2 закрывается, когда на него кликает капибара, я обертываю обходной путь внутри предложения if, чтобы убедиться, что некоторые части окна select2 работают.

Наконец, я вернул текущее значение выбора, чтобы проверить его (на самом деле, это не нужно, так как я установил параметр с этим значением как «выбранный»)

Надеюсь, это кому-нибудь поможет.

0 голосов
/ 03 июля 2018

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...