水豚 Select2 帮助 w/Firefox

Capybara Select2 Help w/Firefox

出于某种原因,我 运行 遇到了 Select2 和 Firefox w/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 与最新的水豚版本有问题。

不确定您使用的是什么,您曾经能够将 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 隐藏)并选择从中正确输入。

我已经测试了 Thomas 的答案,但它对我不起作用。当 Capybara 单击所需选项时,select2 框自行关闭并设置 0 选项。 Finnaly,我做了一个演练,因为我检查了我想要的选项作为 selected 并触发了 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 并将水豚测试中的 'page' 作为参数。 变量 'datos' 是带有 selector 选项文本及其值的散列。

当水豚点击它时 select2 框关闭,我将 walkaround 包装在 if 子句中以确保 select2 框的某些部分正常工作。

最后,我返回了 select 的当前值来测试它(真的,它不需要,因为我将该值设置为 'selected')

希望对大家有所帮助。