capybara 3.25.0 → 3.26.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 439a641ea3d9a06bcc674c159c3ef16612fb29874e71f11ef7bb2d0e73382892
4
- data.tar.gz: a5e57dfb62e3682a87f05650a13945545a61183a84a15498390d07aa3ec6e4ed
3
+ metadata.gz: 799d14b5b1f64c06a58d962e7187f439332772f95d9d946d7452cf04d1710669
4
+ data.tar.gz: 79d2dc83febaaae726776d509c01e591558a7a174c2e8b58733082981610c57c
5
5
  SHA512:
6
- metadata.gz: d50ab813eecabef7465c9a42904174f65eefe6dc8e0f92fea59d523753582c1797a1a87880a1d9805edb8f74e33585314841d6fac7abcf2781a627ac9703191e
7
- data.tar.gz: 0d4f2b360e528a3fae6357072592ac5295cb500d68251d23bc66a014fc62528473e960b4049d4e24a5339a8a41f02f15c70b7ae59b5f51ebfb1a7369afa47f27
6
+ metadata.gz: ccb7b53977549aaa7597577b74a5bde4ebcaee1fa9137b7aad1c7317f73b980cfb27552921386af12601febffc2326c481915d96ac6c56f87f594a9c726ea855
7
+ data.tar.gz: 87c6490f0f8132750d30391aadb007ae9376d03d093c12f783ed32a3a373b33541c0ef66f7b0f7c8c069b982203542e92b33e294a80611b52dbc79e7d20021dc
data/History.md CHANGED
@@ -1,3 +1,19 @@
1
+ # Version 3.26.0
2
+ Release date: 2019-07-15
3
+
4
+ ### Added
5
+
6
+ * `w3c_click_offset` configuration option applies to `right_click` and `double_click` as well as `click`
7
+ * Warning when passing `nil` to the text/content assertions/expectations
8
+ * `Session#server_url` returns the base url the AUT is being run at (when controlled by Capybara)
9
+ * `option` selector type accepts an integer as locator
10
+
11
+ ### Fixed
12
+
13
+ * Default puma server registration now specifies `queue_requests: false` - Issue #2227
14
+ * Workaround issue with FF 68 and hanging during reset if a system modal is visible
15
+ * Don't expand file path if it's already absolute - Issue #2228
16
+
1
17
  # Version 3.25.0
2
18
  Release date: 2019-06-27
3
19
 
data/README.md CHANGED
@@ -7,7 +7,8 @@
7
7
  [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jnicklas/capybara?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
8
8
  [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=capybara&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=capybara&package-manager=bundler&version-scheme=semver)
9
9
 
10
- **Note** You are viewing the README for the 3.25.x version of Capybara
10
+ **Note** You are viewing the README for the 3.26.x version of Capybara.
11
+
11
12
 
12
13
  Capybara helps you test web applications by simulating how a real user would
13
14
  interact with your app. It is agnostic about the driver running your tests and
@@ -162,12 +162,10 @@ module Capybara
162
162
  # @option options [Integer] y Y coordinate to offset the click location. If {Capybara.configure w3c_click_offset} is `true` the
163
163
  # offset will be from the element center, otherwise it will be from the top left corner of the element
164
164
  # @return [Capybara::Node::Element] The element
165
- def click(*keys, wait: nil, **options)
166
- raise ArgumentError, 'You must specify both x: and y: for a click offset' if nil ^ options[:x] ^ options[:y]
167
-
168
- options[:offset] = :center if session_options.w3c_click_offset
169
- synchronize(wait) { base.click(Array(keys), options) }
170
- self
165
+ def click(*keys, **options)
166
+ perform_click_action(keys, options) do |k, opts|
167
+ base.click(k, opts)
168
+ end
171
169
  end
172
170
 
173
171
  ##
@@ -177,11 +175,10 @@ module Capybara
177
175
  # @macro action_waiting_behavior
178
176
  # @macro click_modifiers
179
177
  # @return [Capybara::Node::Element] The element
180
- def right_click(*keys, wait: nil, **offset)
181
- raise ArgumentError, 'You must specify both x: and y: for a click offset' if nil ^ offset[:x] ^ offset[:y]
182
-
183
- synchronize(wait) { base.right_click(keys, offset) }
184
- self
178
+ def right_click(*keys, **options)
179
+ perform_click_action(keys, options) do |k, opts|
180
+ base.right_click(k, opts)
181
+ end
185
182
  end
186
183
 
187
184
  ##
@@ -191,11 +188,10 @@ module Capybara
191
188
  # @macro action_waiting_behavior
192
189
  # @macro click_modifiers
193
190
  # @return [Capybara::Node::Element] The element
194
- def double_click(*keys, wait: nil, **offset)
195
- raise ArgumentError, 'You must specify both x: and y: for a click offset' if nil ^ offset[:x] ^ offset[:y]
196
-
197
- synchronize(wait) { base.double_click(keys, offset) }
198
- self
191
+ def double_click(*keys, **options)
192
+ perform_click_action(keys, options) do |k, opts|
193
+ base.double_click(k, opts)
194
+ end
199
195
  end
200
196
 
201
197
  ##
@@ -556,6 +552,16 @@ module Capybara
556
552
  return result;
557
553
  }).apply(this, arguments)
