capybara 3.25.0 → 3.26.0

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
  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