Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gem/capybara-select2.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
gem.require_paths = ["lib"]

gem.add_dependency 'rspec'
gem.add_dependency 'capybara'
end
46 changes: 5 additions & 41 deletions gem/lib/capybara-select2.rb
Original file line number Diff line number Diff line change
@@ -1,50 +1,14 @@
require "capybara-select2/version"
# frozen_string_literal: true

require 'capybara-select2/version'
require 'capybara/selectors/tag_selector'
require 'rspec/core'
require 'capybara-select2/query'

module Capybara
module Select2
def select2(value, options = {})
raise "Must pass a hash containing 'from' or 'xpath' or 'css'" unless options.is_a?(Hash) and [:from, :xpath, :css].any? { |k| options.has_key? k }

if options.has_key? :xpath
select2_container = find(:xpath, options[:xpath])
elsif options.has_key? :css
select2_container = find(:css, options[:css])
else
select_name = options[:from]
select2_container = find("label", text: select_name).find(:xpath, '..').find(".select2-container")
end

# Open select2 field
if select2_container.has_selector?(".select2-selection")
# select2 version 4.0
select2_container.find(".select2-selection").click
elsif select2_container.has_selector?(".select2-choice")
select2_container.find(".select2-choice").click
else
select2_container.find(".select2-choices").click
end

if options.has_key? :search
find(:xpath, "//body").find(".select2-search input.select2-search__field").set(value)
page.execute_script(%|$("input.select2-search__field:visible").keyup();|)
drop_container = ".select2-results"
elsif find(:xpath, "//body").has_selector?(".select2-dropdown")
# select2 version 4.0
drop_container = ".select2-dropdown"
else
drop_container = ".select2-drop"
end

[value].flatten.each do |value|
if find(:xpath, "//body").has_selector?("#{drop_container} li.select2-results__option")
# select2 version 4.0
find(:xpath, "//body").find("#{drop_container} li.select2-results__option", text: value).click
else
find(:xpath, "//body").find("#{drop_container} li.select2-result-selectable", text: value).click
end
end
Capybara::Select2::Query.new(page, value, options).call
end
end
end
Expand Down
89 changes: 89 additions & 0 deletions gem/lib/capybara-select2/query.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# frozen_string_literal: true

module Capybara
module Select2
class Query
CONTROL_SELECTOR =
'.select2-selection,.select2-choice,.select2-choices'
OPEN_CONTAINER_SELECTOR =
'.select2-container--open .select2-dropdown'
SEARCH_FIELD_SELECTOR = 'input.select2-search__field'
OPTION_SELECTOR =
'li.select2-results__option,li.select2-results__option--highlighted'

attr_reader :page, :value, :options

def initialize(page, value, options = {})
@page = page
@value = value
check_options!(options)
@options = options
end

def call
open_select2(find_container)
page.within page.find(:xpath, '//body') do
page.within page.find(OPEN_CONTAINER_SELECTOR) do
populate_search(value) if options.key? :search
select_options(value)
end
end
end

private

def select_options(values)
[values].flatten.each do |value|
select_option(value)
end
end

def select_option(value)
wait_for_option_with_text(value)
page.find(OPTION_SELECTOR, text: value).click
end

def check_options!(options)
return if allowed_options?(options)
raise "Must pass a hash containing 'from' or 'xpath' or 'css'"
end

def open_select2(container)
container.find(CONTROL_SELECTOR).click
end

def allowed_options?(options = {})
return false unless options.is_a?(Hash)
%i[from xpath css].any? { |option| options.key? option }
end

def find_container
if options.key? :xpath
page.find(:xpath, options[:xpath])
elsif options.key? :css
page.find(:css, options[:css])
else
select_name = options[:from]
page.find('label', text: select_name)
.find(:xpath, '..')
.find('.select2-container')
end
end

def populate_search(value)
page.find(SEARCH_FIELD_SELECTOR).set(value)
page.execute_script(
%($("#{OPEN_CONTAINER_SELECTOR} #{SEARCH_FIELD_SELECTOR}:visible").keyup();)
)
end

def wait_for_option_with_text(value)
Timeout.timeout(2) do
sleep(0.1) until page.has_selector?(OPTION_SELECTOR, text: value)
end
rescue Timeout::Error
page.find(OPTION_SELECTOR, text: value).click
end
end
end
end
4 changes: 3 additions & 1 deletion gem/lib/capybara-select2/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

module Capybara
module Select2
VERSION = "1.0.1"
VERSION = '1.0.3'
end
end
2 changes: 1 addition & 1 deletion gem/lib/capybara/select2.rb
Original file line number Diff line number Diff line change
@@ -1 +1 @@
require '../capybara-select2'
require '../capybara-select2'
2 changes: 2 additions & 0 deletions gem/lib/capybara/selectors/tag_selector.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Capybara
module Selectors
module TagSelector
Expand Down