558
554
  JS
555
+
556
+ private
557
+
558
+ def perform_click_action(keys, wait: nil, **options)
559
+ raise ArgumentError, 'You must specify both x: and y: for a click offset' if nil ^ options[:x] ^ options[:y]
560
+
561
+ options[:offset] ||= :center if session_options.w3c_click_offset
562
+ synchronize(wait) { yield keys, options }
563
+ self
564
+ end
559
565
  end
560
566
  end
561
567
  end
@@ -6,11 +6,17 @@ module Capybara
6
6
  class TextQuery < BaseQuery
7
7
  def initialize(type = nil, expected_text, session_options:, **options) # rubocop:disable Style/OptionalArguments
8
8
  @type = type.nil? ? default_type : type
9
- @expected_text = expected_text.is_a?(Regexp) ? expected_text : expected_text.to_s
10
9
  @options = options
11
10
  super(@options)
12
11
  self.session_options = session_options
13
12
 
13
+ if expected_text.nil? && !exact?
14
+ warn 'Checking for expected text of nil is confusing and/or pointless since it will always match. '\
15
+ 'Please specify a string or regexp instead.'
16
+ end
17
+
18
+ @expected_text = expected_text.is_a?(Regexp) ? expected_text : expected_text.to_s
19
+
14
20
  @search_regexp = Capybara::Helpers.to_regexp(@expected_text, exact: exact?)
15
21
 
16
22
  assert_valid_keys
@@ -23,7 +23,7 @@ Capybara.register_server :puma do |app, port, host, **options|
23
23
  # If we just run the Puma Rack handler it installs signal handlers which prevent us from being able to interrupt tests.
24
24
  # Therefore construct and run the Server instance ourselves.
25
25
  # Rack::Handler::Puma.run(app, { Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false }.merge(options))
26
- options = { Host: host, Port: port, Threads: '0:4', workers: 0, daemon: false }.merge(options)
26
+ options = { Host: host, Port: port, Threads: '0:4', workers: 0, daemon: false, queue_requests: false }.merge(options)
27
27
  conf = Rack::Handler::Puma.config(app, options)
28
28
  events = conf.options[:Silent] ? ::Puma::Events.strings : ::Puma::Events.stdio
29
29
 
@@ -12,32 +12,37 @@ require 'capybara/rspec/matchers/become_closed'
12
12
 
13
13
  module Capybara
14
14
  module RSpecMatchers
15
- # RSpec matcher for whether the element(s) matching a given selector exist
16
- # See {Capybara::Node::Matcher#assert_selector}
15
+ # RSpec matcher for whether the element(s) matching a given selector exist.
16
+ #
17
+ # @see Capybara::Node::Matchers#assert_selector
17
18
  def have_selector(*args, &optional_filter_block)
