capybara 2.9.0 → 2.9.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 074717523be47e7a162c2d4bc45f5ff49737e6a8
4
- data.tar.gz: 25c95e6c9273c09663933921ba177067e622ea65
3
+ metadata.gz: cc4841dedf9ca38322cb47a786b24f8628e62fd2
4
+ data.tar.gz: be5ea00f82b66a46769eab36218b26be66dda267
5
5
  SHA512:
6
- metadata.gz: d1db39b289e31ac1432a30cbe5ff8ce957867e1b3fd854813d8bfa954af0babb5a89ac1ccfa21ff6d5074b112a69e4b6deb751bc9c054026bad65d9a2f7d6e0d
7
- data.tar.gz: 635c3bfb9e2d366ad8bc87a2abe075f2286e496fd2171bf32e6ef6628a55f8f95dfee2fd8e326819ca81d1dc0c85ac0dfee86d0491c5710e5c53f6e756e50c65
6
+ metadata.gz: 266ef0ca4cec47b1692544d070b6cf467f366d52d4675dae21b2e2cce3985f9ea8a5b268f70d71e290cabe4f0fbf7134b39283e2ea180cabd7610d7c34ec06f7
7
+ data.tar.gz: d4ec85892ef15b4f1fee2b51b8b52a51119baaaf2a09b0abb096621197608e545036c0146cbcb64d860736cf014bb375186fec6d4f13d66e04e79959e174470c
data/History.md CHANGED
@@ -1,3 +1,10 @@
1
+ #Version 2.9.1
2
+ Release date: 2016-09-23
3
+
4
+ ### Fixed
5
+ * allow_label_click option did not work in some cases with Poltergeist - Issue #1762 [Thomas Walpole]
6
+ * matches_selector? should have access to all of a selectors options except the count options [Thomas Walpole]
7
+
1
8
  #Version 2.9.0
2
9
  Release date: 2016-09-19
3
10
 
data/README.md CHANGED
@@ -781,7 +781,7 @@ module MyModule
781
781
  include Capybara::DSL
782
782
 
783
783
  def login!
784
- within("//form[@id='session']") do
784
+ within(:xpath, "//form[@id='session']") do
785
785
  fill_in 'Email', :with => 'user@example.com'
786
786
  fill_in 'Password', :with => 'password'
787
787
  end
@@ -852,7 +852,7 @@ manually.
852
852
  require 'capybara'
853
853
 
854
854
  session = Capybara::Session.new(:webkit, my_rack_app)
855
- session.within("//form[@id='session']") do
855
+ session.within("form#session") do
856
856
  session.fill_in 'Email', :with => 'user@example.com'
857
857
  session.fill_in 'Password', :with => 'password'
858
858
  end
@@ -109,11 +109,12 @@ module Capybara
109
109
  allow_label_click = options.delete(:allow_label_click) { Capybara.automatic_label_click }
110
110
 
111
111
  begin
112
- find(:radio_button, locator, options).set(true)
113
- rescue Capybara::ElementNotFound => e
114
- raise unless allow_label_click
112
+ radio = find(:radio_button, locator, options)
113
+ radio.set(true)
114
+ rescue => e
115
+ raise unless allow_label_click && catch_error?(e)
115
116
  begin
116
- radio = find(:radio_button, locator, options.merge({wait: 0, visible: :hidden}))
117
+ radio ||= find(:radio_button, locator, options.merge({wait: 0, visible: :all}))
117
118
  label = find(:label, for: radio, wait: 0, visible: true)
118
119
  label.click unless radio.checked?
119
120
  rescue
@@ -145,11 +146,12 @@ module Capybara
145
146
  allow_label_click = options.delete(:allow_label_click) { Capybara.automatic_label_click }
146
147
 
147
148
  begin
148
- find(:checkbox, locator, options).set(true)
149
- rescue Capybara::ElementNotFound => e
150
- raise unless allow_label_click
149
+ cbox = find(:checkbox, locator, options)
150
+ cbox.set(true)
151
+ rescue => e
152
+ raise unless allow_label_click && catch_error?(e)
151
153
  begin
