Capybara integration tests with jquery.selectize

后端 未结 5 1928
隐瞒了意图╮
隐瞒了意图╮ 2021-01-17 17:49

How can I write a capybara integration test with a form using jquery.selectize?

I\'d like to test a user entering a couple of values.

相关标签:
5条回答
  • 2021-01-17 18:34

    selectize uses all key events (keydown, keypress, keyup) to provide a great UI, but doesn't seem to provide an easy way to set data from javascript.

    One solution is to use the syn.js library to trigger the right key events. Here's a helper that works:

    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']
    

    Note that the delay is needed because focussing on the input isn't instant.

    0 讨论(0)
  • 2021-01-17 18:38

    This is my helper I mix in with my feature specs. It tweaks and extends Christian's answer.

    • It addresses both select and text input types
    • It reads like the regular Capybara fill_in method
    • It can accept any identifier that works for find_field to find the input. So, you can use the label's text, the element's id or the element's name to find the element.

    The only assumption this code makes is that your text input has a name attribute (which, of course, the Rails input helpers add automatically)

    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
    

    Example usage:

    selectize "Single-choice field", with: "Only option"
    selectize "Multi-choice field", with: ["Option A", "Option B"]
    
    0 讨论(0)
  • 2021-01-17 18:39

    The API allows it but the options need to be added first before the value can be set:

    var selectize = $('.selector')[0].selectize
    selectize.addOptions([{text: 'Hello', value: 'Hello'}, {text: 'World', value: 'World'}])
    selectize.setValue(['Hello', 'World'])
    
    0 讨论(0)
  • 2021-01-17 18:40

    Most of the answers here change stuff from beneath the covers and aren't the same as the users interaction. Here is a version which is close to the what the user does.

    # 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
    
    0 讨论(0)
  • 2021-01-17 18:44

    I created a helper that I mix in to my capybara feature specs:

    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
    

    And here's an example of how it is used:

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

    The first parameter is a "key" and works in our application given our markup. Depending on your markup, you might need a little tweak. This requires a Javascript enabled capybara driver (we use poltergeist).

    0 讨论(0)
提交回复
热议问题