18
19
  Matchers::HaveSelector.new(*args, &optional_filter_block)
19
20
  end
20
21
 
21
- # RSpec matcher for whether the element(s) matching a group of selectors exist
22
- # See {Capybara::Node::Matcher#assert_all_of_selectors}
22
+ # RSpec matcher for whether the element(s) matching a group of selectors exist.
23
+ #
24
+ # @see Capybara::Node::Matchers#assert_all_of_selectors
23
25
  def have_all_of_selectors(*args, &optional_filter_block)
24
26
  Matchers::HaveAllSelectors.new(*args, &optional_filter_block)
25
27
  end
26
28
 
27
- # RSpec matcher for whether no element(s) matching a group of selectors exist
28
- # See {Capybara::Node::Matcher#assert_none_of_selectors}
29
+ # RSpec matcher for whether no element(s) matching a group of selectors exist.
30
+ #
31
+ # @see Capybara::Node::Matchers#assert_none_of_selectors
29
32
  def have_none_of_selectors(*args, &optional_filter_block)
30
33
  Matchers::HaveNoSelectors.new(*args, &optional_filter_block)
31
34
  end
32
35
 
33
- # RSpec matcher for whether the element(s) matching any of a group of selectors exist
34
- # See {Capybara::Node::Matcher#assert_any_of_selectors}
36
+ # RSpec matcher for whether the element(s) matching any of a group of selectors exist.
37
+ #
38
+ # @see Capybara::Node::Matchers#assert_any_of_selectors
35
39
  def have_any_of_selectors(*args, &optional_filter_block)
36
40
  Matchers::HaveAnySelectors.new(*args, &optional_filter_block)
37
41
  end
38
42
 
39
- # RSpec matcher for whether the current element matches a given selector
40
- # See {Capybara::Node::Matchers#assert_matches_selector}
43
+ # RSpec matcher for whether the current element matches a given selector.
44
+ #
45
+ # @see Capybara::Node::Matchers#assert_matches_selector
41
46
  def match_selector(*args, &optional_filter_block)
42
47
  Matchers::MatchSelector.new(*args, &optional_filter_block)
43
48
  end
@@ -53,20 +58,24 @@ module Capybara
53
58
  end
54
59
 
55
60
  # @!method have_xpath(xpath, **options, &optional_filter_block)
56
- # RSpec matcher for whether elements(s) matching a given xpath selector exist
57
- # See {Capybara::Node::Matchers#has_xpath?}
61
+ # RSpec matcher for whether elements(s) matching a given xpath selector exist.
62
+ #
63
+ # @see Capybara::Node::Matchers#has_xpath?
58
64
 
59
65
  # @!method have_css(css, **options, &optional_filter_block)
60
66
  # RSpec matcher for whether elements(s) matching a given css selector exist
61
- # See {Capybara::Node::Matchers#has_css?}
67
+ #
68
+ # @see Capybara::Node::Matchers#has_css?
62
69
 
63
70
  # @!method match_xpath(xpath, **options, &optional_filter_block)
64
- # RSpec matcher for whether the current element matches a given xpath selector
65
- # See {Capybara::Node::Matchers#matches_xpath?}
71
+ # RSpec matcher for whether the current element matches a given xpath selector.
72
+ #
73
+ # @see Capybara::Node::Matchers#matches_xpath?
66
74
 
67
75
  # @!method match_css(css, **options, &optional_filter_block)
68
- # RSpec matcher for whether the current element matches a given css selector
69
- # See {Capybara::Node::Matchers#matches_css?}
76
+ # RSpec matcher for whether the current element matches a given css selector.
77
+ #
78
+ # @see Capybara::Node::Matchers#matches_css?
70
79
 
71
80
  %i[link button field select table].each do |selector|
72
81
  define_method "have_#{selector}" do |locator = nil, **options, &optional_filter_block|
@@ -75,24 +84,29 @@ module Capybara
75
84
  end
76
85
 
77
86
  # @!method have_link(locator = nil, **options, &optional_filter_block)
78
- # RSpec matcher for links
79
- # See {Capybara::Node::Matchers#has_link?}
87
+ # RSpec matcher for links.
88
+ #
89
+ # @see Capybara::Node::Matchers#has_link?
80
90
 
81
91
  # @!method have_button(locator = nil, **options, &optional_filter_block)
82
- # RSpec matcher for buttons
83
- # See {Capybara::Node::Matchers#has_button?}
92
+ # RSpec matcher for buttons.
93
+ #
94
+ # @see Capybara::Node::Matchers#has_button?
84
95
 
85
96
  # @!method have_field(locator = nil, **options, &optional_filter_block)
86
- # RSpec matcher for links
87
- # See {Capybara::Node::Matchers#has_field?}
97
+ # RSpec matcher for links.
98
+ #
99
+ # @see Capybara::Node::Matchers#has_field?
88
100
 
89
101
  # @!method have_select(locator = nil, **options, &optional_filter_block)
90
- # RSpec matcher for select elements
91
- # See {Capybara::Node::Matchers#has_select?}
102
+ # RSpec matcher for select elements.
103
+ #
104
+ # @see Capybara::Node::Matchers#has_select?
92
105
 
93
106
  # @!method have_table(locator = nil, **options, &optional_filter_block)
94
- # RSpec matcher for table elements
95
- # See {Capybara::Node::Matchers#has_table?}
107
+ # RSpec matcher for table elements.
108
+ #
109
+ # @see Capybara::Node::Matchers#has_table?
96
110
 
97
111
  %i[checked unchecked].each do |state|
98
112
  define_method "have_#{state}_field" do |locator = nil, **options, &optional_filter_block|
@@ -101,15 +115,18 @@ module Capybara
101
115
  end
102
116
 
103
117
  # @!method have_checked_field(locator = nil, **options, &optional_filter_block)
104
- # RSpec matcher for checked fields
105
- # See {Capybara::Node::Matchers#has_checked_field?}
118
+ # RSpec matcher for checked fields.
119
+ #
120
+ # @see Capybara::Node::Matchers#has_checked_field?
106
121
 
107
122
  # @!method have_unchecked_field(locator = nil, **options, &optional_filter_block)
108
- # RSpec matcher for unchecked fields
109
- # See {Capybara::Node::Matchers#has_unchecked_field?}
123
+ # RSpec matcher for unchecked fields.
124
+ #
125
+ # @see Capybara::Node::Matchers#has_unchecked_field?
110
126
 
111
- # RSpec matcher for text content
112
- # See {Capybara::Node::Matchers#assert_text}
127
+ # RSpec matcher for text content.
128
+ #
129
+ # @see Capybara::Node::Matchers#assert_text
113
130
  def have_text(*args)
114
131
  Matchers::HaveText.new(*args)
115
132
  end
@@ -119,14 +136,16 @@ module Capybara
119
136
  Matchers::HaveTitle.new(title, options)
120
137
  end
121
138
 
122
- # RSpec matcher for the current path
123
- # See {Capybara::SessionMatchers#assert_current_path}
139
+ # RSpec matcher for the current path.
140
+ #
141
+ # @see Capybara::SessionMatchers#assert_current_path
124
142
  def have_current_path(path, **options)
125
143
  Matchers::HaveCurrentPath.new(path, options)
126
144
  end
127
145
 
128
- # RSpec matcher for element style
129
- # See {Capybara::Node::Matchers#matches_style?}
146
+ # RSpec matcher for element style.
147
+ #
148
+ # @see Capybara::Node::Matchers#matches_style?
130
149
  def match_style(styles, **options)
131
150
  Matchers::MatchStyle.new(styles, options)
132
151
  end
@@ -154,24 +173,27 @@ module Capybara
154
173
  end
155
174
  end
156
175
 
157
- # RSpec matcher for whether sibling element(s) matching a given selector exist
158
- # See {Capybara::Node::Matcher#assert_sibling}
176
+ # RSpec matcher for whether sibling element(s) matching a given selector exist.
177
+ #
178
+ # @see Capybara::Node::Matchers#assert_sibling
159
179
  def have_sibling(*args, &optional_filter_block)
160
180
  Matchers::HaveSibling.new(*args, &optional_filter_block)
161
181
  end
162
182
 
163
- # RSpec matcher for whether ancestor element(s) matching a given selector exist
164
- # See {Capybara::Node::Matcher#assert_ancestor}
183
+ # RSpec matcher for whether ancestor element(s) matching a given selector exist.
184
+ #
185
+ # @see Capybara::Node::Matchers#assert_ancestor
165
186
  def have_ancestor(*args, &optional_filter_block)
166
187
  Matchers::HaveAncestor.new(*args, &optional_filter_block)
167
188
  end
168
189
 
169
190
  ##
170
191
  # Wait for window to become closed.
192
+ #
171
193
  # @example
172
194
  # expect(window).to become_closed(wait: 0.8)
173
- # @param options [Hash] optional param
174
- # @option options [Numeric] :wait (Capybara.default_max_wait_time) Maximum wait time
195
+ #
196
+ # @option options [Numeric] :wait Maximum wait time. Defaults to {Capybara.configure default_max_wait_time}
175
197
  def become_closed(**options)
176
198
  Matchers::BecomeClosed.new(options)
177
199
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- Capybara.add_selector(:option, locator_type: [String, Symbol]) do
3
+ Capybara.add_selector(:option, locator_type: [String, Symbol, Integer]) do
4
4
  xpath do |locator|
5
5
  xpath = XPath.descendant(:option)
6
6
  xpath = xpath[XPath.string.n.is(locator.to_s)] unless locator.nil?
@@ -375,8 +375,11 @@ private
375
375
  begin
376
376
  wait.until do
377
377
  alert = @browser.switch_to.alert
378
- regexp = text.is_a?(Regexp) ? text : Regexp.escape(text.to_s)
379
- alert.text.match?(regexp) ? alert : nil
378
+ regexp = text.is_a?(Regexp) ? text : Regexp.new(Regexp.escape(text.to_s))
379
+ matched = alert.text.match?(regexp)
380
+ raise Capybara::ModalNotFound, "Unable to find modal dialog with #{text} - found '#{alert.text}' instead." unless matched
381
+
382
+ alert
380
383
  end
381
384
  rescue *find_modal_errors
382
385
  raise Capybara::ModalNotFound, "Unable to find modal dialog#{" with #{text}" if text}"
@@ -39,6 +39,15 @@ module Capybara::Selenium::Driver::W3CFirefoxDriver
39
39
  # Use instance variable directly so we avoid starting the browser just to reset the session
40
40
  return unless @browser
41
41
 
42
+ if browser_version >= 68
43
+ begin
44
+ # Firefox 68 hangs if we try to switch windows while a modal is visible
45
+ browser.switch_to.alert&.dismiss
46
+ rescue Selenium::WebDriver::Error::NoSuchAlertError # rubocop:disable Lint/HandleExceptions
47
+ # Swallow
48
+ end
49
+ end
50
+
42
51
  switch_to_window(window_handles.first)
43
52
  window_handles.slice(1..-1).each { |win| close_window(win) }
44
53
  super
@@ -68,6 +77,10 @@ private
68
77
  def build_node(native_node, initial_cache = {})
69
78
  ::Capybara::Selenium::FirefoxNode.new(self, native_node, initial_cache)
70
79
  end
80
+
81
+ def browser_version
82
+ browser.capabilities[:browser_version].to_f
83
+ end
71
84
  end
72
85
 
73
86
  Capybara::Selenium::Driver.register_specialization :firefox, Capybara::Selenium::Driver::FirefoxDriver
@@ -300,7 +300,10 @@ private
300
300
 
301
301
  def set_file(value) # rubocop:disable Naming/AccessorMethodName
302
302
  path_names = value.to_s.empty? ? [] : value