152
- cbox = find(:checkbox, locator, options.merge({wait: 0, visible: :hidden}))
154
+ cbox ||= find(:checkbox, locator, options.merge({wait: 0, visible: :all}))
153
155
  label = find(:label, for: cbox, wait: 0, visible: true)
154
156
  label.click unless cbox.checked?
155
157
  rescue
@@ -181,11 +183,12 @@ module Capybara
181
183
  allow_label_click = options.delete(:allow_label_click) { Capybara.automatic_label_click }
182
184
 
183
185
  begin
184
- find(:checkbox, locator, options).set(false)
185
- rescue Capybara::ElementNotFound => e
186
- raise unless allow_label_click
186
+ cbox = find(:checkbox, locator, options)
187
+ cbox.set(false)
188
+ rescue => e
189
+ raise unless allow_label_click && catch_error?(e)
187
190
  begin
188
- cbox = find(:checkbox, locator, options.merge({wait: 0, visible: :hidden}))
191
+ cbox ||= find(:checkbox, locator, options.merge({wait: 0, visible: :all}))
189
192
  label = find(:label, for: cbox, wait: 0, visible: true)
190
193
  label.click if cbox.checked?
191
194
  rescue
@@ -1,8 +1,6 @@
1
1
  module Capybara
2
2
  module Queries
3
3
  class MatchQuery < Capybara::Queries::SelectorQuery
4
- VALID_KEYS = [:text, :visible, :exact, :wait]
5
-
6
4
  def visible
7
5
  if options.has_key?(:visible)
8
6
  super
@@ -14,7 +12,7 @@ module Capybara
14
12
  private
15
13
 
16
14
  def valid_keys
17
- VALID_KEYS + @selector.custom_filters.keys
15
+ super - COUNT_KEYS
18
16
  end
19
17
  end
20
18
  end
@@ -4,7 +4,7 @@ module Capybara
4
4
  class SelectorQuery < Queries::BaseQuery
5
5
  attr_accessor :selector, :locator, :options, :expression, :find, :negative
6
6
 
7
- VALID_KEYS = COUNT_KEYS + [:text, :visible, :exact, :match, :wait, :filter_set]
7
+ VALID_KEYS = COUNT_KEYS + [:text, :id, :class, :visible, :exact, :match, :wait, :filter_set]
8
8
  VALID_MATCH = [:first, :smart, :prefer_exact, :one]
9
9
 
10
10
  def initialize(*args)
@@ -39,6 +39,8 @@ module Capybara
39
39
  def description
40
40
  @description = String.new("#{label} #{locator.inspect}")
41
41
  @description << " with text #{options[:text].inspect}" if options[:text]
42
+ @description << " with id #{options[:id]}" if options[:id]
43
+ @description << " with classes #{Array(options[:class]).join(',')}]" if options[:class]
42
44
  @description << selector.description(options)
43
45
  @description
44
46
  end
@@ -92,15 +94,16 @@ module Capybara
92
94
 
93
95
  def xpath(exact=nil)
94
96
  exact = self.exact? if exact.nil?
95
- if @expression.respond_to?(:to_xpath) and exact
97
+ expr = if @expression.respond_to?(:to_xpath) and exact
96
98
  @expression.to_xpath(:exact)
97
99
  else
98
100
  @expression.to_s
99
101
  end
102
+ filtered_xpath(expr)
100
103
  end
101
104
 
102
105
  def css
103
- @expression
106
+ filtered_css(@expression)
104
107
  end
105
108
 
106
109
  # @api private
@@ -141,7 +144,7 @@ module Capybara
141
144
  end
142
145
 
143
146
  def custom_keys
144
- query_filters.keys + @selector.expression_filters
147
+ @custom_keys ||= query_filters.keys + @selector.expression_filters
145
148
  end
146
149
 
147
150
  def assert_valid_keys
@@ -151,6 +154,32 @@ module Capybara
151
154
  end
152
155
  end
153
156
 
