capybara 3.0.2 → 3.0.3
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 +9 -0
- data/lib/capybara.rb +1 -0
- data/lib/capybara/node/actions.rb +1 -1
- data/lib/capybara/selenium/driver.rb +26 -30
- data/lib/capybara/selenium/node.rb +3 -3
- data/lib/capybara/server.rb +15 -7
- data/lib/capybara/spec/session/check_spec.rb +6 -0
- data/lib/capybara/spec/session/choose_spec.rb +6 -0
- data/lib/capybara/spec/session/uncheck_spec.rb +7 -0
- data/lib/capybara/version.rb +1 -1
- data/spec/selenium_spec_chrome_remote.rb +56 -0
- data/spec/shared_selenium_session.rb +8 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8304f8ac3e0f20f8fae8db3eedea4f623de6756708c0ba95ec83fc4587ec4321
|
4
|
+
data.tar.gz: dff277e0f6abb0275ff4462de9fd9de8c930032f4a574448af16688af337c58c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b7bfa133c75b1556490b7337178cfd3e9137157e16c922679b72067b055fd54d659237367c7f066bbb7e2a6d75311db8736abc8e4d94030898a39e39a297ae9
|
7
|
+
data.tar.gz: b320cdc763f873e87f13b83ec693db1f590a32a2193fb56a7dfd82310101b39636c26a1da520b723dca31672f289201d649b90a0288f1ae281ac40b6b3d612bc
|
data/History.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
# Version 3.0.3
|
2
|
+
Release date: 2018-04-30
|
3
|
+
|
4
|
+
### Fixes
|
5
|
+
|
6
|
+
* Issue in `check` where the locator string could not be omitted
|
7
|
+
* Selenium browser type detection when using remote [Ian Ker-Seymer]
|
8
|
+
* Potential hang when waiting for requests to complete [Chris Zetter]
|
9
|
+
|
1
10
|
# Version 3.0.2
|
2
11
|
Release date: 2018-04-13
|
3
12
|
|
data/lib/capybara.rb
CHANGED
@@ -494,6 +494,7 @@ Capybara.register_driver :selenium_chrome do |app|
|
|
494
494
|
end
|
495
495
|
|
496
496
|
Capybara.register_driver :selenium_chrome_headless do |app|
|
497
|
+
Capybara::Selenium::Driver.load_selenium
|
497
498
|
browser_options = ::Selenium::WebDriver::Chrome::Options.new
|
498
499
|
browser_options.args << '--headless'
|
499
500
|
browser_options.args << '--disable-gpu'
|
@@ -129,7 +129,7 @@ module Capybara
|
|
129
129
|
# @macro waiting_behavior
|
130
130
|
#
|
131
131
|
# @return [Capybara::Node::Element] The element checked or the label clicked
|
132
|
-
def check(locator, **options)
|
132
|
+
def check(locator = nil, **options)
|
133
133
|
_check_with_label(:checkbox, true, locator, **options)
|
134
134
|
end
|
135
135
|
|
@@ -13,12 +13,29 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
13
13
|
|
14
14
|
attr_reader :app, :options
|
15
15
|
|
16
|
+
def self.load_selenium
|
17
|
+
require 'selenium-webdriver'
|
18
|
+
# Fix for selenium-webdriver 3.4.0 which misnamed these
|
19
|
+
unless defined?(::Selenium::WebDriver::Error::ElementNotInteractableError)
|
20
|
+
::Selenium::WebDriver::Error.const_set('ElementNotInteractableError', Class.new(::Selenium::WebDriver::Error::WebDriverError))
|
21
|
+
end
|
22
|
+
unless defined?(::Selenium::WebDriver::Error::ElementClickInterceptedError)
|
23
|
+
::Selenium::WebDriver::Error.const_set('ElementClickInterceptedError', Class.new(::Selenium::WebDriver::Error::WebDriverError))
|
24
|
+
end
|
25
|
+
rescue LoadError => e
|
26
|
+
if e.message =~ /selenium-webdriver/
|
27
|
+
raise LoadError, "Capybara's selenium driver is unable to load `selenium-webdriver`, please install the gem and add `gem 'selenium-webdriver'` to your Gemfile if you are using bundler."
|
28
|
+
else
|
29
|
+
raise e
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
16
33
|
def browser
|
17
34
|
unless @browser
|
18
|
-
if firefox?
|
19
|
-
|
20
|
-
|
21
|
-
end
|
35
|
+
# if firefox?
|
36
|
+
# options[:desired_capabilities] ||= {}
|
37
|
+
# options[:desired_capabilities][:unexpectedAlertBehaviour] = "ignore"
|
38
|
+
# end
|
22
39
|
|
23
40
|
@processed_options = options.reject { |key, _val| SPECIAL_OPTIONS.include?(key) }
|
24
41
|
@browser = Selenium::WebDriver.for(options[:browser], @processed_options)
|
@@ -38,7 +55,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
38
55
|
end
|
39
56
|
|
40
57
|
def initialize(app, **options)
|
41
|
-
load_selenium
|
58
|
+
self.class.load_selenium
|
42
59
|
@session = nil
|
43
60
|
@app = app
|
44
61
|
@browser = nil
|
@@ -288,30 +305,26 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
288
305
|
|
289
306
|
# @api private
|
290
307
|
def firefox?
|
291
|
-
|
308
|
+
browser.browser == :firefox
|
292
309
|
end
|
293
310
|
|
294
311
|
# @api private
|
295
312
|
def chrome?
|
296
|
-
|
313
|
+
browser.browser == :chrome
|
297
314
|
end
|
298
315
|
|
299
316
|
# @api private
|
300
317
|
def edge?
|
301
|
-
|
318
|
+
browser.browser == :edge
|
302
319
|
end
|
303
320
|
|
304
321
|
# @api private
|
305
322
|
def ie?
|
306
|
-
|
323
|
+
browser.browser == :ie
|
307
324
|
end
|
308
325
|
|
309
326
|
private
|
310
327
|
|
311
|
-
def browser_name
|
312
|
-
options[:browser].to_s
|
313
|
-
end
|
314
|
-
|
315
328
|
def clear_storage
|
316
329
|
if options[:clear_session_storage]
|
317
330
|
if @browser.respond_to? :session_storage
|
@@ -472,21 +485,4 @@ private
|
|
472
485
|
arg
|
473
486
|
end
|
474
487
|
end
|
475
|
-
|
476
|
-
def load_selenium
|
477
|
-
require 'selenium-webdriver'
|
478
|
-
# Fix for selenium-webdriver 3.4.0 which misnamed these
|
479
|
-
unless defined?(::Selenium::WebDriver::Error::ElementNotInteractableError)
|
480
|
-
::Selenium::WebDriver::Error.const_set('ElementNotInteractableError', Class.new(::Selenium::WebDriver::Error::WebDriverError))
|
481
|
-
end
|
482
|
-
unless defined?(::Selenium::WebDriver::Error::ElementClickInterceptedError)
|
483
|
-
::Selenium::WebDriver::Error.const_set('ElementClickInterceptedError', Class.new(::Selenium::WebDriver::Error::WebDriverError))
|
484
|
-
end
|
485
|
-
rescue LoadError => e
|
486
|
-
if e.message =~ /selenium-webdriver/
|
487
|
-
raise LoadError, "Capybara's selenium driver is unable to load `selenium-webdriver`, please install the gem and add `gem 'selenium-webdriver'` to your Gemfile if you are using bundler."
|
488
|
-
else
|
489
|
-
raise e
|
490
|
-
end
|
491
|
-
end
|
492
488
|
end
|
@@ -255,7 +255,7 @@ private
|
|
255
255
|
|
256
256
|
def set_date(value) # rubocop:disable Naming/AccessorMethodName
|
257
257
|
if value.respond_to?(:to_date)
|
258
|
-
set_text(value.to_date.strftime(SET_FORMATS[driver.
|
258
|
+
set_text(value.to_date.strftime(SET_FORMATS[driver.browser.browser][:date]))
|
259
259
|
else
|
260
260
|
set_text(value)
|
261
261
|
end
|
@@ -263,7 +263,7 @@ private
|
|
263
263
|
|
264
264
|
def set_time(value) # rubocop:disable Naming/AccessorMethodName
|
265
265
|
if value.respond_to?(:to_time)
|
266
|
-
set_text(value.to_time.strftime(SET_FORMATS[driver.
|
266
|
+
set_text(value.to_time.strftime(SET_FORMATS[driver.browser.browser][:time]))
|
267
267
|
else
|
268
268
|
set_text(value)
|
269
269
|
end
|
@@ -271,7 +271,7 @@ private
|
|
271
271
|
|
272
272
|
def set_datetime_local(value) # rubocop:disable Naming/AccessorMethodName
|
273
273
|
if value.respond_to?(:to_time)
|
274
|
-
set_text(value.to_time.strftime(SET_FORMATS[driver.
|
274
|
+
set_text(value.to_time.strftime(SET_FORMATS[driver.browser.browser][:datetime]))
|
275
275
|
else
|
276
276
|
set_text(value)
|
277
277
|
end
|
data/lib/capybara/server.rb
CHANGED
@@ -90,9 +90,13 @@ module Capybara
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def wait_for_pending_requests
|
93
|
-
|
94
|
-
|
95
|
-
|
93
|
+
start_time = Capybara::Helpers.monotonic_time
|
94
|
+
while pending_requests?
|
95
|
+
if (Capybara::Helpers.monotonic_time - start_time) > 60
|
96
|
+
raise "Requests did not finish in 60 seconds"
|
97
|
+
end
|
98
|
+
sleep 0.01
|
99
|
+
end
|
96
100
|
end
|
97
101
|
|
98
102
|
def boot
|
@@ -103,11 +107,15 @@ module Capybara
|
|
103
107
|
Capybara.server.call(middleware, port, host)
|
104
108
|
end
|
105
109
|
|
106
|
-
|
110
|
+
start_time = Capybara::Helpers.monotonic_time
|
111
|
+
until responsive?
|
112
|
+
if (Capybara::Helpers.monotonic_time - start_time) > 60
|
113
|
+
raise "Rack application timed out during boot"
|
114
|
+
end
|
115
|
+
@server_thread.join(0.1)
|
116
|
+
end
|
107
117
|
end
|
108
|
-
|
109
|
-
raise "Rack application timed out during boot"
|
110
|
-
else
|
118
|
+
|
111
119
|
self
|
112
120
|
end
|
113
121
|
|
@@ -62,6 +62,12 @@ Capybara::SpecHelper.spec "#check" do
|
|
62
62
|
expect(extract_results(@session)['pets']).to include('dog', 'cat', 'hamster')
|
63
63
|
end
|
64
64
|
|
65
|
+
it "should work without a locator string" do
|
66
|
+
@session.check(id: "form_pets_cat")
|
67
|
+
@session.click_button('awesome')
|
68
|
+
expect(extract_results(@session)['pets']).to include('dog', 'cat', 'hamster')
|
69
|
+
end
|
70
|
+
|
65
71
|
it "casts to string" do
|
66
72
|
@session.check(:form_pets_cat)
|
67
73
|
@session.click_button('awesome')
|
@@ -17,6 +17,12 @@ Capybara::SpecHelper.spec "#choose" do
|
|
17
17
|
expect(extract_results(@session)['gender']).to eq('both')
|
18
18
|
end
|
19
19
|
|
20
|
+
it "should work without a locator string" do
|
21
|
+
@session.choose(id: "gender_male")
|
22
|
+
@session.click_button('awesome')
|
23
|
+
expect(extract_results(@session)['gender']).to eq('male')
|
24
|
+
end
|
25
|
+
|
20
26
|
it "casts to string" do
|
21
27
|
@session.choose("Both")
|
22
28
|
@session.click_button(:awesome)
|
@@ -19,6 +19,13 @@ Capybara::SpecHelper.spec "#uncheck" do
|
|
19
19
|
expect(extract_results(@session)['pets']).not_to include('hamster')
|
20
20
|
end
|
21
21
|
|
22
|
+
it "should work without a locator string" do
|
23
|
+
@session.uncheck(id: "form_pets_hamster")
|
24
|
+
@session.click_button('awesome')
|
25
|
+
expect(extract_results(@session)['pets']).to include('dog')
|
26
|
+
expect(extract_results(@session)['pets']).not_to include('hamster')
|
27
|
+
end
|
28
|
+
|
22
29
|
it "casts to string" do
|
23
30
|
@session.uncheck(:form_pets_hamster)
|
24
31
|
@session.click_button('awesome')
|
data/lib/capybara/version.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
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
|
+
def selenium_host
|
9
|
+
ENV.fetch('SELENIUM_HOST', '0.0.0.0')
|
10
|
+
end
|
11
|
+
|
12
|
+
def selenium_port
|
13
|
+
ENV.fetch('SELENIUM_PORT', 4444)
|
14
|
+
end
|
15
|
+
|
16
|
+
def ensure_selenium_running!
|
17
|
+
TCPSocket.open(selenium_host, selenium_port)
|
18
|
+
rescue
|
19
|
+
raise 'Selenium is not running. ' \
|
20
|
+
"You can run a selenium server easily with: \n" \
|
21
|
+
' $ docker-compose up -d selenium'
|
22
|
+
end
|
23
|
+
|
24
|
+
Capybara.register_driver :selenium_chrome_remote do |app|
|
25
|
+
ensure_selenium_running!
|
26
|
+
|
27
|
+
url = "http://#{selenium_host}:#{selenium_port}/wd/hub"
|
28
|
+
caps = Selenium::WebDriver::Remote::Capabilities.chrome
|
29
|
+
|
30
|
+
Capybara::Selenium::Driver.new app,
|
31
|
+
browser: :remote,
|
32
|
+
desired_capabilities: caps,
|
33
|
+
url: url
|
34
|
+
end
|
35
|
+
|
36
|
+
CHROME_REMOTE_DRIVER = :selenium_chrome_remote
|
37
|
+
|
38
|
+
module TestSessions
|
39
|
+
Chrome = Capybara::Session.new(CHROME_REMOTE_DRIVER, TestApp)
|
40
|
+
end
|
41
|
+
|
42
|
+
skipped_tests = %i[response_headers status_code trigger]
|
43
|
+
# skip window tests when headless for now - closing a window not supported by chromedriver/chrome
|
44
|
+
skipped_tests << :windows if ENV['TRAVIS'] && (ENV['SKIP_WINDOW'] || ENV['HEADLESS'])
|
45
|
+
|
46
|
+
Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_REMOTE_DRIVER.to_s, capybara_skip: skipped_tests
|
47
|
+
|
48
|
+
RSpec.describe "Capybara::Session with chrome" do
|
49
|
+
include Capybara::SpecHelper
|
50
|
+
include_examples "Capybara::Session", TestSessions::Chrome, CHROME_REMOTE_DRIVER
|
51
|
+
include_examples Capybara::RSpecMatchers, TestSessions::Chrome, CHROME_REMOTE_DRIVER
|
52
|
+
|
53
|
+
it 'is considered to be chrome' do
|
54
|
+
expect(session.driver).to be_chrome
|
55
|
+
end
|
56
|
+
end
|
@@ -43,13 +43,15 @@ RSpec.shared_examples "Capybara::Session" do |session, mode|
|
|
43
43
|
end
|
44
44
|
|
45
45
|
it "should have return code 1 when running selenium_driver_rspec_failure.rb" do
|
46
|
-
skip if
|
46
|
+
skip if headless_or_remote?
|
47
|
+
|
47
48
|
system(@env, 'rspec spec/fixtures/selenium_driver_rspec_failure.rb', out: File::NULL, err: File::NULL)
|
48
49
|
expect($CHILD_STATUS.exitstatus).to eq(1)
|
49
50
|
end
|
50
51
|
|
51
52
|
it "should have return code 0 when running selenium_driver_rspec_success.rb" do
|
52
|
-
skip if
|
53
|
+
skip if headless_or_remote?
|
54
|
+
|
53
55
|
system(@env, 'rspec spec/fixtures/selenium_driver_rspec_success.rb', out: File::NULL, err: File::NULL)
|
54
56
|
expect($CHILD_STATUS.exitstatus).to eq(0)
|
55
57
|
end
|
@@ -226,4 +228,8 @@ RSpec.shared_examples "Capybara::Session" do |session, mode|
|
|
226
228
|
end
|
227
229
|
end
|
228
230
|
end
|
231
|
+
|
232
|
+
def headless_or_remote?
|
233
|
+
!ENV['HEADLESS'].nil? || session.driver.options[:browser] == :remote
|
234
|
+
end
|
229
235
|
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.
|
4
|
+
version: 3.0.3
|
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-04-
|
13
|
+
date: 2018-04-30 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: addressable
|
@@ -473,6 +473,7 @@ files:
|
|
473
473
|
- spec/rspec_spec.rb
|
474
474
|
- spec/selector_spec.rb
|
475
475
|
- spec/selenium_spec_chrome.rb
|
476
|
+
- spec/selenium_spec_chrome_remote.rb
|
476
477
|
- spec/selenium_spec_edge.rb
|
477
478
|
- spec/selenium_spec_ie.rb
|
478
479
|
- spec/selenium_spec_marionette.rb
|