303
- native.send_keys(Array(path_names).map(&File.method(:expand_path)).join("\n"))
303
+ file_names = Array(path_names).map do |pn|
304
+ Pathname.new(pn).absolute? ? pn : File.expand_path(pn)
305
+ end.join("\n")
306
+ native.send_keys(file_names)
304
307
  end
305
308
 
306
309
  def set_content_editable(value) # rubocop:disable Naming/AccessorMethodName
@@ -86,6 +86,10 @@ module Capybara
86
86
  self
87
87
  end
88
88
 
89
+ def base_url
90
+ "http#{'s' if using_ssl?}://#{host}:#{port}"
91
+ end
92
+
89
93
  private
90
94
 
91
95
  def middleware
@@ -806,6 +806,10 @@ module Capybara
806
806
  end
807
807
  end
808
808
 
809
+ def server_url
810
+ @server&.base_url
811
+ end
812
+
809
813
  private
810
814
 
811
815
  @@instance_created = false # rubocop:disable Style/ClassVars
@@ -863,10 +867,6 @@ module Capybara
863
867
  end
864
868
  end
865
869
 
866
- def server_url
867
- "http#{'s' if @server.using_ssl?}://#{@server.host}:#{@server.port}" if @server
868
- end
869
-
870
870
  def adjust_server_port(uri)
871
871
  uri.port ||= @server.port if @server && config.always_include_port
872
872
  end
@@ -139,6 +139,12 @@ Capybara::SpecHelper.spec '#has_text?' do
139
139
  expect(@session).to have_text(nil)
140
140
  end
141
141
 
142
+ it 'should warn when passed nil' do
143
+ @session.visit('/with_html')
144
+ expect_any_instance_of(Kernel).to receive(:warn).with(/Checking for expected text of nil is confusing/) # rubocop:disable RSpec/AnyInstance
145
+ expect(@session).to have_text(nil)
146
+ end
147
+
142
148
  it 'should wait for text to appear', requires: [:js] do
143
149
  Capybara.using_wait_time(3) do
144
150
  @session.visit('/with_js')
@@ -751,19 +751,46 @@ Capybara::SpecHelper.spec 'node' do
751
751
  @clicker = @session.find(:id, 'clicker')
752
752
  end
753
753
 
754
- it 'should offset from top left of element' do
755
- @clicker.click(x: 10, y: 5)
756
- expect(@session).to have_text(/clicked at 110,105/)
757
- end
754
+ context 'when w3c_click_offset is false' do
755
+ before do
756
+ Capybara.w3c_click_offset = false
757
+ end
758
+
759
+ it 'should offset from top left of element' do
760
+ @clicker.double_click(x: 10, y: 5)
761
+ expect(@session).to have_text(/clicked at 110,105/)
762
+ end
763
+
764
+ it 'should offset outside the element' do
765
+ @clicker.double_click(x: -15, y: -10)
766
+ expect(@session).to have_text(/clicked at 85,90/)
767
+ end
758
768
 
759
- it 'should offset outside the element' do
760
- @clicker.click(x: -15, y: -10)
761
- expect(@session).to have_text(/clicked at 85,90/)
769
+ it 'should default to click the middle' do
770
+ @clicker.double_click
771
+ expect(@session).to have_text(/clicked at 150,150/)
772
+ end
762
773
  end
763
774
 
764
- it 'should default to click the middle' do
765
- @clicker.click
766
- expect(@session).to have_text(/clicked at 150,150/)
775
+ context 'when w3c_click_offset is true' do
776
+ before do
777
+ Capybara.w3c_click_offset = true
778
+ end
779
+
780
+ it 'should offset from center of element' do
781
+ @clicker.double_click(x: 10, y: 5)
782
+ expect(@session).to have_text(/clicked at 160,155/)
783
+ end
784
+
785
+ it 'should offset outside from center of element' do
786
+ @clicker.double_click(x: -65, y: -60)
787
+ expect(@session).to have_text(/clicked at 85,90/)
788
+ end
789
+
790
+ it 'should default to click the middle' do
791
+ @clicker.double_click
792
+ expect(@session).to have_text(/clicked at 150,150/)
793
+ end
767
794
  end
