Skip to content

Instantly share code, notes, and snippets.

@jaryl
Forked from thijsc/gist:1391107
Created February 6, 2012 08:56
Show Gist options
  • Save jaryl/1750858 to your computer and use it in GitHub Desktop.
Save jaryl/1750858 to your computer and use it in GitHub Desktop.
Select item from chosen js select with Capybara-Webkit
def select_from_chosen(item_text, options)
field_id = find_field(options[:from])[:id]
within "##{field_id}_chzn" do
find('a.chzn-single').click
input = find("div.chzn-search input")
item_text.each_char do |char|
input.base.invoke('keypress', false, false, false, false, char.ord, nil);
end
find('ul.chzn-results').click
input.base.invoke('keypress', false, false, false, false, 40, nil); # down arrow
input.base.invoke('keypress', false, false, false, false, 13, nil); # return
within 'a.chzn-single' do
page.should have_content item_text
end
end
end
def select_from_multi_chosen(item_text, options)
field_id = find_field(options[:from])[:id]
within "##{field_id}_chzn" do
input = find("ul.chzn-choices input")
item_text.each_char do |char|
input.base.invoke('keypress', false, false, false, false, char.ord, nil);
end
input.base.invoke('keypress', false, false, false, false, 13, nil); # return
within 'ul.chzn-choices' do
page.should have_content item_text
end
end
end
@jaryl
Copy link
Author

jaryl commented Feb 9, 2012

This is buggy, do not use. Will try fixing it but no promises.

@nshelake
Copy link

Hi,

It gives

undefined method `invoke' for # Capybara::Driver::Node tag="input"

error it i use

input.base.invoke('keypress', false, false, false, false, 13, nil); # return

in my code

@kenelliott
Copy link

This worked for my intents and purposes.

def select_from_chosen(item_text, options)
field = find_by_id(options[:from]+"_chzn")
page.execute_script("$('##{options[:from]}').val('#{item_text}').trigger('liszt:updated');")
end

select_from_chosen "Option Value", :from => "select_id"

@bsbodden
Copy link

I've experimented with several ways to accomplish this but the one that felt the least intrusive was:

def select_from_chosen(id, position)
  find(:css, "##{id}_chzn .search-field").click()
  find(:css, "##{id}_chzn_o_#{position}").click()
end

Since it doesn't force the execution of JS and it mimics the user behavior more closely. You could also do one where you click on the fields and then type to mimic the search, followed by an enter to select the currently highlighted choice

@jsantos17
Copy link

It's important to notice that the previous methods have a potentially bad bug. They all have race conditions, as they will return before all the JavaScript has been processed and the underlying hidden select elements have been updated. This will lead to incomplete requests and thus failing RSpec tests non-deterministically. The solution is easy enough: return the value of the of the modified fields at the end of the function.

@hoffmanc
Copy link

hoffmanc commented Jun 1, 2016

Here's what I just started using, as I wanted to mimic the existing select syntax:

  def choose(val, from:)
    group = find 'div.select', text: from
    group.click
    within(group) do
      find('li', text: val).click
    end
  end

@tdtadeu
Copy link

tdtadeu commented Sep 6, 2017

I'm using hoffmanc's solution and it's working ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment