Capybara 与 jquery.selectize 的集成测试

问题描述 投票:0回答:7

如何使用

jquery.selectize
编写带有表单的水豚集成测试?

我想测试用户输入几个值。

ruby-on-rails-3 capybara capybara-webkit selectize.js
7个回答
6
投票

这里的大多数答案都从底层改变了内容,并且与用户交互不同。这是一个接近用户所做的版本。

# waits for the text to show up in autocomplete and then selects it
def selectize_select(selectize_class, text)
  find("#{selectize_class} .selectize-input input").native.send_keys(text) #fill the input text
  find(:xpath, "//div[@data-selectable and contains(., '#{text}')]").click #wait for the input and then click on it
  # convert css selector to xpath selector using Nokogiri::CSS.xpath_for
end

5
投票

我创建了一个助手,并将其混合到我的水豚功能规格中:

module PageSteps
  def fill_in_selectized(key, *values)
    values.flatten.each do |value|
      page.execute_script(%{
        $('.#{key} .selectize-input input').val('#{value}');
        $('##{key}').selectize()[0].selectize.createItem();
      })
    end
  end
end

这是一个如何使用它的示例:

# Single value
fill_in_selectized('candidate_offices', 'Santa Monica')

# Multiple values
fill_in_selectized('candidate_offices', ['San Francisco', 'Santa Monica'])

第一个参数是一个“键”,根据我们的标记,它可以在我们的应用程序中工作。根据您的标记,您可能需要进行一些调整。这需要启用 Javascript 的水豚驱动程序(我们使用poltergeist)。


1
投票

API 允许,但需要先添加选项,然后才能设置值:

var selectize = $('.selector')[0].selectize
selectize.addOptions([{text: 'Hello', value: 'Hello'}, {text: 'World', value: 'World'}])
selectize.setValue(['Hello', 'World'])

1
投票

这是我与我的功能规格混合在一起的帮手。它调整并扩展了Christian 的答案

  • 它同时解决
    select
    text
    输入类型
  • 它读起来就像普通的水豚
    fill_in
    方法
  • 它可以接受任何适用于
    find_field
    的标识符来查找输入。因此,您可以使用标签的文本、元素的 id 或元素的名称来查找元素。

此代码所做的唯一假设是您的文本输入具有

name
属性(当然,Rails 输入帮助程序会自动添加)

def selectize(key, with:)
  field = page.find_field(key, visible: false)
  case field.tag_name
  when "select"
    page.execute_script(%{
      $("select[name='#{field["name"]}']")
        .selectize()[0].selectize.setValue(#{Array(with)});
    })
  else
    Array(with).each do |value|
      page.execute_script(%{
        $("input[name='#{field["name"]}']")
          .next()
          .find(".selectize-input input").val('#{value}')
          .end()
          .prev()
          .selectize()[0].selectize.createItem();
      })
    end
  end
end

使用示例:

selectize "Single-choice field", with: "Only option"
selectize "Multi-choice field", with: ["Option A", "Option B"]

1
投票

在 2022 年,上述方法对我来说都不起作用,这是我现在使用的:

def selectize_select(option_name, from:)
  page.execute_script <<~JS
    const id = $('label:contains(#{from.to_json})').attr('for').replace(/-selectized$/, '')
    const selectize = $(`#${id}`).selectize({})[0].selectize;
    selectize.setValue(selectize.search(#{option_name.to_json}).items[0].id);
  JS
end

它匹配标签和选项名称,而不是输入 ID 和选项值:

selectize_select 'Capybara', from: 'Your favorite animal'

0
投票

selectize
使用所有按键事件(
keydown
keypress
keyup
)来提供出色的 UI,但似乎没有提供从 javascript 设置数据的简单方法。

一种解决方案是使用

syn.js
库来触发右键事件。这是一个有效的助手:

def fill_in_selectize_area selector, options
  # Syn appears to require an id, so assign a temporary one
  @selectize_unique_id ||= 0
  unique_id = "temp_selectize_id_#{@selectize_unique_id +=1}"
  with = options.fetch(:with)
  page.execute_script %Q{
    var selectize = $(#{selector.to_json})[0].selectize;
    var type = #{with.to_json}.join(selectize.settings.delimiter) + '\t';
    selectize.$control_input.attr('id', #{unique_id.to_json});
    Syn.click({}, #{unique_id.to_json}).delay().type(type);
  }
  # make sure that it worked *and* that it's finished:
  page.should have_content with.join('×') << '×' 
end

# example use:
fill_in_selectize_area '[name="blog[tags]"]', with: ['awesome subject', 'other tag']

请注意,需要

delay
,因为专注于输入并不是即时的。


0
投票

我有多种方法来填写选择输入,但没有一种方法适用于根据用户输入动态加载选项的情况。这是需要的,因为否则 select 会有几千个选项,并且页面加载速度会非常慢。

这是最终起作用的版本(它基于此线程中投票最多的答案,但具有改进的 CSS 选择器)

def fill_in_selectize(key, options = {})
    # fill the input text
    find("##{key} + .selectize-control .selectize-input input").native.send_keys(options[:with])
    # wait for the input and then click on it
    find(:xpath, "//div[@data-selectable and contains(., '#{options[:with]}')]").click
  end
© www.soinside.com 2019 - 2024. All rights reserved.