capybara 3.0.0.rc1 → 3.0.0.rc2
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 +4 -4
- data/History.md +18 -2
- data/README.md +1 -0
- data/lib/capybara/driver/base.rb +10 -0
- data/lib/capybara/helpers.rb +5 -3
- data/lib/capybara/node/matchers.rb +4 -2
- data/lib/capybara/queries/ancestor_query.rb +7 -1
- data/lib/capybara/queries/base_query.rb +4 -1
- data/lib/capybara/queries/text_query.rb +3 -6
- data/lib/capybara/queries/title_query.rb +2 -2
- data/lib/capybara/rack_test/node.rb +23 -7
- data/lib/capybara/rspec/matchers.rb +0 -1
- data/lib/capybara/selector/filter_set.rb +1 -1
- data/lib/capybara/selector/selector.rb +1 -1
- data/lib/capybara/selenium/driver.rb +11 -0
- data/lib/capybara/selenium/node.rb +50 -4
- data/lib/capybara/session.rb +1 -1
- data/lib/capybara/spec/public/test.js +0 -1
- data/lib/capybara/spec/session/ancestor_spec.rb +4 -4
- data/lib/capybara/spec/session/assert_text.rb +5 -6
- data/lib/capybara/spec/session/assert_title.rb +12 -3
- data/lib/capybara/spec/session/attach_file_spec.rb +29 -18
- data/lib/capybara/spec/session/current_url_spec.rb +10 -0
- data/lib/capybara/spec/session/fill_in_spec.rb +24 -0
- data/lib/capybara/spec/session/find_field_spec.rb +1 -1
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
- data/lib/capybara/spec/session/has_text_spec.rb +3 -8
- data/lib/capybara/spec/session/node_spec.rb +1 -1
- data/lib/capybara/spec/session/refresh_spec.rb +3 -1
- data/lib/capybara/spec/session/reset_session_spec.rb +18 -0
- data/lib/capybara/spec/session/save_screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/text_spec.rb +16 -3
- data/lib/capybara/spec/session/title_spec.rb +10 -0
- data/lib/capybara/spec/session/window/within_window_spec.rb +2 -3
- data/lib/capybara/spec/spec_helper.rb +4 -0
- data/lib/capybara/spec/test_app.rb +9 -0
- data/lib/capybara/spec/views/form.erb +6 -0
- data/lib/capybara/spec/views/with_html.erb +20 -0
- data/lib/capybara/version.rb +1 -1
- data/spec/selenium_spec_chrome.rb +2 -0
- data/spec/selenium_spec_edge.rb +27 -0
- data/spec/selenium_spec_ie.rb +27 -0
- data/spec/selenium_spec_marionette.rb +2 -0
- data/spec/server_spec.rb +1 -1
- data/spec/shared_selenium_session.rb +9 -0
- data/spec/spec_helper.rb +2 -2
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d9b394cb5aaa7d6849ba4fd9e486b7fae2298a64f6a5e2f88fd80abea82a2ba6
|
4
|
+
data.tar.gz: eeca1e3b972c9efb89224fb701a1612a5d503621327af3fb77bf1a028a21761d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 615f9400b993c2408414f886a5cfdd41272e29cb9c3fa1763758888416d3e9c5f42d4d179686f8ac56b185610503aef904be6a508e5e8b7d703760ff85a498a0
|
7
|
+
data.tar.gz: 0045d33244fdc1cd6615cac65760399088330bc1751781c1ea2c0107570f096f52766841ad2f1a40efb595127e9e78b5c4b1d9341dcd146721eedba0e588062a
|
data/History.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
# Version 3.0.0.rc2
|
2
|
+
Release date: 2018-03-23
|
3
|
+
|
4
|
+
### Changed
|
5
|
+
|
6
|
+
* Drivers are now expected to return visible text more in line with the WebDriver spec for visible text
|
7
|
+
* Drivers are expected to close extra windows when resetting the session
|
8
|
+
* Selenium driver supports Date/Time when filling in date/time/datetime-local inputs
|
9
|
+
* `current_url` returns the url for the top level browsing context
|
10
|
+
* `title` returns the title for the top level browsing context
|
11
|
+
|
12
|
+
### Added
|
13
|
+
|
14
|
+
* `Driver#frame_url` returns the url for the current frame
|
15
|
+
* `Driver#frame_title` returns the title for the current frame
|
16
|
+
|
1
17
|
# Version 3.0.0.rc1
|
2
18
|
Release date: 2018-03-02
|
3
19
|
|
@@ -6,7 +22,7 @@ Release date: 2018-03-02
|
|
6
22
|
|
7
23
|
### Changed
|
8
24
|
|
9
|
-
* `first` now raises ElementNotFound, by default, instead of returning nil
|
25
|
+
* `first` now raises ElementNotFound, by default, instead of returning nil when no matches are found - Issue #1507
|
10
26
|
* 'all' now waits for at least one matching element by default. Pass `wait: false` if you want the previous
|
11
27
|
behavior where an empty result would be returned immediately if no matching elements exist yet.
|
12
28
|
* ArgumentError raised if extra parameters passed to selector queries
|
@@ -19,7 +35,7 @@ Release date: 2018-03-02
|
|
19
35
|
* RSpec 2.x support
|
20
36
|
* selenium-webdriver 2.x support
|
21
37
|
* Nokogiri < 1.8 support
|
22
|
-
* `field_labeled`
|
38
|
+
* `field_labeled` alias for `find_field`
|
23
39
|
|
24
40
|
# Version 2.18.0
|
25
41
|
Release date: 2018-02-12
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Capybara
|
2
2
|
|
3
3
|
[](https://travis-ci.org/teamcapybara/capybara)
|
4
|
+
[](https://ci.appveyor.com/api/projects/github/teamcapybara/capybara)
|
4
5
|
[](https://gemnasium.com/teamcapybara/capybara)
|
5
6
|
[](https://codeclimate.com/github/teamcapybara/capybara)
|
6
7
|
[](https://gitter.im/jnicklas/capybara?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
data/lib/capybara/driver/base.rb
CHANGED
@@ -67,6 +67,16 @@ class Capybara::Driver::Base
|
|
67
67
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#switch_to_frame'
|
68
68
|
end
|
69
69
|
|
70
|
+
def frame_title
|
71
|
+
find_xpath('/html/head/title').map(&:all_text).first.to_s
|
72
|
+
end
|
73
|
+
|
74
|
+
def frame_url
|
75
|
+
evaluate_script('document.location.href')
|
76
|
+
rescue Capybara::NotSupportedByDriverError
|
77
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#frame_title'
|
78
|
+
end
|
79
|
+
|
70
80
|
def current_window_handle
|
71
81
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#current_window_handle'
|
72
82
|
end
|
data/lib/capybara/helpers.rb
CHANGED
@@ -6,7 +6,7 @@ module Capybara
|
|
6
6
|
extend self
|
7
7
|
|
8
8
|
##
|
9
|
-
#
|
9
|
+
# @deprecated
|
10
10
|
# Normalizes whitespace space by stripping leading and trailing
|
11
11
|
# whitespace and replacing sequences of whitespace characters
|
12
12
|
# with a single space.
|
@@ -15,6 +15,7 @@ module Capybara
|
|
15
15
|
# @return [String] Normalized text
|
16
16
|
#
|
17
17
|
def normalize_whitespace(text)
|
18
|
+
warn "DEPRECATED: Capybara::Helpers::normalize_whitespace is deprecated, please update your driver"
|
18
19
|
text.to_s.gsub(/[[:space:]]+/, ' ').strip
|
19
20
|
end
|
20
21
|
|
@@ -28,10 +29,11 @@ module Capybara
|
|
28
29
|
# @param [Fixnum, Boolean, nil] options Options passed to Regexp.new when creating the Regexp
|
29
30
|
# @return [Regexp] Regexp to match the passed in text and options
|
30
31
|
#
|
31
|
-
def to_regexp(text, exact: false, options: nil)
|
32
|
+
def to_regexp(text, exact: false, all_whitespace: false, options: nil)
|
32
33
|
return text if text.is_a?(Regexp)
|
33
34
|
|
34
|
-
escaped = Regexp.escape(
|
35
|
+
escaped = Regexp.escape(text)
|
36
|
+
escaped = escaped.gsub("\\ ", "[[:blank:]]") if all_whitespace
|
35
37
|
escaped = "\\A#{escaped}\\z" if exact
|
36
38
|
Regexp.new(escaped, options)
|
37
39
|
end
|
@@ -112,7 +112,8 @@ module Capybara
|
|
112
112
|
#
|
113
113
|
# @overload assert_all_of_selectors([kind = Capybara.default_selector], *locators, options = {})
|
114
114
|
#
|
115
|
-
def assert_all_of_selectors(*args, wait:
|
115
|
+
def assert_all_of_selectors(*args, wait: nil, **options, &optional_filter_block)
|
116
|
+
wait = session_options.default_max_wait_time if wait.nil?
|
116
117
|
selector = args.first.is_a?(Symbol) ? args.shift : session_options.default_selector
|
117
118
|
synchronize(wait) do
|
118
119
|
args.each do |locator|
|
@@ -136,7 +137,8 @@ module Capybara
|
|
136
137
|
#
|
137
138
|
# @overload assert_none_of_selectors([kind = Capybara.default_selector], *locators, options = {})
|
138
139
|
#
|
139
|
-
def assert_none_of_selectors(*args, wait:
|
140
|
+
def assert_none_of_selectors(*args, wait: nil, **options, &optional_filter_block)
|
141
|
+
wait = session_options.default_max_wait_time if wait.nil?
|
140
142
|
selector = args.first.is_a?(Symbol) ? args.shift : session_options.default_selector
|
141
143
|
synchronize(wait) do
|
142
144
|
args.each do |locator|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Capybara
|
4
4
|
module Queries
|
5
|
-
class AncestorQuery <
|
5
|
+
class AncestorQuery < Capybara::Queries::SelectorQuery
|
6
6
|
# @api private
|
7
7
|
def resolve_for(node, exact = nil)
|
8
8
|
@child_node = node
|
@@ -18,6 +18,12 @@ module Capybara
|
|
18
18
|
desc += " that is an ancestor of #{child_query.description}" if child_query
|
19
19
|
desc
|
20
20
|
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def valid_keys
|
25
|
+
super - COUNT_KEYS
|
26
|
+
end
|
21
27
|
end
|
22
28
|
end
|
23
29
|
end
|
@@ -22,7 +22,10 @@ module Capybara
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.wait(options, default = Capybara.default_max_wait_time)
|
25
|
-
|
25
|
+
# if no value or nil for the :wait option is passed it should default to the default
|
26
|
+
w = options.fetch(:wait, nil)
|
27
|
+
w = default if w.nil?
|
28
|
+
w || 0
|
26
29
|
end
|
27
30
|
|
28
31
|
##
|
@@ -10,11 +10,8 @@ module Capybara
|
|
10
10
|
else
|
11
11
|
type
|
12
12
|
end
|
13
|
-
|
14
|
-
|
15
|
-
else
|
16
|
-
Capybara::Helpers.normalize_whitespace(expected_text)
|
17
|
-
end
|
13
|
+
|
14
|
+
@expected_text = expected_text.is_a?(Regexp) ? expected_text : expected_text.to_s
|
18
15
|
@options = options
|
19
16
|
super(@options)
|
20
17
|
self.session_options = session_options
|
@@ -94,7 +91,7 @@ module Capybara
|
|
94
91
|
end
|
95
92
|
|
96
93
|
def text(node, query_type)
|
97
|
-
|
94
|
+
node.text(query_type)
|
98
95
|
end
|
99
96
|
end
|
100
97
|
end
|
@@ -5,10 +5,10 @@ module Capybara
|
|
5
5
|
module Queries
|
6
6
|
class TitleQuery < BaseQuery
|
7
7
|
def initialize(expected_title, **options)
|
8
|
-
@expected_title = expected_title.is_a?(Regexp) ? expected_title :
|
8
|
+
@expected_title = expected_title.is_a?(Regexp) ? expected_title : expected_title.to_s
|
9
9
|
@options = options
|
10
10
|
super(@options)
|
11
|
-
@search_regexp = Capybara::Helpers.to_regexp(@expected_title, exact: options.fetch(:exact, false))
|
11
|
+
@search_regexp = Capybara::Helpers.to_regexp(@expected_title, all_whitespace: true, exact: options.fetch(:exact, false))
|
12
12
|
assert_valid_keys
|
13
13
|
end
|
14
14
|
|
@@ -1,12 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Capybara::RackTest::Node < Capybara::Driver::Node
|
4
|
+
BLOCK_ELEMENTS = %w[p h1 h2 h3 h4 h5 h6 ol ul pre address blockquote dl div fieldset form hr noscript table].freeze
|
5
|
+
|
4
6
|
def all_text
|
5
|
-
|
7
|
+
native.text
|
8
|
+
.gsub(/[\u200b\u200e\u200f]/, '')
|
9
|
+
.gsub(/[\ \n\f\t\v\u2028\u2029]+/, ' ')
|
10
|
+
.gsub(/\A[[:space:]&&[^\u00a0]]+/, "")
|
11
|
+
.gsub(/[[:space:]&&[^\u00a0]]+\z/, "")
|
12
|
+
.tr("\u00a0", ' ')
|
6
13
|
end
|
7
14
|
|
8
15
|
def visible_text
|
9
|
-
|
16
|
+
displayed_text.gsub(/\ +/, ' ')
|
17
|
+
.gsub(/[\ \n]*\n[\ \n]*/, "\n")
|
18
|
+
.gsub(/\A[[:space:]&&[^\u00a0]]+/, "")
|
19
|
+
.gsub(/[[:space:]&&[^\u00a0]]+\z/, "")
|
20
|
+
.tr("\u00a0", ' ')
|
10
21
|
end
|
11
22
|
|
12
23
|
def [](name)
|
@@ -103,15 +114,20 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
103
114
|
|
104
115
|
protected
|
105
116
|
|
106
|
-
|
107
|
-
|
117
|
+
# @api private
|
118
|
+
def displayed_text(check_ancestor: true)
|
119
|
+
if !string_node.visible?(check_ancestor)
|
108
120
|
''
|
109
121
|
elsif native.text?
|
110
122
|
native.text
|
123
|
+
.gsub(/[\u200b\u200e\u200f]/, '')
|
124
|
+
.gsub(/[\ \n\f\t\v\u2028\u2029]+/, ' ')
|
111
125
|
elsif native.element?
|
112
|
-
native.children.map do |child|
|
113
|
-
Capybara::RackTest::Node.new(driver, child).
|
114
|
-
end.join
|
126
|
+
text = native.children.map do |child|
|
127
|
+
Capybara::RackTest::Node.new(driver, child).displayed_text(check_ancestor: false)
|
128
|
+
end.join || ''
|
129
|
+
text = "\n#{text}\n" if BLOCK_ELEMENTS.include?(tag_name)
|
130
|
+
text
|
115
131
|
else
|
116
132
|
''
|
117
133
|
end
|
@@ -26,6 +26,8 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
26
26
|
@w3c = ((defined?(Selenium::WebDriver::Remote::W3CCapabilities) && @browser.capabilities.is_a?(Selenium::WebDriver::Remote::W3CCapabilities)) ||
|
27
27
|
(defined?(Selenium::WebDriver::Remote::W3C::Capabilities) && @browser.capabilities.is_a?(Selenium::WebDriver::Remote::W3C::Capabilities)))
|
28
28
|
main = Process.pid
|
29
|
+
@primary_window_handle = current_window_handle
|
30
|
+
|
29
31
|
at_exit do
|
30
32
|
# Store the exit status of the test run since it goes away after calling the at_exit proc...
|
31
33
|
@exit_status = $ERROR_INFO.status if $ERROR_INFO.is_a?(SystemExit)
|
@@ -108,6 +110,9 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
108
110
|
# Use instance variable directly so we avoid starting the browser just to reset the session
|
109
111
|
return unless @browser
|
110
112
|
|
113
|
+
switch_to_window(@primary_window_handle)
|
114
|
+
window_handles.reject { |handle| handle == @primary_window_handle }.each { |win| close_window(win) }
|
115
|
+
|
111
116
|
navigated = false
|
112
117
|
start_time = Capybara::Helpers.monotonic_time
|
113
118
|
begin
|
@@ -205,6 +210,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
205
210
|
end
|
206
211
|
|
207
212
|
def close_window(handle)
|
213
|
+
raise ArgumentError, "Not allowed to close the primary window" if handle == @primary_window_handle
|
208
214
|
within_given_window(handle) do
|
209
215
|
browser.close
|
210
216
|
end
|
@@ -286,6 +292,11 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
286
292
|
browser_name == "chrome"
|
287
293
|
end
|
288
294
|
|
295
|
+
# @api private
|
296
|
+
def edge?
|
297
|
+
browser_name == "edge"
|
298
|
+
end
|
299
|
+
|
289
300
|
private
|
290
301
|
|
291
302
|
def browser_name
|
@@ -1,14 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Capybara::Selenium::Node < Capybara::Driver::Node
|
4
|
+
SET_FORMATS = Hash.new(date: '%Y-%m-%d', time: '%H:%M', datetime: "%m%d%Y\t%I%M%P").merge(
|
5
|
+
firefox: {
|
6
|
+
date: '%Y-%m-%d',
|
7
|
+
time: '%H:%M',
|
8
|
+
datetime: "%m%d%Y\t%I%M%P"
|
9
|
+
},
|
10
|
+
chrome: {
|
11
|
+
date: '%m%d%Y',
|
12
|
+
time: '%I%M%P',
|
13
|
+
datetime: "%m%d%Y\t%I%M%P"
|
14
|
+
}
|
15
|
+
)
|
16
|
+
|
4
17
|
def visible_text
|
5
|
-
|
6
|
-
Capybara::Helpers.normalize_whitespace(native.text)
|
18
|
+
native.text
|
7
19
|
end
|
8
20
|
|
9
21
|
def all_text
|
10
22
|
text = driver.execute_script("return arguments[0].textContent", self)
|
11
|
-
|
23
|
+
text.gsub(/[\u200b\u200e\u200f]/, '')
|
24
|
+
.gsub(/[\ \n\f\t\v\u2028\u2029]+/, ' ')
|
25
|
+
.gsub(/\A[[:space:]&&[^\u00a0]]+/, "")
|
26
|
+
.gsub(/[[:space:]&&[^\u00a0]]+\z/, "")
|
27
|
+
.tr("\u00a0", ' ')
|
12
28
|
end
|
13
29
|
|
14
30
|
def [](name)
|
@@ -48,6 +64,12 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
|
48
64
|
click if value ^ checked?
|
49
65
|
when 'file'
|
50
66
|
set_file(value)
|
67
|
+
when 'date'
|
68
|
+
set_date(value)
|
69
|
+
when 'time'
|
70
|
+
set_time(value)
|
71
|
+
when 'datetime-local'
|
72
|
+
set_datetime_local(value)
|
51
73
|
else
|
52
74
|
set_text(value, options)
|
53
75
|
end
|
@@ -197,7 +219,7 @@ private
|
|
197
219
|
find_xpath(XPath.ancestor(:select)[1]).first
|
198
220
|
end
|
199
221
|
|
200
|
-
def set_text(value, clear: nil, **)
|
222
|
+
def set_text(value, clear: nil, **_unused)
|
201
223
|
if value.to_s.empty? && clear.nil?
|
202
224
|
native.clear
|
203
225
|
elsif clear == :backspace
|
@@ -231,6 +253,30 @@ private
|
|
231
253
|
yield
|
232
254
|
end
|
233
255
|
|
256
|
+
def set_date(value) # rubocop:disable Naming/AccessorMethodName
|
257
|
+
if value.respond_to?(:to_date)
|
258
|
+
set_text(value.to_date.strftime(SET_FORMATS[driver.options[:browser].to_sym][:date]))
|
259
|
+
else
|
260
|
+
set_text(value)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
def set_time(value) # rubocop:disable Naming/AccessorMethodName
|
265
|
+
if value.respond_to?(:to_time)
|
266
|
+
set_text(value.to_time.strftime(SET_FORMATS[driver.options[:browser].to_sym][:time]))
|
267
|
+
else
|
268
|
+
set_text(value)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
def set_datetime_local(value) # rubocop:disable Naming/AccessorMethodName
|
273
|
+
if value.respond_to?(:to_time)
|
274
|
+
set_text(value.to_time.strftime(SET_FORMATS[driver.options[:browser].to_sym][:datetime]))
|
275
|
+
else
|
276
|
+
set_text(value)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
234
280
|
def set_file(value) # rubocop:disable Naming/AccessorMethodName
|
235
281
|
path_names = value.to_s.empty? ? [] : value
|
236
282
|
if driver.chrome?
|
data/lib/capybara/session.rb
CHANGED
@@ -413,7 +413,7 @@ module Capybara
|
|
413
413
|
# @overload within_frame(element)
|
414
414
|
# @param [Capybara::Node::Element] frame element
|
415
415
|
# @overload within_frame([kind = :frame], locator, options = {})
|
416
|
-
# @param [
|
416
|
+
# @param [Symbol] kind Optional selector type (:css, :xpath, :field, etc.) - Defaults to :frame
|
417
417
|
# @param [String] locator The locator for the given selector kind. For :frame this is the name/id of a frame/iframe element
|
418
418
|
# @overload within_frame(index)
|
419
419
|
# @param [Integer] index index of a frame (0 based)
|
@@ -17,7 +17,7 @@ Capybara::SpecHelper.spec '#ancestor' do
|
|
17
17
|
|
18
18
|
it "should find the ancestor element using the given locator and options" do
|
19
19
|
el = @session.find(:css, '#child')
|
20
|
-
expect(el.ancestor('//div', text:
|
20
|
+
expect(el.ancestor('//div', text: "Ancestor\nAncestor\nAncestor")[:id]).to eq('ancestor3')
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should raise an error if there are multiple matches" do
|
@@ -53,8 +53,8 @@ Capybara::SpecHelper.spec '#ancestor' do
|
|
53
53
|
xpath { |num| ".//*[@id='ancestor#{num}']" }
|
54
54
|
end
|
55
55
|
el = @session.find(:css, '#child')
|
56
|
-
expect(el.ancestor(:level, 1)
|
57
|
-
expect(el.ancestor(:level, 3)
|
56
|
+
expect(el.ancestor(:level, 1)[:id]).to eq "ancestor1"
|
57
|
+
expect(el.ancestor(:level, 3)[:id]).to eq "ancestor3"
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -62,7 +62,7 @@ Capybara::SpecHelper.spec '#ancestor' do
|
|
62
62
|
el = @session.find(:css, '#child')
|
63
63
|
expect do
|
64
64
|
el.ancestor(:xpath, '//div[@id="nosuchthing"]')
|
65
|
-
end.to raise_error(Capybara::ElementNotFound, "Unable to find xpath \"//div[@id=\\\"nosuchthing\\\"]\" that is an ancestor of visible css \"#child\"")
|
65
|
+
end.to raise_error(Capybara::ElementNotFound, "Unable to find visible xpath \"//div[@id=\\\"nosuchthing\\\"]\" that is an ancestor of visible css \"#child\"")
|
66
66
|
end
|
67
67
|
|
68
68
|
context "within a scope" do
|
@@ -7,8 +7,7 @@ Capybara::SpecHelper.spec '#assert_text' do
|
|
7
7
|
expect(@session.assert_text('Lorem')).to eq(true)
|
8
8
|
expect(@session.assert_text('Redirect')).to eq(true)
|
9
9
|
expect(@session.assert_text(:Redirect)).to eq(true)
|
10
|
-
expect(@session.assert_text('text with
|
11
|
-
expect(@session.assert_text("text with \n\n whitespace")).to eq(true)
|
10
|
+
expect(@session.assert_text('text with whitespace')).to eq(true)
|
12
11
|
end
|
13
12
|
|
14
13
|
it "should take scopes into account" do
|
@@ -49,7 +48,7 @@ Capybara::SpecHelper.spec '#assert_text' do
|
|
49
48
|
it "should raise error with a helpful message if the requested text is present but with incorrect case" do
|
50
49
|
@session.visit('/with_html')
|
51
50
|
expect do
|
52
|
-
@session.assert_text('Text With
|
51
|
+
@session.assert_text('Text With Whitespace')
|
53
52
|
end.to raise_error(Capybara::ExpectationNotMet, /it was found 1 time using a case insensitive search/)
|
54
53
|
end
|
55
54
|
|
@@ -77,7 +76,7 @@ Capybara::SpecHelper.spec '#assert_text' do
|
|
77
76
|
@session.visit('/with_html')
|
78
77
|
expect do
|
79
78
|
@session.assert_text(/xxxxyzzz/)
|
80
|
-
end.to raise_error(Capybara::ExpectationNotMet, /\Aexpected to find text matching \/xxxxyzzz\/ in "This is a test
|
79
|
+
end.to raise_error(Capybara::ExpectationNotMet, /\Aexpected to find text matching \/xxxxyzzz\/ in "This is a test\\nHeader Class(.+)"\Z/)
|
81
80
|
end
|
82
81
|
|
83
82
|
it "should escape any characters that would have special meaning in a regexp" do
|
@@ -112,7 +111,7 @@ Capybara::SpecHelper.spec '#assert_text' do
|
|
112
111
|
Capybara.using_wait_time(0) do
|
113
112
|
@session.visit('/with_js')
|
114
113
|
@session.find(:css, '#reload-list').click
|
115
|
-
@session.find(:css, '#the-list').assert_text(
|
114
|
+
@session.find(:css, '#the-list').assert_text("Foo\nBar", wait: 0.9)
|
116
115
|
end
|
117
116
|
end
|
118
117
|
|
@@ -174,7 +173,7 @@ Capybara::SpecHelper.spec '#assert_no_text' do
|
|
174
173
|
@session.visit('/with_html')
|
175
174
|
expect do
|
176
175
|
@session.assert_no_text('Lorem')
|
177
|
-
end.to raise_error(Capybara::ExpectationNotMet, /\Aexpected not to find text "Lorem" in "This is a test
|
176
|
+
end.to raise_error(Capybara::ExpectationNotMet, /\Aexpected not to find text "Lorem" in "This is a test.*"\z/)
|
178
177
|
end
|
179
178
|
|
180
179
|
it "should be true if scoped to an element which does not have the text" do
|
@@ -40,11 +40,20 @@ Capybara::SpecHelper.spec '#assert_title' do
|
|
40
40
|
end.to raise_error(Capybara::ExpectationNotMet, 'expected "with_js" to include "monkey"')
|
41
41
|
end
|
42
42
|
|
43
|
-
it "should normalize given title" do
|
44
|
-
@session.
|
43
|
+
it "should not normalize given title" do
|
44
|
+
@session.visit('/with_js')
|
45
|
+
expect { @session.assert_title(' with_js ') }.to raise_error(Capybara::ExpectationNotMet)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should match correctly normalized title" do
|
49
|
+
uri = Addressable::URI.parse('/with_title')
|
50
|
+
uri.query_values = { title: ' with space title ' }
|
51
|
+
@session.visit(uri.to_s)
|
52
|
+
@session.assert_title(' with space title')
|
53
|
+
expect { @session.assert_title('with space title') }.to raise_error(Capybara::ExpectationNotMet)
|
45
54
|
end
|
46
55
|
|
47
|
-
it "should normalize given title in error message" do
|
56
|
+
it "should not normalize given title in error message" do
|
48
57
|
expect do
|
49
58
|
@session.assert_title(2)
|
50
59
|
end.to raise_error(Capybara::ExpectationNotMet, 'expected "with_js" to include "2"')
|
@@ -11,19 +11,19 @@ Capybara::SpecHelper.spec "#attach_file" do
|
|
11
11
|
|
12
12
|
context "with normal form" do
|
13
13
|
it "should set a file path by id" do
|
14
|
-
@session.attach_file "form_image", __FILE__
|
14
|
+
@session.attach_file "form_image", with_os_path_separators(__FILE__)
|
15
15
|
@session.click_button('awesome')
|
16
16
|
expect(extract_results(@session)['image']).to eq(File.basename(__FILE__))
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should set a file path by label" do
|
20
|
-
@session.attach_file "Image", __FILE__
|
20
|
+
@session.attach_file "Image", with_os_path_separators(__FILE__)
|
21
21
|
@session.click_button('awesome')
|
22
22
|
expect(extract_results(@session)['image']).to eq(File.basename(__FILE__))
|
23
23
|
end
|
24
24
|
|
25
25
|
it "casts to string" do
|
26
|
-
@session.attach_file :form_image, __FILE__
|
26
|
+
@session.attach_file :form_image, with_os_path_separators(__FILE__)
|
27
27
|
@session.click_button('awesome')
|
28
28
|
expect(extract_results(@session)['image']).to eq(File.basename(__FILE__))
|
29
29
|
end
|
@@ -31,13 +31,13 @@ Capybara::SpecHelper.spec "#attach_file" do
|
|
31
31
|
|
32
32
|
context "with multipart form" do
|
33
33
|
it "should set a file path by id" do
|
34
|
-
@session.attach_file "form_document", @test_file_path
|
34
|
+
@session.attach_file "form_document", with_os_path_separators(@test_file_path)
|
35
35
|
@session.click_button('Upload Single')
|
36
36
|
expect(@session).to have_content(File.read(@test_file_path))
|
37
37
|
end
|
38
38
|
|
39
39
|
it "should set a file path by label" do
|
40
|
-
@session.attach_file "Single Document", @test_file_path
|
40
|
+
@session.attach_file "Single Document", with_os_path_separators(@test_file_path)
|
41
41
|
@session.click_button('Upload Single')
|
42
42
|
expect(@session).to have_content(File.read(@test_file_path))
|
43
43
|
end
|
@@ -48,25 +48,25 @@ Capybara::SpecHelper.spec "#attach_file" do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
it "should send content type text/plain when uploading a text file" do
|
51
|
-
@session.attach_file "Single Document", @test_file_path
|
51
|
+
@session.attach_file "Single Document", with_os_path_separators(@test_file_path)
|
52
52
|
@session.click_button 'Upload Single'
|
53
53
|
expect(@session).to have_content('text/plain')
|
54
54
|
end
|
55
55
|
|
56
56
|
it "should send content type image/jpeg when uploading an image" do
|
57
|
-
@session.attach_file "Single Document", @test_jpg_file_path
|
57
|
+
@session.attach_file "Single Document", with_os_path_separators(@test_jpg_file_path)
|
58
58
|
@session.click_button 'Upload Single'
|
59
59
|
expect(@session).to have_content('image/jpeg')
|
60
60
|
end
|
61
61
|
|
62
62
|
it "should not break when uploading a file without extension" do
|
63
|
-
@session.attach_file "Single Document", @no_extension_file_path
|
63
|
+
@session.attach_file "Single Document", with_os_path_separators(@no_extension_file_path)
|
64
64
|
@session.click_button 'Upload Single'
|
65
65
|
expect(@session).to have_content(File.read(@no_extension_file_path))
|
66
66
|
end
|
67
67
|
|
68
68
|
it "should not break when using HTML5 multiple file input" do
|
69
|
-
@session.attach_file "Multiple Documents", @test_file_path
|
69
|
+
@session.attach_file "Multiple Documents", with_os_path_separators(@test_file_path)
|
70
70
|
@session.click_button('Upload Multiple')
|
71
71
|
expect(@session).to have_content(File.read(@test_file_path))
|
72
72
|
expect(@session.body).to include("1 | ") # number of files
|
@@ -74,7 +74,8 @@ Capybara::SpecHelper.spec "#attach_file" do
|
|
74
74
|
|
75
75
|
it "should not break when using HTML5 multiple file input uploading multiple files" do
|
76
76
|
pending "Selenium is buggy on this, see http://code.google.com/p/selenium/issues/detail?id=2239" if @session.respond_to?(:mode) && @session.mode.to_s =~ /^selenium_(firefox|marionette)/
|
77
|
-
@session.attach_file
|
77
|
+
@session.attach_file("Multiple Documents",
|
78
|
+
[@test_file_path, @another_test_file_path].map { |f| with_os_path_separators(f) })
|
78
79
|
@session.click_button('Upload Multiple')
|
79
80
|
expect(@session.body).to include("2 | ") # number of files
|
80
81
|
expect(@session.body).to include(File.read(@test_file_path))
|
@@ -91,7 +92,7 @@ Capybara::SpecHelper.spec "#attach_file" do
|
|
91
92
|
it "should raise an error" do
|
92
93
|
msg = "Unable to find visible file field \"does not exist\" that is not disabled"
|
93
94
|
expect do
|
94
|
-
@session.attach_file('does not exist', @test_file_path)
|
95
|
+
@session.attach_file('does not exist', with_os_path_separators(@test_file_path))
|
95
96
|
end.to raise_error(Capybara::ElementNotFound, msg)
|
96
97
|
end
|
97
98
|
end
|
@@ -104,14 +105,14 @@ Capybara::SpecHelper.spec "#attach_file" do
|
|
104
105
|
|
105
106
|
context "with :exact option" do
|
106
107
|
it "should set a file path by partial label when false" do
|
107
|
-
@session.attach_file "Imag", __FILE__, exact:
|
108
|
+
@session.attach_file "Imag", with_os_path_separators(__FILE__), exact: false
|
108
109
|
@session.click_button('awesome')
|
109
110
|
expect(extract_results(@session)['image']).to eq(File.basename(__FILE__))
|
110
111
|
end
|
111
112
|
|
112
113
|
it "should not allow partial matches when true" do
|
113
114
|
expect do
|
114
|
-
@session.attach_file "Imag", __FILE__, exact: true
|
115
|
+
@session.attach_file "Imag", with_os_path_separators(__FILE__), exact: true
|
115
116
|
end.to raise_error(Capybara::ElementNotFound)
|
116
117
|
end
|
117
118
|
end
|
@@ -119,30 +120,40 @@ Capybara::SpecHelper.spec "#attach_file" do
|
|
119
120
|
context "with :make_visible option", requires: %i[js es_args] do
|
120
121
|
it "applies a default style change when true" do
|
121
122
|
@session.visit('/with_js')
|
122
|
-
expect { @session.attach_file("hidden_file", __FILE__) }.to raise_error Capybara::ElementNotFound
|
123
123
|
expect do
|
124
|
-
@session.attach_file("hidden_file", __FILE__
|
124
|
+
@session.attach_file("hidden_file", with_os_path_separators(__FILE__))
|
125
|
+
end.to raise_error Capybara::ElementNotFound
|
126
|
+
expect do
|
127
|
+
@session.attach_file("hidden_file", with_os_path_separators(__FILE__), make_visible: true)
|
125
128
|
end.not_to raise_error
|
126
129
|
end
|
127
130
|
|
128
131
|
it "accepts a hash of styles to be applied" do
|
129
132
|
@session.visit('/with_js')
|
130
133
|
expect do
|
131
|
-
@session.attach_file("hidden_file",
|
134
|
+
@session.attach_file("hidden_file",
|
135
|
+
with_os_path_separators(__FILE__),
|
136
|
+
make_visible: { opacity: 1, display: 'block' })
|
132
137
|
end.not_to raise_error
|
133
138
|
end
|
134
139
|
|
135
140
|
it "raises an error when the file input is not made visible" do
|
136
141
|
@session.visit('/with_js')
|
137
142
|
expect do
|
138
|
-
@session.attach_file("hidden_file", __FILE__, make_visible: { color: 'red' })
|
143
|
+
@session.attach_file("hidden_file", with_os_path_separators(__FILE__), make_visible: { color: 'red' })
|
139
144
|
end.to raise_error(Capybara::ExpectationNotMet)
|
140
145
|
end
|
141
146
|
|
142
147
|
it "resets the style when done" do
|
143
148
|
@session.visit('/with_js')
|
144
|
-
@session.attach_file("hidden_file", __FILE__, make_visible: true)
|
149
|
+
@session.attach_file("hidden_file", with_os_path_separators(__FILE__), make_visible: true)
|
145
150
|
expect(@session.evaluate_script("arguments[0].style.display", @session.find(:css, '#hidden_file', visible: :all))).to eq 'none'
|
146
151
|
end
|
147
152
|
end
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
def with_os_path_separators(path)
|
157
|
+
Gem.win_platform? ? path.to_s.tr('/', '\\') : path.to_s
|
158
|
+
end
|
148
159
|
end
|
@@ -105,4 +105,14 @@ Capybara::SpecHelper.spec '#current_url, #current_path, #current_host' do
|
|
105
105
|
expect { @session.current_url }.not_to raise_exception
|
106
106
|
expect { @session.current_path }.not_to raise_exception
|
107
107
|
end
|
108
|
+
|
109
|
+
context "within iframe", requires: [:frames] do
|
110
|
+
it "should get the url of the top level browsing context" do
|
111
|
+
@session.visit('/within_frames')
|
112
|
+
expect(@session.current_url).to match(/within_frames\z/)
|
113
|
+
@session.within_frame('frameOne') do
|
114
|
+
expect(@session.current_url).to match(/within_frames\z/)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
108
118
|
end
|
@@ -53,6 +53,30 @@ Capybara::SpecHelper.spec "#fill_in" do
|
|
53
53
|
expect(extract_results(@session)['password']).to eq('supasikrit')
|
54
54
|
end
|
55
55
|
|
56
|
+
context "Date/Time" do
|
57
|
+
it "should fill in a date input" do
|
58
|
+
date = Date.today
|
59
|
+
@session.fill_in('form_date', with: date)
|
60
|
+
@session.click_button('awesome')
|
61
|
+
expect(Date.parse(extract_results(@session)['date'])).to eq date
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should fill in a time input" do
|
65
|
+
time = Time.new(2018, 3, 9, 15, 26)
|
66
|
+
@session.fill_in('form_time', with: time)
|
67
|
+
@session.click_button('awesome')
|
68
|
+
results = extract_results(@session)['time']
|
69
|
+
expect(Time.parse(results).strftime('%r')).to eq time.strftime('%r')
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should fill in a datetime input" do
|
73
|
+
dt = Time.new(2018, 3, 13, 9, 53)
|
74
|
+
@session.fill_in('form_datetime', with: dt)
|
75
|
+
@session.click_button('awesome')
|
76
|
+
expect(Time.parse(extract_results(@session)['datetime'])).to eq dt
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
56
80
|
it "should handle HTML in a textarea" do
|
57
81
|
@session.fill_in('form_description', with: 'is <strong>very</strong> secret!')
|
58
82
|
@session.click_button('awesome')
|
@@ -7,7 +7,7 @@ Capybara::SpecHelper.spec '#find_field' do
|
|
7
7
|
|
8
8
|
it "should find any field" do
|
9
9
|
expect(@session.find_field('Dog').value).to eq('dog')
|
10
|
-
expect(@session.find_field('form_description').
|
10
|
+
expect(@session.find_field('form_description').value).to eq('Descriptive text goes here')
|
11
11
|
expect(@session.find_field('Region')[:name]).to eq('form[region]')
|
12
12
|
expect(@session.find_field('With Asterisk*')).to be
|
13
13
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Capybara::SpecHelper.spec '#frame_title', requires: [:frames] do
|
4
|
+
before(:each) do
|
5
|
+
@session.visit('/within_frames')
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should return the title in a frame" do
|
9
|
+
@session.within_frame("frameOne") do
|
10
|
+
expect(@session.driver.frame_title).to eq 'This is the title of frame one'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return the title in FrameTwo" do
|
15
|
+
@session.within_frame("frameTwo") do
|
16
|
+
expect(@session.driver.frame_title).to eq 'This is the title of frame two'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return the title in the main frame" do
|
21
|
+
expect(@session.driver.frame_title).to eq 'With Frames'
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Capybara::SpecHelper.spec '#frame_url', requires: [:frames] do
|
4
|
+
before(:each) do
|
5
|
+
@session.visit('/within_frames')
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should return the url in a frame" do
|
9
|
+
@session.within_frame("frameOne") do
|
10
|
+
expect(@session.driver.frame_url).to end_with '/frame_one'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return the url in FrameTwo" do
|
15
|
+
@session.within_frame("frameTwo") do
|
16
|
+
expect(@session.driver.frame_url).to end_with '/frame_two'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return the url in the main frame" do
|
21
|
+
expect(@session.driver.frame_url).to end_with('/within_frames')
|
22
|
+
end
|
23
|
+
end
|
@@ -29,14 +29,9 @@ Capybara::SpecHelper.spec '#has_text?' do
|
|
29
29
|
expect(@session).to have_text('exercitation ullamco laboris')
|
30
30
|
end
|
31
31
|
|
32
|
-
it "should
|
32
|
+
it "should search correctly normalized text" do
|
33
33
|
@session.visit('/with_html')
|
34
|
-
expect(@session).to have_text('text with
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should ignore whitespace and newlines in the search string" do
|
38
|
-
@session.visit('/with_html')
|
39
|
-
expect(@session).to have_text("text with \n\n whitespace")
|
34
|
+
expect(@session).to have_text('text with whitespace')
|
40
35
|
end
|
41
36
|
|
42
37
|
it "should be false if the given text is not on the page" do
|
@@ -326,7 +321,7 @@ Capybara::SpecHelper.spec '#has_no_text?' do
|
|
326
321
|
it "should not find element if it appears after given wait duration" do
|
327
322
|
@session.visit('/with_js')
|
328
323
|
@session.click_link('Click me')
|
329
|
-
expect(@session).to have_no_text('Has been clicked', wait: 0.
|
324
|
+
expect(@session).to have_no_text('Has been clicked', wait: 0.05)
|
330
325
|
end
|
331
326
|
end
|
332
327
|
end
|
@@ -119,7 +119,7 @@ Capybara::SpecHelper.spec "node" do
|
|
119
119
|
@session.visit('/with_js')
|
120
120
|
@session.find(:css, '#existing_content_editable_child').set('WYSIWYG')
|
121
121
|
expect(@session.find(:css, '#existing_content_editable_child').text).to eq('WYSIWYG')
|
122
|
-
expect(@session.find(:css, '#existing_content_editable_child_parent').text).to eq(
|
122
|
+
expect(@session.find(:css, '#existing_content_editable_child_parent').text).to eq("Some content\nWYSIWYG")
|
123
123
|
end
|
124
124
|
end
|
125
125
|
end
|
@@ -18,7 +18,9 @@ Capybara::SpecHelper.spec '#refresh' do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
it "it reposts" do
|
21
|
-
|
21
|
+
if marionette?(@session) || edge?(@session)
|
22
|
+
skip "Firefox and Edge insist on prompting without providing a way to suppress"
|
23
|
+
end
|
22
24
|
@session.visit('/form')
|
23
25
|
@session.select('Sweden', from: 'form_region')
|
24
26
|
@session.click_button('awesome')
|
@@ -63,6 +63,24 @@ Capybara::SpecHelper.spec '#reset_session!' do
|
|
63
63
|
expect(@session.current_path).to eq("/")
|
64
64
|
end
|
65
65
|
|
66
|
+
it "closes extra windows", requires: [:windows] do
|
67
|
+
@session.visit('/with_html')
|
68
|
+
@session.open_new_window
|
69
|
+
@session.open_new_window
|
70
|
+
expect(@session.windows.size).to eq 3
|
71
|
+
@session.reset_session!
|
72
|
+
expect(@session.windows.size).to eq 1
|
73
|
+
end
|
74
|
+
|
75
|
+
it "closes extra windows when not on the first window", requires: [:windows] do
|
76
|
+
@session.visit('/with_html')
|
77
|
+
@session.switch_to_window(@session.open_new_window)
|
78
|
+
@session.open_new_window
|
79
|
+
expect(@session.windows.size).to eq 3
|
80
|
+
@session.reset_session!
|
81
|
+
expect(@session.windows.size).to eq 1
|
82
|
+
end
|
83
|
+
|
66
84
|
context "When reuse_server == false" do
|
67
85
|
before do
|
68
86
|
@reuse_server = Capybara.reuse_server
|
@@ -16,7 +16,7 @@ Capybara::SpecHelper.spec '#save_screenshot', requires: [:screenshot] do
|
|
16
16
|
|
17
17
|
@session.save_screenshot
|
18
18
|
|
19
|
-
regexp = Regexp.new(File.
|
19
|
+
regexp = Regexp.new(File.join(Dir.pwd, 'capybara-\d+\.png'))
|
20
20
|
expect(@session.driver).to have_received(:save_screenshot).with(regexp, {})
|
21
21
|
end
|
22
22
|
|
@@ -36,7 +36,7 @@ Capybara::SpecHelper.spec '#save_screenshot', requires: [:screenshot] do
|
|
36
36
|
|
37
37
|
@session.save_screenshot
|
38
38
|
|
39
|
-
regexp = Regexp.new(File.
|
39
|
+
regexp = Regexp.new(File.join(alternative_path, 'capybara-\d+\.png'))
|
40
40
|
expect(@session.driver).to have_received(:save_screenshot).with(regexp, {})
|
41
41
|
end
|
42
42
|
|
@@ -51,9 +51,22 @@ Capybara::SpecHelper.spec '#text' do
|
|
51
51
|
after { Capybara.default_selector = :xpath }
|
52
52
|
end
|
53
53
|
|
54
|
-
it "should
|
54
|
+
it "should be correctly normalized when visible" do
|
55
55
|
@session.visit('/with_html')
|
56
|
-
@session.find(:css, '#
|
57
|
-
expect(
|
56
|
+
el = @session.find(:css, '#normalized')
|
57
|
+
expect(el.text).to eq "Some text\nMore text\nAnd more text\nEven more text on multiple lines"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should be a textContent with irrelevant whitespace collapsed when non-visible" do
|
61
|
+
@session.visit('/with_html')
|
62
|
+
el = @session.find(:css, '#non_visible_normalized', visible: false)
|
63
|
+
expect(el.text(:all)).to eq "Some textMore text And more text Even more text on multiple lines"
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should strip correctly" do
|
67
|
+
@session.visit('/with_html')
|
68
|
+
el = @session.find(:css, '#ws')
|
69
|
+
expect(el.text).to eq " "
|
70
|
+
expect(el.text(:all)).to eq " "
|
58
71
|
end
|
59
72
|
end
|
@@ -14,4 +14,14 @@ Capybara::SpecHelper.spec '#title' do
|
|
14
14
|
end
|
15
15
|
after { Capybara.default_selector = :xpath }
|
16
16
|
end
|
17
|
+
|
18
|
+
context "within iframe", requires: [:frames] do
|
19
|
+
it "should get the title of the top level browsing context" do
|
20
|
+
@session.visit('/within_frames')
|
21
|
+
expect(@session.title).to eq('With Frames')
|
22
|
+
@session.within_frame('frameOne') do
|
23
|
+
expect(@session.title).to eq('With Frames')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
17
27
|
end
|
@@ -20,16 +20,15 @@ Capybara::SpecHelper.spec '#within_window', requires: [:windows] do
|
|
20
20
|
|
21
21
|
context "with an instance of Capybara::Window" do
|
22
22
|
it "should not invoke driver#switch_to_window when given current window" do
|
23
|
-
|
24
|
-
expect(@session.driver).to receive(:switch_to_window).exactly(3).times.and_call_original
|
23
|
+
allow(@session.driver).to receive(:switch_to_window).and_call_original
|
25
24
|
@session.within_window @window do
|
26
25
|
expect(@session.title).to eq('With Windows')
|
27
26
|
end
|
27
|
+
expect(@session.driver).not_to have_received(:switch_to_window)
|
28
28
|
end
|
29
29
|
|
30
30
|
it "should be able to switch to another window" do
|
31
31
|
window = (@session.windows - [@window]).first
|
32
|
-
expect(@session.driver).to receive(:switch_to_window).exactly(5).times.and_call_original
|
33
32
|
@session.within_window window do
|
34
33
|
expect(@session).to have_title(/Title of the first popup|Title of popup two/)
|
35
34
|
end
|
@@ -133,6 +133,10 @@ module Capybara
|
|
133
133
|
def chrome_gte?(version, session)
|
134
134
|
chrome?(session) && (session.driver.browser.capabilities[:version].to_f >= version)
|
135
135
|
end
|
136
|
+
|
137
|
+
def edge?(session)
|
138
|
+
session.respond_to?(:driver) && session.driver.respond_to?(:edge?, true) && session.driver.send(:edge?)
|
139
|
+
end
|
136
140
|
end
|
137
141
|
end
|
138
142
|
|
@@ -144,6 +144,15 @@ class TestApp < Sinatra::Base
|
|
144
144
|
erb :with_html, locals: { referrer: request.referrer }
|
145
145
|
end
|
146
146
|
|
147
|
+
get '/with_title' do
|
148
|
+
<<-HTML
|
149
|
+
<title>#{params[:title] || 'Test Title'}</title>
|
150
|
+
<body>
|
151
|
+
<svg><title>abcdefg</title></svg>
|
152
|
+
</body>
|
153
|
+
HTML
|
154
|
+
end
|
155
|
+
|
147
156
|
get '/:view' do |view|
|
148
157
|
erb view.to_sym, locals: { referrer: request.referrer }
|
149
158
|
end
|
@@ -426,6 +426,12 @@ New line after and before textarea tag
|
|
426
426
|
<input type="button" disabled="disabled" value="Disabled button"/>
|
427
427
|
</p>
|
428
428
|
|
429
|
+
<p>
|
430
|
+
<input type="date" name="form[date]" id="form_date"/>
|
431
|
+
<input type="time" name="form[time]" id="form_time"/>
|
432
|
+
<input type="datetime-local" name="form[datetime]" id="form_datetime">
|
433
|
+
</p>
|
434
|
+
|
429
435
|
<p>
|
430
436
|
<input id="readonly" name="form[readonly_test]" readonly/>
|
431
437
|
<input id="not_readonly" name="form[readonly_test]" />
|
@@ -153,3 +153,23 @@ banana</textarea>
|
|
153
153
|
</div>
|
154
154
|
|
155
155
|
<div id='1escape.me' class="2escape">needs escaping</div>
|
156
|
+
|
157
|
+
<div id="normalized">
|
158
|
+
Some text<div>More text</div>
|
159
|
+
<div> And more text</div>
|
160
|
+
Even more text
|
161
|
+
|
162
|
+
on multiple lines
|
163
|
+
</div>
|
164
|
+
|
165
|
+
<div id="non_visible_normalized" style="display: none">
|
166
|
+
Some text<div>More text</div>
|
167
|
+
<div> And more text</div>
|
168
|
+
Even more text
|
169
|
+
|
170
|
+
on multiple lines
|
171
|
+
</div>
|
172
|
+
|
173
|
+
<div id="ws">
|
174
|
+
                   
|
175
|
+
</div>
|
data/lib/capybara/version.rb
CHANGED
@@ -28,6 +28,8 @@ skipped_tests = %i[response_headers status_code trigger]
|
|
28
28
|
# skip window tests when headless for now - closing a window not supported by chromedriver/chrome
|
29
29
|
skipped_tests << :windows if ENV['TRAVIS'] && (ENV['SKIP_WINDOW'] || ENV['HEADLESS'])
|
30
30
|
|
31
|
+
$stdout.puts `#{Selenium::WebDriver::Chrome.driver_path} --version` if ENV['CI']
|
32
|
+
|
31
33
|
Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_DRIVER.to_s, capybara_skip: skipped_tests
|
32
34
|
|
33
35
|
RSpec.describe "Capybara::Session with chrome" do
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require "selenium-webdriver"
|
5
|
+
require 'shared_selenium_session'
|
6
|
+
require 'rspec/shared_spec_matchers'
|
7
|
+
|
8
|
+
Capybara.register_driver :selenium_edge do |app|
|
9
|
+
# ::Selenium::WebDriver.logger.level = "debug"
|
10
|
+
Capybara::Selenium::Driver.new(app, browser: :edge)
|
11
|
+
end
|
12
|
+
|
13
|
+
module TestSessions
|
14
|
+
SeleniumEdge = Capybara::Session.new(:selenium_edge, TestApp)
|
15
|
+
end
|
16
|
+
|
17
|
+
skipped_tests = %i[response_headers status_code trigger modals]
|
18
|
+
|
19
|
+
$stdout.puts `#{Selenium::WebDriver::Edge.driver_path} --version` if ENV['CI']
|
20
|
+
|
21
|
+
Capybara::SpecHelper.run_specs TestSessions::SeleniumEdge, "selenium", capybara_skip: skipped_tests
|
22
|
+
|
23
|
+
RSpec.describe "Capybara::Session with Edge" do
|
24
|
+
include Capybara::SpecHelper
|
25
|
+
include_examples "Capybara::Session", TestSessions::SeleniumEdge, :selenium_edge
|
26
|
+
include_examples Capybara::RSpecMatchers, TestSessions::SeleniumEdge, :selenium_edge
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require "selenium-webdriver"
|
5
|
+
require 'shared_selenium_session'
|
6
|
+
require 'rspec/shared_spec_matchers'
|
7
|
+
|
8
|
+
Capybara.register_driver :selenium_ie do |app|
|
9
|
+
# ::Selenium::WebDriver.logger.level = "debug"
|
10
|
+
Capybara::Selenium::Driver.new(app, browser: :ie)
|
11
|
+
end
|
12
|
+
|
13
|
+
module TestSessions
|
14
|
+
SeleniumIE = Capybara::Session.new(:selenium_ie, TestApp)
|
15
|
+
end
|
16
|
+
|
17
|
+
skipped_tests = %i[response_headers status_code trigger]
|
18
|
+
|
19
|
+
$stdout.puts `#{Selenium::WebDriver::IE.driver_path} --version` if ENV['CI']
|
20
|
+
|
21
|
+
Capybara::SpecHelper.run_specs TestSessions::SeleniumIE, "selenium", capybara_skip: skipped_tests
|
22
|
+
|
23
|
+
RSpec.describe "Capybara::Session with Internet Explorer" do
|
24
|
+
include Capybara::SpecHelper
|
25
|
+
include_examples "Capybara::Session", TestSessions::SeleniumIE, :selenium_ie
|
26
|
+
include_examples Capybara::RSpecMatchers, TestSessions::SeleniumIE, :selenium_ie
|
27
|
+
end
|
@@ -40,6 +40,8 @@ end
|
|
40
40
|
skipped_tests = %i[response_headers status_code trigger]
|
41
41
|
skipped_tests << :windows if ENV['TRAVIS'] && ENV['SKIP_WINDOW']
|
42
42
|
|
43
|
+
$stdout.puts `#{Selenium::WebDriver::Firefox.driver_path} --version` if ENV['CI']
|
44
|
+
|
43
45
|
Capybara::SpecHelper.run_specs TestSessions::SeleniumMarionette, "selenium", capybara_skip: skipped_tests
|
44
46
|
|
45
47
|
RSpec.describe "Capybara::Session with firefox" do
|
data/spec/server_spec.rb
CHANGED
@@ -35,7 +35,7 @@ RSpec.describe Capybara::Server do
|
|
35
35
|
ensure
|
36
36
|
Capybara.server_host = nil
|
37
37
|
end
|
38
|
-
end unless ENV['TRAVIS']
|
38
|
+
end unless ENV['TRAVIS'] && (RUBY_ENGINE == 'jruby') or Gem.win_platform?
|
39
39
|
|
40
40
|
it "should use specified port" do
|
41
41
|
Capybara.server_port = 22789
|
@@ -64,6 +64,7 @@ RSpec.shared_examples "Capybara::Session" do |session, mode|
|
|
64
64
|
end
|
65
65
|
|
66
66
|
it "can be called before visiting" do
|
67
|
+
skip "Edge driver doesn't get any interactions when alert is set" if edge?(@session)
|
67
68
|
@session.accept_alert "Initial alert" do
|
68
69
|
@session.visit('/initial_alert')
|
69
70
|
end
|
@@ -217,5 +218,13 @@ RSpec.shared_examples "Capybara::Session" do |session, mode|
|
|
217
218
|
expect(@session).to have_current_path('/')
|
218
219
|
end
|
219
220
|
end
|
221
|
+
|
222
|
+
context "Windows" do
|
223
|
+
it "can't close the primary window" do
|
224
|
+
expect do
|
225
|
+
@session.current_window.close
|
226
|
+
end.to raise_error(ArgumentError, 'Not allowed to close the primary window')
|
227
|
+
end
|
228
|
+
end
|
220
229
|
end
|
221
230
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
require 'rspec/expectations'
|
4
4
|
require "capybara/spec/spec_helper"
|
5
|
-
require 'webdrivers' if ENV['
|
5
|
+
require 'webdrivers' if ENV['CI']
|
6
6
|
|
7
7
|
RSpec.configure do |config|
|
8
8
|
Capybara::SpecHelper.configure(config)
|
9
|
-
config.filter_run_including focus_: true unless ENV['
|
9
|
+
config.filter_run_including focus_: true unless ENV['CI']
|
10
10
|
config.run_all_when_everything_filtered = true
|
11
11
|
end
|
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.0.0.
|
4
|
+
version: 3.0.0.rc2
|
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: 2018-03-
|
13
|
+
date: 2018-03-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: addressable
|
@@ -371,6 +371,8 @@ files:
|
|
371
371
|
- lib/capybara/spec/session/find_link_spec.rb
|
372
372
|
- lib/capybara/spec/session/find_spec.rb
|
373
373
|
- lib/capybara/spec/session/first_spec.rb
|
374
|
+
- lib/capybara/spec/session/frame/frame_title_spec.rb
|
375
|
+
- lib/capybara/spec/session/frame/frame_url_spec.rb
|
374
376
|
- lib/capybara/spec/session/frame/switch_to_frame_spec.rb
|
375
377
|
- lib/capybara/spec/session/frame/within_frame_spec.rb
|
376
378
|
- lib/capybara/spec/session/go_back_spec.rb
|
@@ -471,6 +473,8 @@ files:
|
|
471
473
|
- spec/rspec_spec.rb
|
472
474
|
- spec/selector_spec.rb
|
473
475
|
- spec/selenium_spec_chrome.rb
|
476
|
+
- spec/selenium_spec_edge.rb
|
477
|
+
- spec/selenium_spec_ie.rb
|
474
478
|
- spec/selenium_spec_marionette.rb
|
475
479
|
- spec/server_spec.rb
|
476
480
|
- spec/session_spec.rb
|