768
795
  end
769
796
  end
@@ -807,19 +834,46 @@ Capybara::SpecHelper.spec 'node' do
807
834
  @clicker = @session.find(:id, 'clicker')
808
835
  end
809
836
 
810
- it 'should offset from top left of element' do
811
- @clicker.click(x: 10, y: 5)
812
- expect(@session).to have_text(/clicked at 110,105/)
813
- end
837
+ context 'when w3c_click_offset is false' do
838
+ before do
839
+ Capybara.w3c_click_offset = false
840
+ end
841
+
842
+ it 'should offset from top left of element' do
843
+ @clicker.right_click(x: 10, y: 5)
844
+ expect(@session).to have_text(/clicked at 110,105/)
845
+ end
846
+
847
+ it 'should offset outside the element' do
848
+ @clicker.right_click(x: -15, y: -10)
849
+ expect(@session).to have_text(/clicked at 85,90/)
850
+ end
814
851
 
815
- it 'should offset outside the element' do
816
- @clicker.click(x: -15, y: -10)
817
- expect(@session).to have_text(/clicked at 85,90/)
852
+ it 'should default to click the middle' do
853
+ @clicker.right_click
854
+ expect(@session).to have_text(/clicked at 150,150/)
855
+ end
818
856
  end
819
857
 
820
- it 'should default to click the middle' do
821
- @clicker.click
822
- expect(@session).to have_text(/clicked at 150,150/)
858
+ context 'when w3c_click_offset is true' do
859
+ before do
860
+ Capybara.w3c_click_offset = true
861
+ end
862
+
863
+ it 'should offset from center of element' do
864
+ @clicker.right_click(x: 10, y: 5)
865
+ expect(@session).to have_text(/clicked at 160,155/)
866
+ end
867
+
868
+ it 'should offset outside from center of element' do
869
+ @clicker.right_click(x: -65, y: -60)
870
+ expect(@session).to have_text(/clicked at 85,90/)
871
+ end
872
+
873
+ it 'should default to click the middle' do
874
+ @clicker.right_click
875
+ expect(@session).to have_text(/clicked at 150,150/)
876
+ end
823
877
  end
824
878
  end
825
879
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Capybara
4
- VERSION = '3.25.0'
4
+ VERSION = '3.26.0'
5
5
  end
@@ -74,6 +74,13 @@ RSpec.describe Capybara::Server do
74
74
  end
75
75
  end
76
76
 
77
+ it 'should return its #base_url' do
78
+ app = proc { |_env| [200, {}, ['Hello Server!']] }
79
+ server = Capybara::Server.new(app).boot
80
+ uri = ::Addressable::URI.parse(server.base_url)
81
+ expect(uri.to_hash).to include(scheme: 'http', host: server.host, port: server.port)
82
+ end
83
+
77
84
  it 'should support SSL' do
78
85
  begin
79
86
  key = File.join(Dir.pwd, 'spec', 'fixtures', 'key.pem')
@@ -93,6 +100,8 @@ RSpec.describe Capybara::Server do
93
100
  end
94
101
 
95
102
  expect(res.body).to include('Hello SSL Server!')
103
+ uri = ::Addressable::URI.parse(server.base_url)
104
+ expect(uri.to_hash).to include(scheme: 'https', host: server.host, port: server.port)
96
105
  ensure
97
106
  Capybara.server = :default
98
107
  end
@@ -323,6 +323,8 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
323
323
  end
324
324
 
325
325
  it 'can attach a relative file' do
326
+ pending 'Geckdoriver on windows requires alternate file separator which path expansion replaces' if Gem.win_platform? && firefox?(session)
327
+
326
328
  session.visit('/form')
327
329
  session.attach_file('Single Document', 'spec/fixtures/capybara.csv')
328
330
  session.click_button('Upload Single')
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: 3.25.0
4
+ version: 3.26.0
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: 2019-06-28 00:00:00.000000000 Z
13
+ date: 2019-07-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: addressable