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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78eeeb205ad6e29addf7c2729e180b39076becacfee989561cea4c9e29f6bd65
4
- data.tar.gz: 9adb328acd7184ee33e156ec4b842ca048aa792ddda95e9396a515778a04b82d
3
+ metadata.gz: 8304f8ac3e0f20f8fae8db3eedea4f623de6756708c0ba95ec83fc4587ec4321
4
+ data.tar.gz: dff277e0f6abb0275ff4462de9fd9de8c930032f4a574448af16688af337c58c
5
5
  SHA512:
6
- metadata.gz: 89ba8bfe2b60b8dc5dd3234c6f1bff37576d93432d64e13478dde82b94d6e2e6d46ec7e4c28791744382c578223edfc242c27f34695e2a078a7637465fc01833
7
- data.tar.gz: e8334635068aef37f9ca3a2bd66b9de9fa2b467391dfd9ffa1d72df333cbbeb1adb5ac120471d162286ed14ccf85af160a3421c700ce98ee7f9e3bfb2edc4377
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
 
@@ -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
- options[:desired_capabilities] ||= {}
20
- options[:desired_capabilities][:unexpectedAlertBehaviour] = "ignore"
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
- browser_name == "firefox"
308
+ browser.browser == :firefox
292
309
  end
293
310
 
294
311
  # @api private
295
312
  def chrome?
296
- browser_name == "chrome"
313
+ browser.browser == :chrome
297
314
  end
298
315
 
299
316
  # @api private
300
317
  def edge?
301
- browser_name == "edge"
318
+ browser.browser == :edge
302
319
  end
303
320
 
304
321
  # @api private
305
322
  def ie?
306
- browser_name == "ie"
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.options[:browser].to_sym][:date]))
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.options[:browser].to_sym][:time]))
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.options[:browser].to_sym][:datetime]))
274
+ set_text(value.to_time.strftime(SET_FORMATS[driver.browser.browser][:datetime]))
275
275
  else
276
276
  set_text(value)
277
277
  end
@@ -90,9 +90,13 @@ module Capybara
90
90
  end
91
91
 
92
92
  def wait_for_pending_requests
93
- Timeout.timeout(60) { sleep(0.01) while pending_requests? }
94
- rescue Timeout::Error
95
- raise "Requests did not finish in 60 seconds"
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
- Timeout.timeout(60) { @server_thread.join(0.1) until responsive? }
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
- rescue Timeout::Error
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')
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Capybara
4
- VERSION = '3.0.2'.freeze
4
+ VERSION = '3.0.3'.freeze
5
5
  end
@@ -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 ENV['HEADLESS']
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 ENV['HEADLESS']
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.2
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 00:00:00.000000000 Z
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