使用jquery.selectize进行Capybara集成测试

时间:2014-04-29 17:55:56

标签: ruby-on-rails-3 capybara capybara-webkit selectize.js

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

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

5 个答案:

答案 0 :(得分: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'])

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

答案 1 :(得分:5)

这里的大多数答案都会从封面下改变内容,与用户交互不同。这是一个接近用户所做的版本。

# 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

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

这是我的助手,我将其与我的功能规格混合在一起。它调整并扩展Christian's answer

  • 它同时处理selecttext输入类型
  • 它读起来像常规的Capybara 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"]

答案 4 :(得分:0)

selectize使用所有关键事件(keydownkeypresskeyup)来提供出色的用户界面,但似乎并没有提供简单的方法从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是必需的,因为专注于输入不是即时的。