capybara-select 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9dfbc64a457c2deff5829d629d5b36d76bc171272708cf986b6c11cc7e248c5e
4
+ data.tar.gz: 674a66dc213e0df0721c907d28a4537b47c2e19959b623354ff6644e4318e1cf
5
+ SHA512:
6
+ metadata.gz: 8a8ef90e15eafee60a35af1b3b5c0c53bf8061a2b6168010882ed98cdaa1647a5fdb8fc1b3c5ea49bf251249aba92c13c2ff31663b8f52ff04aed2c905f7217a
7
+ data.tar.gz: fb63296bfcf654617b6922852202a1928bd77ce108e11376760a799dee4375da80d56340070f4de492bc1a720c063e5eddd1c43fa499ceda55c14f12d691a45c
data/Changes.md ADDED
@@ -0,0 +1,34 @@
1
+ # capybara-select Changes
2
+
3
+ 1.0.0
4
+ ---------
5
+
6
+ First release of this fork under its own name, `capybara-select`; `capybara-select2` on rubygems.org is the
7
+ original (1.0.1, 2015). Keep `require 'capybara-select2'` and `Capybara::Select2`.
8
+
9
+ - A click that does not open the dropdown is retried (3 clicks), so a field that re-renders under the click, or a
10
+ dropdown that closes straight away, still gets its option picked.
11
+ - A dropdown that closes before the option is listed (a lookup re-rendering the form) is opened again.
12
+ - A field re-rendered under the click (`StaleElementReferenceError`) is found again with the same locator.
13
+ - A field that never opens fails fast with `select2 dropdown did not open after 3 clicks on …`, instead of waiting
14
+ `default_max_wait_time` several times and reporting missing 3.x `li.select2-result-selectable` options. The
15
+ select2 version is read from the field, not from the dropdown.
16
+ - `search: true` and the "Searching…" wait no longer spend a full `default_max_wait_time` when nothing is loading,
17
+ and every wait is bounded.
18
+ - Fix: `from:` with select2 3.x matched both the label and select2's off-screen copy of it.
19
+ - Fix: `Capybara::Ambiguous` reported the number of listed options, not of matches.
20
+ - `search: true` works with select2 3.x.
21
+ - Private helpers are prefixed with `select2_` (`select2_find_and_open`, `select2_fetch_options`, …). They are mixed
22
+ into every example, so a spec helper with 1.0.4's names (`find_select2_and_open`, `open_select2`,
23
+ `find_select2_container`, `fetch_options`) used to replace them. Call `select2` instead of those helpers.
24
+ - `css:` and `xpath:` may point at an element wrapping the select2 container, such as a form field.
25
+ - Removed `lib/capybara/select2.rb`, which could not be loaded.
26
+ - Specs against select2 4.0.13 and 3.5.4 in headless Chrome. Requires Ruby >= 3.2, Capybara 3 and
27
+ selenium-webdriver 4. Packages only files committed to git. Release tasks in `rakelib/release.rake`.
28
+
29
+ 1.0.4 (fork, never published)
30
+ ---------
31
+
32
+ - `mode:` (`:exact_text`, `:insensitive`, `:case_insensitive`), `await_option:`, `max_retries:` and retries while
33
+ select2 shows "Searching…".
34
+ - `wait:` to sleep before reading options (was `sleep:`).
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 William Yeung
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # capybara-select
2
+
3
+ [![CI](https://github.com/moskvin/capybara-select2/actions/workflows/ci.yml/badge.svg)](https://github.com/moskvin/capybara-select2/actions/workflows/ci.yml)
4
+
5
+ Capybara helpers to pick an option in a [select2](https://select2.org) field (4.x and 3.x), for RSpec feature specs
6
+ run with Selenium.
7
+
8
+ A fork of [capybara-select2](https://github.com/goodwill/capybara-select2), released as `capybara-select` because the
9
+ original name is taken on rubygems.org. It keeps the original's `require` name and `Capybara::Select2` module, and
10
+ adds what flaky browser specs need:
11
+
12
+ - a click that does not open the dropdown is retried, and a dropdown that closes before its option is listed (a form
13
+ re-rendering under the click) is opened again;
14
+ - a field re-rendered under the click is found again with the same locator;
15
+ - a field that never opens fails fast with `select2 dropdown did not open after 3 clicks on …`;
16
+ - results that load slowly are waited for ("Searching…"), within `Capybara.default_max_wait_time`.
17
+
18
+ ## Installation
19
+
20
+ ```ruby
21
+ group :test do
22
+ gem 'capybara-select', require: 'capybara-select2'
23
+ end
24
+ ```
25
+
26
+ The gem includes its helpers into every RSpec example. Outside RSpec (for example Cucumber), add
27
+ `include Capybara::Select2` to your support file.
28
+
29
+ ## Usage
30
+
31
+ Locate the field by its label, the `for` of its label, CSS or XPath of the select2 container:
32
+
33
+ ```ruby
34
+ select2('Banana', from: 'Fruit')
35
+ select2('Banana', field: 'fruit')
36
+ select2('Banana', css: '#question_12 .select2-container')
37
+ select2('Banana', xpath: container.path)
38
+ ```
39
+
40
+ Options:
41
+
42
+ | Option | Default | |
43
+ |---|---|---|
44
+ | `mode:` | `:exact_text` | `:insensitive` matches part of the text (or a Regexp), `:case_insensitive` ignores case |
45
+ | `search: true` | | types the value into the search box first, for fields with a minimum input length |
46
+ | `await_option: true` | | polls for the option before reading the list (`max_retries:`, default 5) |
47
+ | `wait:` | | sleeps this many seconds before reading the list |
48
+
49
+ `select2_filter('an', from: 'Fruit', search: true)` returns the listed options without picking one.
50
+
51
+ For a field with [tags](https://select2.github.io/select2/#tags):
52
+
53
+ ```ruby
54
+ select2_tag('value', from: 'Label of input')
55
+ ```
56
+
57
+ ## Development
58
+
59
+ bundle install
60
+ bundle exec rake # RuboCop and the specs (headless Chrome, select2 4.0.13 and 3.5.4)
61
+
62
+ ## Releasing
63
+
64
+ rake "release:bump[minor]" # bump version.rb, add a Changes.md section
65
+ rake release:dry_run # checks, lint, specs, package inspection; pushes nothing
66
+ rake release # the same checks, then tag vX.Y.Z and push to rubygems.org
67
+
68
+ ## License
69
+
70
+ MIT, see [LICENSE.txt](LICENSE.txt). Original author: William Yeung.
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/capybara-select2/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'capybara-select'
7
+ spec.version = Capybara::Select2::VERSION
8
+ spec.authors = ['William Yeung', 'Nikolay Moskvin']
9
+ spec.email = ['william@tofugear.com']
10
+
11
+ spec.summary = 'Capybara helpers to pick options in select2 (3.x and 4.x) fields'
12
+ spec.description = 'select2 and select2_filter for Capybara/RSpec, with retries for dropdowns that close or ' \
13
+ 're-render under the click and for results that load slowly. A fork of capybara-select2.'
14
+ spec.homepage = 'https://github.com/moskvin/capybara-select2'
15
+ spec.license = 'MIT'
16
+
17
+ # Only files committed to git, so a local scratch file can never be published.
18
+ spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, &:read).split("\x0").select do |f|
19
+ f.start_with?('lib/') || %w[Changes.md LICENSE.txt README.md capybara-select2.gemspec].include?(f)
20
+ end
21
+
22
+ spec.require_paths = ['lib']
23
+ spec.required_ruby_version = '>= 3.2.0'
24
+
25
+ spec.metadata = {
26
+ 'homepage_uri' => 'https://github.com/moskvin/capybara-select2',
27
+ 'bug_tracker_uri' => 'https://github.com/moskvin/capybara-select2/issues',
28
+ 'changelog_uri' => 'https://github.com/moskvin/capybara-select2/blob/master/Changes.md',
29
+ 'source_code_uri' => 'https://github.com/moskvin/capybara-select2',
30
+ 'rubygems_mfa_required' => 'true'
31
+ }
32
+
33
+ spec.add_dependency 'capybara', '>= 3.0', '< 4'
34
+ spec.add_dependency 'rspec-core', '>= 3.0', '< 4'
35
+ spec.add_dependency 'rspec-expectations', '>= 3.0', '< 4'
36
+ spec.add_dependency 'selenium-webdriver', '>= 4.0', '< 5'
37
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Capybara
4
+ module Selectors
5
+ module TagSelector
6
+ def select2_tag(value, options = {})
7
+ if options[:from]
8
+ find(:fillable_field, options[:from]).set(value)
9
+ else
10
+ find('input.select2-input').set(value)
11
+ end
12
+
13
+ find('.select2-drop li', text: value).click
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Capybara
4
+ module Select2
5
+ VERSION = '1.0.0'
6
+ end
7
+ end
@@ -0,0 +1,243 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'capybara-select2/version'
4
+ require 'capybara/selectors/tag_selector'
5
+ require 'rspec/core'
6
+ require 'selenium/webdriver'
7
+
8
+ module Capybara
9
+ module Select2
10
+ # Clicks used to open a dropdown. A click can be lost when the field re-renders under it, or the dropdown can
11
+ # close straight away; each attempt waits default_max_wait_time / OPEN_ATTEMPTS for it to open.
12
+ OPEN_ATTEMPTS = 3
13
+
14
+ # Markup per select2 major version. The version is read from the field itself, never from an open dropdown,
15
+ # so a dropdown that failed to open is reported as such instead of as missing 3.x options.
16
+ MARKUP = {
17
+ 4 => {
18
+ trigger: '.select2-selection',
19
+ open: '.select2-container--open',
20
+ dropdown: '.select2-container--open .select2-dropdown',
21
+ option: 'li.select2-results__option',
22
+ search: '.select2-container--open input.select2-search__field',
23
+ loading: '.loading-results'
24
+ }.freeze,
25
+ 3 => {
26
+ trigger: '.select2-choice, .select2-choices',
27
+ open: '.select2-dropdown-open',
28
+ dropdown: '.select2-drop-active',
29
+ option: 'li.select2-result-selectable',
30
+ search: '.select2-drop-active input.select2-input',
31
+ loading: '.select2-searching'
32
+ }.freeze
33
+ }.freeze
34
+
35
+ # Fill in a select2 filter and return the options.
36
+ # @return [Array] the filtered options
37
+ def select2_filter(value, **args)
38
+ markup = select2_find_and_open(value, **args)
39
+ select2_fetch_options(value, markup:, **args).find_all(select2_option_selector(markup))
40
+ end
41
+
42
+ # Fill in a select2 field and select the value.
43
+ # @param value [String, Regexp]
44
+ # @param args
45
+ # - xpath, css, from or field [String] - locates the select2 container
46
+ # - mode [Symbol] - :exact_text (default), :insensitive or :case_insensitive
47
+ # - search [Boolean] - type the value into the search box first
48
+ # - wait [Float] - sleep this long before reading the options
49
+ # - await_option [Boolean] - poll for the option before reading the options
50
+ # - max_retries [Integer] - polls for await_option (default 5)
51
+ # @raise [Capybara::ElementNotFound]
52
+ # @raise [Capybara::Ambiguous]
53
+ # @raise [Capybara::ExpectationNotMet] when the dropdown does not open
54
+ def select2(value, **args)
55
+ text = select2_match_text(value, args[:mode])
56
+ exact_text = select2_exact_text?(args[:mode])
57
+ option = exact_text ? { exact_text: text } : { text:, count: 1 }
58
+ markup = select2_open_with_option(value, text, option, **args)
59
+ expect(select2_body).to have_css(select2_option_selector(markup), wait: 0, **option)
60
+
61
+ select2_pick_option(value, text, exact_text, markup)
62
+ end
63
+
64
+ private
65
+
66
+ # Private helpers are prefixed with select2_: they are mixed into every example, so a spec helper with the same
67
+ # name would otherwise replace them.
68
+
69
+ def select2_pick_option(value, text, exact_text, markup)
70
+ matches = select2_body.find_all(select2_option_selector(markup)).select do |result|
71
+ exact_text ? result.text == text : result.text.match?(text)
72
+ end
73
+
74
+ case matches.size
75
+ when 0
76
+ raise Capybara::ElementNotFound, "Unable to find a matching option for #{value}"
77
+ when 1
78
+ matches.first.click
79
+ else
80
+ raise Capybara::Ambiguous, "Ambiguous match, found #{matches.size} options for #{value}"
81
+ end
82
+ end
83
+
84
+ def select2_monotonic_now
85
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
86
+ end
87
+
88
+ def select2_match_text(value, mode)
89
+ case mode
90
+ when :insensitive
91
+ value.is_a?(Regexp) ? value : /#{Regexp.escape(value)}/
92
+ when :case_insensitive
93
+ /#{Regexp.escape(value)}/i
94
+ else
95
+ value
96
+ end
97
+ end
98
+
99
+ def select2_exact_text?(mode)
100
+ mode.nil? || mode == :exact_text
101
+ end
102
+
103
+ # Opens the dropdown and waits for the option. A dropdown that closes before the option is listed (the field
104
+ # re-rendered, as a lookup updating a form does) is opened again; one that stays open without it is left to
105
+ # select2's expectation to report.
106
+ def select2_open_with_option(value, text, option, **args)
107
+ OPEN_ATTEMPTS.times do
108
+ markup = select2_find_and_open(value, **args)
109
+ select2_fetch_options(text, markup:, **args)
110
+ return markup if select2_option_listed_or_open?(markup, option)
111
+ end
112
+ raise Capybara::ExpectationNotMet, "select2 dropdown closed before listing #{value} #{OPEN_ATTEMPTS} times"
113
+ end
114
+
115
+ # true once the option is listed, or when default_max_wait_time passes with the dropdown still open;
116
+ # false as soon as the dropdown closes.
117
+ def select2_option_listed_or_open?(markup, option)
118
+ deadline = select2_monotonic_now + Capybara.default_max_wait_time
119
+ body = select2_body
120
+ loop do
121
+ return true if body.has_css?(select2_option_selector(markup), wait: 0, **option)
122
+ return false unless body.has_selector?(markup[:dropdown], wait: 0)
123
+ return true if select2_monotonic_now >= deadline
124
+
125
+ sleep(0.05)
126
+ end
127
+ end
128
+
129
+ def select2_option_selector(markup)
130
+ "#{markup[:dropdown]} #{markup[:option]}"
131
+ end
132
+
133
+ def select2_body
134
+ find(:xpath, '//body')
135
+ end
136
+
137
+ def select2_fetch_options(text, markup:, **args)
138
+ sleep(args[:wait]) unless args[:wait].nil?
139
+ if args[:await_option]
140
+ select2_await_option(text, markup:, max_retries: args[:max_retries] || 5, mode: args[:mode])
141
+ end
142
+ select2_await_loaded(markup)
143
+ select2_body
144
+ end
145
+
146
+ # Polls with a growing wait until the option is listed; select2 then fails with Capybara's own message.
147
+ def select2_await_option(text, markup:, mode:, max_retries:)
148
+ options = select2_exact_text?(mode) ? { exact_text: text } : { text:, count: 1 }
149
+ (max_retries + 1).times do |attempt|
150
+ break if select2_body.has_css?(select2_option_selector(markup), wait: attempt / 10.0, **options)
151
+
152
+ sleep(0.3)
153
+ select2_logger.warn("Retry to find a matching option for #{text}, mode: #{mode}, " \
154
+ "attempt: #{attempt + 1}/#{max_retries}")
155
+ end
156
+ end
157
+
158
+ # Waits, up to default_max_wait_time, while the dropdown shows "Searching…".
159
+ def select2_await_loaded(markup)
160
+ deadline = select2_monotonic_now + Capybara.default_max_wait_time
161
+ loading = "#{markup[:dropdown]} #{markup[:loading]}"
162
+ sleep(0.05) while select2_body.has_selector?(loading, wait: 0) && select2_monotonic_now < deadline
163
+ end
164
+
165
+ def select2_find_container(**args)
166
+ if args[:xpath]
167
+ select2_container_in(find(:xpath, args[:xpath]))
168
+ elsif args[:css]
169
+ select2_container_in(find(:css, args[:css]))
170
+ else
171
+ select2_container_next_to(select2_find_label(**args))
172
+ end
173
+ end
174
+
175
+ def select2_find_label(**args)
176
+ if args[:field]
177
+ find(%(label[for="#{args[:field]}"]))
178
+ elsif args[:from]
179
+ # select2 3.x copies the label into its container as an off-screen label
180
+ find('label:not(.select2-offscreen)', text: args[:from])
181
+ else
182
+ raise ArgumentError, 'None of xpath, css, field, nor from given'
183
+ end
184
+ end
185
+
186
+ def select2_container_next_to(label)
187
+ label.find(:xpath, '..').find('.select2-container')
188
+ end
189
+
190
+ # xpath: and css: may point at the select2 container or at an element wrapping it (such as a form field).
191
+ def select2_container_in(element)
192
+ return element if element.matches_css?('.select2-container', wait: 0)
193
+
194
+ element.find('.select2-container', match: :first)
195
+ end
196
+
197
+ def select2_version(container)
198
+ return 4 if container.has_selector?(MARKUP[4][:trigger], wait: 0)
199
+ return 3 if container.has_selector?(MARKUP[3][:trigger], wait: 0)
200
+
201
+ # Not rendered yet: wait once for either version.
202
+ container.has_selector?("#{MARKUP[4][:trigger]}, #{MARKUP[3][:trigger]}")
203
+ container.has_selector?(MARKUP[4][:trigger], wait: 0) ? 4 : 3
204
+ end
205
+
206
+ # Clicks the field until its dropdown opens. A field re-rendered under the click is found again.
207
+ def select2_open(container, markup, **args)
208
+ wait = Capybara.default_max_wait_time.to_f / OPEN_ATTEMPTS
209
+ OPEN_ATTEMPTS.times do
210
+ return if container.matches_css?(markup[:open], wait: 0)
211
+
212
+ container.find(markup[:trigger], match: :first).click
213
+ return if container.matches_css?(markup[:open], wait:)
214
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError
215
+ container = select2_find_container(**args)
216
+ end
217
+ raise Capybara::ExpectationNotMet,
218
+ "select2 dropdown did not open after #{OPEN_ATTEMPTS} clicks on #{markup[:trigger]}"
219
+ end
220
+
221
+ # Opens the field (typing the value into the search box with `search: true`) and returns its MARKUP.
222
+ def select2_find_and_open(value, **args)
223
+ container = select2_find_container(**args)
224
+ markup = MARKUP.fetch(select2_version(container))
225
+ select2_open(container, markup, **args)
226
+
227
+ if args[:search]
228
+ select2_body.find(markup[:search]).send_keys(value)
229
+ select2_await_loaded(markup)
230
+ end
231
+ markup
232
+ end
233
+
234
+ def select2_logger
235
+ ::Selenium::WebDriver.logger
236
+ end
237
+ end
238
+ end
239
+
240
+ RSpec.configure do |config|
241
+ config.include Capybara::Select2
242
+ config.include Capybara::Selectors::TagSelector
243
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capybara-select
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - William Yeung
8
+ - Nikolay Moskvin
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 1980-01-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capybara
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '4'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '4'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rspec-core
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '3.0'
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '4'
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '3.0'
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '4'
53
+ - !ruby/object:Gem::Dependency
54
+ name: rspec-expectations
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '3.0'
60
+ - - "<"
61
+ - !ruby/object:Gem::Version
62
+ version: '4'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '3.0'
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: '4'
73
+ - !ruby/object:Gem::Dependency
74
+ name: selenium-webdriver
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '4.0'
80
+ - - "<"
81
+ - !ruby/object:Gem::Version
82
+ version: '5'
83
+ type: :runtime
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '4.0'
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: '5'
93
+ description: select2 and select2_filter for Capybara/RSpec, with retries for dropdowns
94
+ that close or re-render under the click and for results that load slowly. A fork
95
+ of capybara-select2.
96
+ email:
97
+ - william@tofugear.com
98
+ executables: []
99
+ extensions: []
100
+ extra_rdoc_files: []
101
+ files:
102
+ - Changes.md
103
+ - LICENSE.txt
104
+ - README.md
105
+ - capybara-select2.gemspec
106
+ - lib/capybara-select2.rb
107
+ - lib/capybara-select2/version.rb
108
+ - lib/capybara/selectors/tag_selector.rb
109
+ homepage: https://github.com/moskvin/capybara-select2
110
+ licenses:
111
+ - MIT
112
+ metadata:
113
+ homepage_uri: https://github.com/moskvin/capybara-select2
114
+ bug_tracker_uri: https://github.com/moskvin/capybara-select2/issues
115
+ changelog_uri: https://github.com/moskvin/capybara-select2/blob/master/Changes.md
116
+ source_code_uri: https://github.com/moskvin/capybara-select2
117
+ rubygems_mfa_required: 'true'
118
+ rdoc_options: []
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: 3.2.0
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ requirements: []
132
+ rubygems_version: 4.0.20
133
+ specification_version: 4
134
+ summary: Capybara helpers to pick options in select2 (3.x and 4.x) fields
135
+ test_files: []