157
+ def filtered_xpath(expr)
158
+ if options.has_key?(:id) || options.has_key?(:class)
159
+ expr = "(#{expr})"
160
+ expr = "#{expr}[#{XPath.attr(:id) == options[:id]}]" if options.has_key?(:id) && !custom_keys.include?(:id)
161
+ if options.has_key?(:class) && !custom_keys.include?(:class)
162
+ class_xpath = Array(options[:class]).map do |klass|
163
+ "contains(concat(' ',normalize-space(@class),' '),' #{klass} ')"
164
+ end.join(" and ")
165
+ expr = "#{expr}[#{class_xpath}]"
166
+ end
167
+ end
168
+ expr
169
+ end
170
+
171
+ def filtered_css(expr)
172
+ if options.has_key?(:id) || options.has_key?(:class)
173
+ css_selectors = expr.split(',').map(&:rstrip)
174
+ expr = css_selectors.map do |sel|
175
+ sel += "##{Capybara::Selector::CSS.escape(options[:id])}" if options.has_key?(:id) && !custom_keys.include?(:id)
176
+ sel += Array(options[:class]).map { |k| ".#{Capybara::Selector::CSS.escape(k)}"}.join if options.has_key?(:class) && !custom_keys.include?(:class)
177
+ sel
178
+ end.join(", ")
179
+ end
180
+ expr
181
+ end
182
+
154
183
  def warn_exact_usage
155
184
  if options.has_key?(:exact) && !supports_exact?
156
185
  warn "The :exact option only has an effect on queries using the XPath#is method. Using it with the query \"#{expression.to_s}\" has no effect."
@@ -65,7 +65,7 @@ end
65
65
  # @filter [Boolean] :disabled Match disabled field?
66
66
  # @filter [Boolean] :multiple Match fields that accept multiple values
67
67
  Capybara.add_selector(:field) do
68
- xpath(:id, :name, :placeholder, :type, :class) do |locator, options|
68
+ xpath(:name, :placeholder, :type) do |locator, options|
69
69
  xpath = XPath.descendant(:input, :textarea, :select)[~XPath.attr(:type).one_of('submit', 'image', 'hidden')]
70
70
  if options[:type]
71
71
  type=options[:type].to_s
@@ -105,12 +105,10 @@ end
105
105
  # @filter [String, Array<String>] :class Matches the class(es) provided
106
106
  #
107
107
  Capybara.add_selector(:fieldset) do
108
- xpath(:id, :legend, :class) do |locator, options|
108
+ xpath(:legend) do |locator, options|
109
109
  xpath = XPath.descendant(:fieldset)
110
110
  xpath = xpath[XPath.attr(:id).equals(locator.to_s) | XPath.child(:legend)[XPath.string.n.is(locator.to_s)]] unless locator.nil?
111
- xpath = xpath[XPath.attr(:id).equals(options[:id])] if options[:id]
112
111
  xpath = xpath[XPath.child(:legend)[XPath.string.n.is(options[:legend])]] if options[:legend]
113
- xpath = xpath[find_by_attr(:class, options[:class])]
114
112
  xpath
115
113
  end
116
114
  end
@@ -128,7 +126,7 @@ end
128
126
  # @filter [String, Regexp] :href Matches the normalized href of the link
129
127
  #
130
128
  Capybara.add_selector(:link) do
131
- xpath(:id, :title, :alt, :class) do |locator, options={}|
129
+ xpath(:title, :alt) do |locator, options={}|
132
130
  xpath = XPath.descendant(:a)[XPath.attr(:href)]
133
131
  unless locator.nil?
134
132
  locator = locator.to_s
@@ -139,7 +137,7 @@ Capybara.add_selector(:link) do
139
137
  matchers |= XPath.attr(:'aria-label').is(locator) if Capybara.enable_aria_label
140
138
  xpath = xpath[matchers]
141
139
  end
142
- xpath = [:id, :title, :class].inject(xpath) { |memo, ef| memo[find_by_attr(ef, options[ef])] }
140
+ xpath = [:title].inject(xpath) { |memo, ef| memo[find_by_attr(ef, options[ef])] }
143
141
  xpath = xpath[XPath.descendant(:img)[XPath.attr(:alt).equals(options[:alt])]] if options[:alt]
144
142
  xpath
145
143
  end
@@ -167,7 +165,7 @@ end
167
165
  # @filter [String] :value Matches the value of an input button
