Skip to content

Commit

Permalink
Refactor gem and apply PR goodwill#40
Browse files Browse the repository at this point in the history
  • Loading branch information
kelevro committed Aug 2, 2017
1 parent 585192e commit d025572
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 44 deletions.
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

0 comments on commit d025572

Please sign in to comment.