168
166
  #
169
167
  Capybara.add_selector(:button) do
170
- xpath(:id, :value, :title, :class) do |locator, options={}|
168
+ xpath(:value, :title) do |locator, options={}|
171
169
  input_btn_xpath = XPath.descendant(:input)[XPath.attr(:type).one_of('submit', 'reset', 'image', 'button')]
172
170
  btn_xpath = XPath.descendant(:button)
173
171
  image_btn_xpath = XPath.descendant(:input)[XPath.attr(:type).equals('image')]
@@ -233,7 +231,7 @@ end
233
231
  #
234
232
  Capybara.add_selector(:fillable_field) do
235
233
  label "field"
236
- xpath(:id, :name, :placeholder, :class) do |locator, options|
234
+ xpath(:name, :placeholder) do |locator, options|
237
235
  xpath = XPath.descendant(:input, :textarea)[~XPath.attr(:type).one_of('submit', 'image', 'radio', 'checkbox', 'hidden', 'file')]
238
236
  locate_field(xpath, locator, options)
239
237
  end
@@ -267,7 +265,7 @@ end
267
265
  #
268
266
  Capybara.add_selector(:radio_button) do
269
267
  label "radio button"
270
- xpath(:id, :name, :class) do |locator, options|
268
+ xpath(:name) do |locator, options|
271
269
  xpath = XPath.descendant(:input)[XPath.attr(:type).equals('radio')]
272
270
  locate_field(xpath, locator, options)
273
271
  end
@@ -298,7 +296,7 @@ end
298
296
  # @filter [String] :option Match the value
299
297
  #
300
298
  Capybara.add_selector(:checkbox) do
301
- xpath(:id, :name, :class) do |locator, options|
299
+ xpath(:name) do |locator, options|
302
300
  xpath = XPath.descendant(:input)[XPath.attr(:type).equals('checkbox')]
303
301
  locate_field(xpath, locator, options)
304
302
  end
@@ -332,7 +330,7 @@ end
332
330
  #
333
331
  Capybara.add_selector(:select) do
334
332
  label "select box"
335
- xpath(:id, :name, :placeholder, :class) do |locator, options|
333
+ xpath(:name, :placeholder) do |locator, options|
336
334
  xpath = XPath.descendant(:select)
337
335
  locate_field(xpath, locator, options)
338
336
  end
@@ -408,7 +406,7 @@ end
408
406
  #
409
407
  Capybara.add_selector(:file_field) do
410
408
  label "file field"
411
- xpath(:id, :name, :class) do |locator, options|
409
+ xpath(:name) do |locator, options|
412
410
  xpath = XPath.descendant(:input)[XPath.attr(:type).equals('file')]
413
411
  locate_field(xpath, locator, options)
414
412
  end
@@ -466,17 +464,15 @@ end
466
464
  # @filter [String, Array<String>] :class Matches the class(es) provided
467
465
  #
468
466
  Capybara.add_selector(:table) do
469
- xpath(:id, :caption, :class) do |locator, options|
467
+ xpath(:caption) do |locator, options|
470
468
  xpath = XPath.descendant(:table)
471
469
  xpath = xpath[XPath.attr(:id).equals(locator.to_s) | XPath.descendant(:caption).is(locator.to_s)] unless locator.nil?
472
470
  xpath = xpath[XPath.descendant(:caption).equals(options[:caption])] if options[:caption]
473
- xpath = [:id, :class].inject(xpath) { |memo, ef| memo[find_by_attr(ef, options[ef])] }
474
471
  xpath
475
472
  end
476
473
 
477
474
  describe do |options|
478
475
  desc = String.new
479
- desc << " with id #{options[:id]}" if options[:id]
480
476
  desc << " with caption #{options[:caption]}" if options[:caption]
481
477
  desc
482
478
  end
@@ -492,7 +488,7 @@ end
492
488
  # @filter [String, Array<String>] :class Matches the class(es) provided
493
489
  #
494
490
  Capybara.add_selector(:frame) do
495
- xpath(:id, :name, :class) do |locator, options|
491
+ xpath(:name) do |locator, options|
496
492
  xpath = XPath.descendant(:iframe) + XPath.descendant(:frame)
497
493
  xpath = xpath[XPath.attr(:id).equals(locator.to_s) | XPath.attr(:name).equals(locator)] unless locator.nil?
498
494
  xpath = expression_filters.inject(xpath) { |memo, ef| memo[find_by_attr(ef, options[ef])] }
@@ -501,7 +497,6 @@ Capybara.add_selector(:frame) do
501
497
 
502
498
  describe do |options|
503
499
  desc = String.new
504
- desc << " with id #{options[:id]}" if options[:id]
505
500
  desc << " with name #{options[:name]}" if options[:name]
506
501
  desc
507
502
  end
@@ -0,0 +1,30 @@
1
+ module Capybara
2
+ class Selector
3
+ class CSS
4
+ def self.escape(str)
5
+ out = String.new("")
6
+ value = str.dup
7
+ out << value.slice!(0...1) if value =~ /^[-_]/
8
+ out << if value[0] =~ NMSTART
9
+ value.slice!(0...1)
10
+ else
11
+ escape_char(value.slice!(0...1))
12
+ end
13
+ out << value.gsub(/[^a-zA-Z0-9_-]/) {|c| escape_char c}
14
+ out
15
+ end
16
+
17
+ def self.escape_char(c)
18
+ return "\\%06x" % c.ord() unless c =~ %r{[ -/:-~]}
19
+ "\\#{c}"
20
+ end
21
+
22
+ S = '\u{80}-\u{D7FF}\u{E000}-\u{FFFD}\u{10000}-\u{10FFFF}'
23
+ H = /[0-9a-fA-F]/
24
+ UNICODE = /\\#{H}{1,6}[ \t\r\n\f]?/
25
+ NONASCII = /[#{S}]/
26
+ ESCAPE = /#{UNICODE}|\\[ -~#{S}]/
27
+ NMSTART = /[_a-zA-Z]|#{NONASCII}|#{ESCAPE}/
28
+ end
29
+ end
30
+ end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require 'capybara/selector/filter_set'
3
+ require 'capybara/selector/css'
3
4
  require 'xpath'
4
5
 
5
6
  #Patch XPath to allow a nil condition in where
@@ -201,7 +202,7 @@ module Capybara
201
202
  locate_xpath += XPath.descendant(:label)[XPath.string.n.is(locator)].descendant(xpath)
202
203
  end
203
204
 
204
- locate_xpath = [:id, :name, :placeholder, :class].inject(locate_xpath) { |memo, ef| memo[find_by_attr(ef, options[ef])] }
205
+ locate_xpath = [:name, :placeholder].inject(locate_xpath) { |memo, ef| memo[find_by_attr(ef, options[ef])] }
205
206
  locate_xpath
206
207
  end
207
208
 
@@ -161,11 +161,20 @@ Capybara::SpecHelper.spec "#check" do
161
161
  expect{@session.check('form_cars_mclaren')}.to raise_error(Capybara::ElementNotFound, 'Unable to find checkbox "form_cars_mclaren"')
162
162
  end
163
163
 
164
- it "should check via the label if allow_label_click == true" do
165
- expect(@session.find(:checkbox, 'form_cars_tesla', unchecked: true, visible: :hidden)).to be
166
- @session.check('form_cars_tesla', allow_label_click: true)
167
- @session.click_button('awesome')
168
- expect(extract_results(@session)['cars']).to include('tesla')
164
+ context "with allow_label_click == true" do
165
+ it "should check via the label if input is hidden" do
166
+ expect(@session.find(:checkbox, 'form_cars_tesla', unchecked: true, visible: :hidden)).to be
167
+ @session.check('form_cars_tesla', allow_label_click: true)
168
+ @session.click_button('awesome')
169
+ expect(extract_results(@session)['cars']).to include('tesla')
170
+ end
171
+
172
+ it "should check via the label if input is moved off the left edge of the page" do
173
+ expect(@session.find(:checkbox, 'form_cars_pagani', unchecked: true, visible: :all)).to be
174
+ @session.check('form_cars_pagani', allow_label_click: true)
175
+ @session.click_button('awesome')
176
+ expect(extract_results(@session)['cars']).to include('pagani')
177
+ end
169
178
  end
170
179
  end
171
180
  end
@@ -42,6 +42,12 @@ Capybara::SpecHelper.spec '#match_selector?' do
42
42
  expect(@element.matches_xpath?("//span", text: '42')).to be true
43
43
  expect(@element.matches_xpath?("//span", text: 'Nope')).to be false
44
44
  end
45
+
46
+ it 'should accept selector filters' do
47
+ @session.visit('/form')
48
+ cbox = @session.find(:css, '#form_pets_dog')
49
+ expect(cbox.matches_selector?(:checkbox, id: 'form_pets_dog', option: 'dog', name: 'form[pets][]', checked: true)).to be true
50
+ end
45
51
  end
46
52
 
47
53
  Capybara::SpecHelper.spec '#not_matches_selector?' do
@@ -33,7 +33,7 @@ Capybara::SpecHelper.spec Capybara::Selector do
33
33
  end
34
34
  end
35
35
 
36
- describe "locate_field selectors" do
36
+ describe "field selectors" do
37
37
  it "can find specifically by id" do
38
38
  expect(@session.find(:field, id: 'customer_email').value).to eq "ben@ben.com"
39
39
  end
@@ -5,9 +5,9 @@
5
5
 
6
6
  <p>
7
7
  <label for="form_title">Title</label>
8
- <select name="form[title]" id="form_title">
9
- <option>Mrs</option>
10
- <option>Mr</option>
8
+ <select name="form[title]" id="form_title" class="title">
9
+ <option class="title">Mrs</option>
10
+ <option class="title">Mr</option>
11
11
  <option>Miss</option>
12
12
  <option disabled="disabled">Other</option>
13
13
  </select>
@@ -183,6 +183,8 @@ New line after and before textarea tag
183
183
  <label for="form_cars_tesla">Tesla</label>
184
184
  <input type="checkbox" value="ferrari" name="form[cars][]" id="form_cars_ferrari" checked="checked" style="display: none"/>
185
185
  <label for="form_cars_ferrari">Ferrari</label>
186
+ <input type="checkbox" value="pagani" name="form[cars][]" id="form_cars_pagani" style="position: absolute; left: -9999px"/>
187
+ <label for="form_cars_pagani">Pagani</label>
186
188
  <input type="checkbox" value="ariel" name="form[cars][]" id="form_cars_ariel" style="display: none"/>
187
189
  <label>
188
190
  McLaren
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Capybara
3
- VERSION = '2.9.0'
3
+ VERSION = '2.9.1'
4
4
  end
@@ -18,10 +18,13 @@ RSpec.describe Capybara do
18
18
  <p class="b">Some Content</p>
19
19
  <p class="b"></p>
20
20
  </div>
21
- <input type="checkbox"/>
21
+ <div id="#special">
22
+ </div>
23
+ <input id="2checkbox" class="2checkbox" type="checkbox"/>
22
24
  <input type="radio"/>
23
- <input type="text"/>
24
- <input type="file"/>
25
+ <label for="my_text_input">My Text Input</label>
26
+ <input type="text" name="form[my_text_input]" placeholder="my text" id="my_text_input"/>
27
+ <input type="file" id="file" class=".special file"/>
25
28
  <a href="#">link</a>
26
29
  <fieldset></fieldset>
27
30
  <select>
@@ -42,6 +45,10 @@ RSpec.describe Capybara do
42
45
  css { |css_class| "div.#{css_class}" }
43
46
  filter(:not_empty, boolean: true, default: true, skip_if: :all) { |node, value| value ^ (node.text == '') }
44
47
  end
48
+
49
+ Capybara.add_selector :custom_css_selector do
50
+ css { |selector| selector }
51
+ end
45
52
  end
46
53
 
47
54
  describe "modify_selector" do
@@ -89,6 +96,77 @@ RSpec.describe Capybara do
89
96
  end
90
97
  end
91
98
 
99
+ context "with :id option" do
100
+ it "works with compound css selectors" do
101
+ expect(string.all(:custom_css_selector, "div, h1", id: 'page').size).to eq 1
102
+ expect(string.all(:custom_css_selector, "h1, div", id: 'page').size).to eq 1
103
+ end
104
+
105
+ it "works with 'special' characters" do
106
+ skip "We support old Nokogiris but they have their limits" if Gem::Version.new(Nokogiri::VERSION) < Gem::Version.new('1.6.8')
107
+ expect(string.find(:custom_css_selector, "div", id: "#special")[:id]).to eq '#special'
108
+ expect(string.find(:custom_css_selector, "input", id: "2checkbox")[:id]).to eq '2checkbox'
109
+ end
110
+ end
111
+
112
+ context "with :class option" do
113
+ it "works with compound css selectors" do
114
+ expect(string.all(:custom_css_selector, "div, h1", class: 'a').size).to eq 2
115
+ expect(string.all(:custom_css_selector, "h1, div", class: 'a').size).to eq 2
116
+ end
117
+
118
+ it "works with 'special' characters" do
119
+ skip "We support old Nokogiris but they have their limits" if Gem::Version.new(Nokogiri::VERSION) < Gem::Version.new('1.6.8')
120
+ expect(string.find(:custom_css_selector, "input", class: ".special")[:id]).to eq 'file'
121
+ expect(string.find(:custom_css_selector, "input", class: "2checkbox")[:id]).to eq '2checkbox'
122
+ end
123
+ end
124
+
125
+ # :css, :xpath, :id, :field, :fieldset, :link, :button, :link_or_button, :fillable_field, :radio_button, :checkbox, :select,
126
+ # :option, :file_field, :label, :table, :frame
127
+
128
+ describe ":css selector" do
129
+ it "finds by CSS locator" do
130
+ expect(string.find(:css, "input#my_text_input")[:name]).to eq 'form[my_text_input]'
131
+ end
132
+ end
133
+
134
+ describe ":xpath selector" do
135
+ it "finds by XPath locator" do
136
+ expect(string.find(:xpath, './/input[@id="my_text_input"]')[:name]).to eq 'form[my_text_input]'
137
+ end
138
+ end
139
+
140
+ describe ":id selector" do
141
+ it "finds by locator" do
142
+ expect(string.find(:id, "my_text_input")[:name]).to eq 'form[my_text_input]'
143
+ end
144
+ end
145
+
146
+ describe ":field selector" do
147
+ it "finds by locator" do
148
+ expect(string.find(:field, 'My Text Input')[:id]).to eq 'my_text_input'
149
+ expect(string.find(:field, 'my_text_input')[:id]).to eq 'my_text_input'
150
+ expect(string.find(:field, 'form[my_text_input]')[:id]).to eq 'my_text_input'
151
+ end
152
+
153
+ it "finds by id" do
154
+ expect(string.find(:field, id: 'my_text_input')[:name]).to eq 'form[my_text_input]'
155
+ end
156
+
157
+ it "finds by name" do
158
+ expect(string.find(:field, name: 'form[my_text_input]')[:id]).to eq 'my_text_input'
159
+ end
160
+
161
+ it "finds by placeholder" do
162
+ expect(string.find(:field, placeholder: 'my text')[:id]).to eq 'my_text_input'
163
+ end
164
+
165
+ it "finds by type" do
166
+ expect(string.find(:field, type: 'file')[:id]).to eq 'file'
167
+ end
168
+ end
169
+
92
170
  describe ":option selector" do
93
171
  it "finds disabled options" do
94
172
  expect(string.find(:option, disabled: true).value).to eq 'b'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.0
4
+ version: 2.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Walpole
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain:
12
12
  - gem-public_cert.pem
13
- date: 2016-09-19 00:00:00.000000000 Z
13
+ date: 2016-09-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: nokogiri
@@ -284,6 +284,7 @@ files:
284
284
  - lib/capybara/rspec/features.rb
285
285
  - lib/capybara/rspec/matchers.rb
286
286
  - lib/capybara/selector.rb
287
+ - lib/capybara/selector/css.rb
287
288
  - lib/capybara/selector/filter.rb
288
289
  - lib/capybara/selector/filter_set.rb
289
290
  - lib/capybara/selector/selector.rb