watir 6.16.3 → 6.19.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/actions/enable-safari/action.yml +11 -0
- data/.github/actions/install-chrome/action.yml +11 -0
- data/.github/workflows/linux.yml +61 -0
- data/.github/workflows/mac.yml +55 -0
- data/.github/workflows/unit.yml +37 -0
- data/.github/workflows/windows.yml +39 -0
- data/.rubocop.yml +32 -107
- data/.rubocop_todo.yml +36 -0
- data/CHANGES.md +55 -0
- data/Gemfile +3 -1
- data/LICENSE +2 -2
- data/README.md +9 -10
- data/Rakefile +4 -4
- data/lib/watir-webdriver.rb +1 -1
- data/lib/watir.rb +3 -1
- data/lib/watir/adjacent.rb +8 -10
- data/lib/watir/after_hooks.rb +4 -4
- data/lib/watir/alert.rb +1 -0
- data/lib/watir/attribute_helper.rb +2 -0
- data/lib/watir/browser.rb +7 -3
- data/lib/watir/capabilities.rb +245 -97
- data/lib/watir/cookies.rb +3 -1
- data/lib/watir/element_collection.rb +21 -6
- data/lib/watir/elements/element.rb +66 -53
- data/lib/watir/elements/file_field.rb +1 -0
- data/lib/watir/elements/html_elements.rb +0 -1
- data/lib/watir/elements/iframe.rb +4 -3
- data/lib/watir/elements/link.rb +0 -9
- data/lib/watir/elements/radio.rb +1 -1
- data/lib/watir/elements/select.rb +22 -7
- data/lib/watir/generator/base/spec_extractor.rb +4 -4
- data/lib/watir/generator/html/generator.rb +1 -1
- data/lib/watir/has_window.rb +17 -15
- data/lib/watir/http_client.rb +17 -0
- data/lib/watir/js_execution.rb +3 -3
- data/lib/watir/js_snippets.rb +2 -2
- data/lib/watir/legacy_wait.rb +1 -1
- data/lib/watir/locators.rb +1 -3
- data/lib/watir/locators/element/locator.rb +12 -6
- data/lib/watir/locators/element/selector_builder.rb +12 -13
- data/lib/watir/locators/element/selector_builder/xpath.rb +40 -13
- data/lib/watir/locators/text_field/selector_builder/xpath.rb +3 -1
- data/lib/watir/logger.rb +7 -20
- data/lib/watir/radio_set.rb +2 -2
- data/lib/watir/user_editable.rb +6 -2
- data/lib/watir/version.rb +1 -1
- data/lib/watir/wait.rb +2 -0
- data/lib/watir/wait/timer.rb +1 -1
- data/lib/watir/window.rb +8 -4
- data/lib/watir/window_collection.rb +114 -0
- data/lib/watirspec.rb +2 -1
- data/lib/watirspec/guards.rb +1 -1
- data/lib/watirspec/implementation.rb +3 -5
- data/lib/watirspec/rake_tasks.rb +2 -0
- data/lib/watirspec/runner.rb +6 -2
- data/lib/watirspec/server.rb +1 -1
- data/spec/spec_helper.rb +2 -7
- data/spec/unit/capabilities_spec.rb +1234 -18
- data/spec/unit/container_spec.rb +1 -1
- data/spec/unit/logger_spec.rb +5 -7
- data/spec/unit/match_elements/element_spec.rb +17 -15
- data/spec/unit/selector_builder/button_spec.rb +16 -15
- data/spec/unit/selector_builder/element_spec.rb +58 -9
- data/spec/unit/selector_builder/text_field_spec.rb +14 -14
- data/spec/unit/unit_helper.rb +2 -4
- data/spec/watirspec/after_hooks_spec.rb +58 -68
- data/spec/watirspec/alert_spec.rb +69 -79
- data/spec/watirspec/browser_spec.rb +51 -48
- data/spec/watirspec/cookies_spec.rb +52 -37
- data/spec/watirspec/drag_and_drop_spec.rb +14 -38
- data/spec/watirspec/elements/button_spec.rb +2 -0
- data/spec/watirspec/elements/buttons_spec.rb +1 -1
- data/spec/watirspec/elements/checkbox_spec.rb +8 -4
- data/spec/watirspec/elements/date_field_spec.rb +18 -9
- data/spec/watirspec/elements/date_time_field_spec.rb +3 -4
- data/spec/watirspec/elements/div_spec.rb +62 -54
- data/spec/watirspec/elements/element_spec.rb +73 -88
- data/spec/watirspec/elements/elements_spec.rb +12 -3
- data/spec/watirspec/elements/filefield_spec.rb +25 -50
- data/spec/watirspec/elements/form_spec.rb +6 -8
- data/spec/watirspec/elements/frame_spec.rb +10 -13
- data/spec/watirspec/elements/iframe_spec.rb +12 -9
- data/spec/watirspec/elements/iframes_spec.rb +2 -2
- data/spec/watirspec/elements/link_spec.rb +23 -12
- data/spec/watirspec/elements/links_spec.rb +11 -3
- data/spec/watirspec/elements/option_spec.rb +15 -17
- data/spec/watirspec/elements/select_list_spec.rb +222 -117
- data/spec/watirspec/elements/text_field_spec.rb +8 -4
- data/spec/watirspec/elements/tr_spec.rb +0 -9
- data/spec/watirspec/html/forms_with_input_elements.html +1 -0
- data/spec/watirspec/html/iframes.html +3 -0
- data/spec/watirspec/html/non_control_elements.html +4 -4
- data/spec/watirspec/html/right_click.html +12 -0
- data/spec/watirspec/html/wait.html +6 -6
- data/spec/watirspec/html/window_switching.html +10 -0
- data/spec/watirspec/legacy_wait_spec.rb +216 -0
- data/spec/watirspec/support/rspec_matchers.rb +33 -14
- data/spec/watirspec/user_editable_spec.rb +1 -1
- data/spec/watirspec/wait_spec.rb +257 -305
- data/spec/watirspec/window_switching_spec.rb +338 -211
- data/spec/watirspec_helper.rb +17 -20
- data/support/doctest_helper.rb +0 -2
- data/watir.gemspec +6 -7
- metadata +37 -26
- data/.travis.yml +0 -84
- data/appveyor.yml +0 -12
- data/lib/watir/elements/area.rb +0 -10
- data/spec/watirspec/relaxed_locate_spec.rb +0 -113
data/CHANGES.md
CHANGED
@@ -1,3 +1,58 @@
|
|
1
|
+
### 6.19.0 (2021-03-12)
|
2
|
+
|
3
|
+
* Create custom Watir HTTP Client
|
4
|
+
* Require minimum of Selenium 3.142.7
|
5
|
+
* Add support for starting browser with :http_client and :service hashes
|
6
|
+
* Allow inferring desired browser from Capabilities or Options if browser not specified
|
7
|
+
* Deprecate WindowCollection#to_a method
|
8
|
+
* Deprecate starting browser with both Capabilities and Options
|
9
|
+
* Deprecate starting browser with both URL and Service
|
10
|
+
* Deprecate using :desired_capabilities
|
11
|
+
* Deprecate starting browser service keywords in top level Hash
|
12
|
+
* Deprecate using :remote to start a browser; browser name must be specified
|
13
|
+
* Deprecate sending unknown keywords into the top level
|
14
|
+
* Fix bug preventing Safari Options from being recognized
|
15
|
+
* Fix bug preventing options provided without :remote keyword from being properly recognized (#812, #870)
|
16
|
+
* Fix bug preventing :headless from being recognized when :options specified (#692)
|
17
|
+
|
18
|
+
### 6.18.0 (2021-02-26)
|
19
|
+
|
20
|
+
* Implement `WindowCollection` to manage multiple `Window` objects
|
21
|
+
* Add support for locating `Window` by `:element`
|
22
|
+
* Deprecate locating `Window` by `:index`
|
23
|
+
* Deprecate `Select#select_all` in favor of `#select` and an `Array`
|
24
|
+
* Implement `Browser#switch_window` (#849)
|
25
|
+
* Add support for `Numeric` attribute values to `Waitable`
|
26
|
+
* Allow users to specify Selenium 4 in their projects
|
27
|
+
* Update stale element handling behavior to match webdriver spec (#905 #909)
|
28
|
+
* Implement `Waitable` for `ElementCollection` (#853 #857)
|
29
|
+
* Improve performance for nested elements (#843)
|
30
|
+
* Less strict version check for `regexp_parser` gem (thanks Pavel Lobashov)
|
31
|
+
|
32
|
+
### 6.17.0 (2020-08-27)
|
33
|
+
* Require Ruby > 2.5
|
34
|
+
* Implement Logger#selenium= to set selenium level from Watir
|
35
|
+
* Implement FileField#upload
|
36
|
+
* Fix bug with staleness handling in #exist and #present? (#853 & #852)
|
37
|
+
* Fix bug when locating elements by text with RegExp (#866 #871)
|
38
|
+
* Implement modifiers for `Element#right_click` (thanks Lakshya Kapoor #861)
|
39
|
+
* Updated locator code to adhere to spec on what attributes are case sensitive (#507 #856)
|
40
|
+
* Fix locating bug when iframe is nested under another element (thanks Matthew Mazaika #885 #886)
|
41
|
+
* Deprecate Element#scroll_into_view in favor of the new Scroll methods (#884)
|
42
|
+
* Fix threading bugs by allowing each Browser instance its own Timer (#881)
|
43
|
+
* Allow adjacent locators to return Input subtype when applicable (#878)
|
44
|
+
* Removed unnecessary reference to rubyforge (thanks olleolleolle #874)
|
45
|
+
* Removed deprecated Selenium classes (thanks joesho112358 #867)
|
46
|
+
* Add support for :service parameter for initializing Browser
|
47
|
+
|
48
|
+
### 6.16.5 (2018-12-25)
|
49
|
+
|
50
|
+
* Fix bug with nested elements using scopes (#842)
|
51
|
+
|
52
|
+
### 6.16.4 (2018-12-24)
|
53
|
+
|
54
|
+
* Minor adjustments to support locator extensions
|
55
|
+
|
1
56
|
### 6.16.3 (2018-12-24)
|
2
57
|
|
3
58
|
* Minor adjustments to support locator extensions
|
data/Gemfile
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
source '
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
gem 'webidl', path: File.expand_path('../webidl') if ENV['LOCAL_WEBIDL']
|
4
4
|
|
5
5
|
gem 'selenium-webdriver', path: File.expand_path('../selenium/build/rb') if ENV['LOCAL_SELENIUM']
|
6
6
|
|
7
|
+
gem 'ffi' if Gem.win_platform? # For selenium-webdriver on Windows
|
8
|
+
|
7
9
|
# Specify your gem's dependencies in watir.gemspec
|
8
10
|
gemspec
|
data/LICENSE
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
(the MIT License)
|
2
2
|
|
3
3
|
Copyright (c) 2009-2015 Jari Bakken
|
4
|
-
Copyright (c) 2015-
|
5
|
-
Copyright (c) 2018 Justin Ko
|
4
|
+
Copyright (c) 2015-2021 Alex Rodionov, Titus Fortner
|
5
|
+
Copyright (c) 2018-2021 Justin Ko
|
6
6
|
|
7
7
|
Permission is hereby granted, free of charge, to any person obtaining
|
8
8
|
a copy of this software and associated documentation files (the
|
data/README.md
CHANGED
@@ -3,10 +3,12 @@
|
|
3
3
|
Watir Powered By Selenium!
|
4
4
|
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/watir.svg)](http://badge.fury.io/rb/watir)
|
6
|
-
[![
|
7
|
-
[![
|
6
|
+
[![Unit Tests](https://github.com/watir/watir/workflows/Unit%20Tests/badge.svg)](https://github.com/watir/watir/actions?query=workflow%3A%22Unit+Tests%22)
|
7
|
+
[![Mac Tests](https://github.com/watir/watir/workflows/Mac%20Tests/badge.svg)](https://github.com/watir/watir/actions?query=workflow%3A%22Mac+Tests%22)
|
8
|
+
[![Windows Tests](https://github.com/watir/watir/workflows/Windows%20Tests/badge.svg)](https://github.com/watir/watir/actions?query=workflow%3A%22Windows+Tests%22)
|
9
|
+
[![Linux Tests](https://github.com/watir/watir/workflows/Linux%20Tests/badge.svg)](https://github.com/watir/watir/actions?query=workflow%3A%22Linux+Tests%22)
|
8
10
|
[![Code Climate](https://codeclimate.com/github/watir/watir.svg)](https://codeclimate.com/github/watir/watir)
|
9
|
-
[![Coverage Status](https://coveralls.io/repos/github/watir/watir/badge.svg?branch=
|
11
|
+
[![Coverage Status](https://coveralls.io/repos/github/watir/watir/badge.svg?branch=main)](https://coveralls.io/github/watir/watir?branch=main)
|
10
12
|
|
11
13
|
## Using Watir
|
12
14
|
|
@@ -69,11 +71,11 @@ $ bundle exec rake svg:update
|
|
69
71
|
|
70
72
|
## Specs
|
71
73
|
|
72
|
-
####
|
74
|
+
#### Github Actions
|
73
75
|
|
74
|
-
Watir specs are run
|
76
|
+
Watir specs are run with [Github Actions](https://github.com/watir/watir/workflows).
|
75
77
|
|
76
|
-
Watir code is tested
|
78
|
+
Watir code is tested on Linux with latest versions of supported browsers and all active Ruby versions.
|
77
79
|
|
78
80
|
#### Doctests
|
79
81
|
|
@@ -95,7 +97,7 @@ to ensure all paths in their code have tests associated with them.
|
|
95
97
|
|
96
98
|
Watir is using [Rubocop](https://github.com/rubocop-hq/rubocop) to ensure a consistent style across the
|
97
99
|
code base. It is run with our minimum supported Ruby version (2.3)
|
98
|
-
We have some [established exceptions](https://github.com/watir/watir/blob/
|
100
|
+
We have some [established exceptions](https://github.com/watir/watir/blob/main/.rubocop.yml)
|
99
101
|
that might need to be tweaked for new code submissions. This can be addressed in the PR as necessary.
|
100
102
|
|
101
103
|
#### Statistics
|
@@ -107,7 +109,4 @@ on wire calls.
|
|
107
109
|
|
108
110
|
## Copyright
|
109
111
|
|
110
|
-
Copyright (c) 2009-2015 Jari Bakken
|
111
|
-
Copyright (c) 2015-2018 Alex Rodionov, Titus Fortner
|
112
|
-
Copyright (c) 2018 Justin Ko
|
113
112
|
See LICENSE for details
|
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ Bundler::GemHelper.install_tasks
|
|
5
5
|
|
6
6
|
require 'rspec/core/rake_task'
|
7
7
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
8
|
-
spec.rspec_opts = %w[--color --
|
8
|
+
spec.rspec_opts = %w[--color --format doc]
|
9
9
|
spec.pattern = 'spec/**/*_spec.rb'
|
10
10
|
spec.exclude_pattern = 'spec/unit/**/*_spec.rb'
|
11
11
|
end
|
@@ -61,7 +61,7 @@ end
|
|
61
61
|
|
62
62
|
if extractor.errors.any?
|
63
63
|
puts "\n\n<======================= ERRORS =======================>\n\n"
|
64
|
-
puts extractor.errors.join("\n
|
64
|
+
puts extractor.errors.join("\n#{'=' * 80}\n")
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -93,7 +93,7 @@ YARD::Rake::YardocTask.new do |task|
|
|
93
93
|
task.options = %w[--debug] # this is pretty slow, so nice with some output
|
94
94
|
end
|
95
95
|
|
96
|
-
require 'yard
|
96
|
+
require 'yard/doctest/rake'
|
97
97
|
YARD::Doctest::RakeTask.new do |task|
|
98
98
|
task.doctest_opts = ['-v']
|
99
99
|
end
|
@@ -115,7 +115,7 @@ namespace :changes do
|
|
115
115
|
|
116
116
|
desc 'Print latest diff'
|
117
117
|
task print: :differ do
|
118
|
-
VersionDiffer.new.print_latest(
|
118
|
+
VersionDiffer.new.print_latest($stdout)
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
data/lib/watir-webdriver.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
require 'watir'
|
2
|
-
warn Kernel.caller.first
|
2
|
+
warn "#{Kernel.caller.first}: `require 'watir-webdriver'` is deprecated. Please, use `require 'watir'`."
|
data/lib/watir.rb
CHANGED
@@ -6,6 +6,7 @@ require 'watir/legacy_wait'
|
|
6
6
|
require 'watir/wait'
|
7
7
|
require 'watir/exception'
|
8
8
|
require 'watir/window'
|
9
|
+
require 'watir/window_collection'
|
9
10
|
require 'watir/has_window'
|
10
11
|
require 'watir/adjacent'
|
11
12
|
require 'watir/js_execution'
|
@@ -13,12 +14,14 @@ require 'watir/alert'
|
|
13
14
|
require 'watir/js_snippets'
|
14
15
|
require 'watir/container'
|
15
16
|
require 'watir/cookies'
|
17
|
+
require 'watir/http_client'
|
16
18
|
require 'watir/capabilities'
|
17
19
|
require 'watir/navigation'
|
18
20
|
require 'watir/browser'
|
19
21
|
require 'watir/screenshot'
|
20
22
|
require 'watir/after_hooks'
|
21
23
|
require 'watir/logger'
|
24
|
+
require 'watir/version'
|
22
25
|
|
23
26
|
module Watir
|
24
27
|
@relaxed_locate = true
|
@@ -114,7 +117,6 @@ require 'watir/elements/element'
|
|
114
117
|
require 'watir/elements/html_elements'
|
115
118
|
require 'watir/elements/svg_elements'
|
116
119
|
|
117
|
-
require 'watir/elements/area'
|
118
120
|
require 'watir/elements/button'
|
119
121
|
require 'watir/elements/cell'
|
120
122
|
require 'watir/elements/checkbox'
|
data/lib/watir/adjacent.rb
CHANGED
@@ -113,16 +113,14 @@ module Watir
|
|
113
113
|
def xpath_adjacent(opt = {})
|
114
114
|
plural = opt.delete(:plural)
|
115
115
|
opt[:index] ||= 0 unless plural || opt.values.any? { |e| e.is_a? Regexp }
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
end
|
125
|
-
klass.new(self, opt)
|
116
|
+
if !plural
|
117
|
+
el = Watir.element_class_for(opt[:tag_name] || '').new(self, opt)
|
118
|
+
el.is_a?(Input) ? el.to_subtype : el
|
119
|
+
elsif opt[:tag_name]
|
120
|
+
Watir.const_get("#{Watir.element_class_for(opt[:tag_name])}Collection").new(self, opt)
|
121
|
+
else
|
122
|
+
HTMLElementCollection.new(self, opt)
|
123
|
+
end
|
126
124
|
end
|
127
125
|
end # Adjacent
|
128
126
|
end # Watir
|
data/lib/watir/after_hooks.rb
CHANGED
@@ -69,8 +69,8 @@ module Watir
|
|
69
69
|
return unless @after_hooks.any? && !@browser.alert.exists?
|
70
70
|
|
71
71
|
each { |after_hook| after_hook.call(@browser) }
|
72
|
-
rescue Selenium::WebDriver::Error::NoSuchWindowError =>
|
73
|
-
Watir.logger.info "Could not execute After Hooks because browser window was closed #{
|
72
|
+
rescue Selenium::WebDriver::Error::NoSuchWindowError => e
|
73
|
+
Watir.logger.info "Could not execute After Hooks because browser window was closed #{e}"
|
74
74
|
end
|
75
75
|
|
76
76
|
#
|
@@ -99,8 +99,8 @@ module Watir
|
|
99
99
|
# @yieldparam [#call] after_hook Object responding to call
|
100
100
|
#
|
101
101
|
|
102
|
-
def each
|
103
|
-
@after_hooks.each { |after_hook|
|
102
|
+
def each(&blk)
|
103
|
+
@after_hooks.each { |after_hook| blk.call(after_hook) }
|
104
104
|
end
|
105
105
|
|
106
106
|
#
|
data/lib/watir/alert.rb
CHANGED
data/lib/watir/browser.rb
CHANGED
@@ -11,7 +11,7 @@ module Watir
|
|
11
11
|
include Exception
|
12
12
|
include Scrolling
|
13
13
|
|
14
|
-
attr_writer :default_context, :original_window, :locator_namespace
|
14
|
+
attr_writer :default_context, :original_window, :locator_namespace, :timer
|
15
15
|
attr_reader :driver, :after_hooks
|
16
16
|
alias wd driver # ensures duck typing with Watir::Element
|
17
17
|
|
@@ -213,11 +213,11 @@ module Watir
|
|
213
213
|
# @param args Arguments will be available in the given script in the 'arguments' pseudo-array
|
214
214
|
#
|
215
215
|
|
216
|
-
def execute_script(script, *args)
|
216
|
+
def execute_script(script, *args, function_name: nil)
|
217
217
|
args.map! do |e|
|
218
218
|
e.is_a?(Element) ? e.wait_until(&:exists?).wd : e
|
219
219
|
end
|
220
|
-
|
220
|
+
Watir.logger.info "Executing Script on Browser: #{function_name}" if function_name
|
221
221
|
wrap_elements_in(self, @driver.execute_script(script, *args))
|
222
222
|
end
|
223
223
|
|
@@ -300,6 +300,10 @@ module Watir
|
|
300
300
|
end
|
301
301
|
end
|
302
302
|
|
303
|
+
def timer
|
304
|
+
@timer ||= Wait::Timer.new
|
305
|
+
end
|
306
|
+
|
303
307
|
private
|
304
308
|
|
305
309
|
def wrap_element(scope, element)
|
data/lib/watir/capabilities.rb
CHANGED
@@ -2,18 +2,22 @@ module Watir
|
|
2
2
|
class Capabilities
|
3
3
|
attr_reader :options
|
4
4
|
|
5
|
-
def initialize(browser, options = {})
|
5
|
+
def initialize(browser = nil, options = {})
|
6
|
+
if browser.is_a?(Hash)
|
7
|
+
options = browser
|
8
|
+
browser = nil
|
9
|
+
end
|
10
|
+
|
6
11
|
@options = options.dup
|
7
12
|
Watir.logger.info "Creating Browser instance of #{browser} with user provided options: #{@options.inspect}"
|
8
|
-
@browser = if browser == :remote && @options.key?(:browser)
|
9
|
-
@options.delete(:browser)
|
10
|
-
elsif browser == :remote && @options.key?(:desired_capabilities)
|
11
|
-
@options[:desired_capabilities].browser_name.to_sym
|
12
|
-
else
|
13
|
-
browser.to_sym
|
14
|
-
end
|
15
|
-
@selenium_browser = browser == :remote || options[:url] ? :remote : browser
|
16
13
|
|
14
|
+
deprecate_options_capabilities
|
15
|
+
deprecate_desired_capabilities
|
16
|
+
deprecate_url_service if @options.key?(:service) && @options.key?(:url)
|
17
|
+
|
18
|
+
@browser = deprecate_remote(browser) || browser.nil? && infer_browser || browser.to_sym
|
19
|
+
|
20
|
+
@selenium_browser = options[:url] ? :remote : @browser
|
17
21
|
@selenium_opts = {}
|
18
22
|
end
|
19
23
|
|
@@ -24,15 +28,15 @@ module Watir
|
|
24
28
|
private
|
25
29
|
|
26
30
|
def process_arguments
|
27
|
-
url = @options.delete(:url)
|
28
|
-
@selenium_opts[:url] = url if url
|
29
|
-
|
30
|
-
create_http_client
|
31
|
-
|
32
|
-
@selenium_opts[:port] = @options.delete(:port) if @options.key?(:port)
|
33
|
-
@selenium_opts[:driver_opts] = @options.delete(:driver_opts) if @options.key?(:driver_opts)
|
34
31
|
@selenium_opts[:listener] = @options.delete(:listener) if @options.key?(:listener)
|
35
32
|
|
33
|
+
if @options.key?(:url)
|
34
|
+
@selenium_opts[:url] = @options.delete(:url)
|
35
|
+
else
|
36
|
+
process_service(@options.delete(:service))
|
37
|
+
end
|
38
|
+
|
39
|
+
process_http_client
|
36
40
|
process_browser_options
|
37
41
|
process_capabilities
|
38
42
|
Watir.logger.info "Creating Browser instance with Watir processed options: #{@selenium_opts.inspect}"
|
@@ -40,110 +44,254 @@ module Watir
|
|
40
44
|
@selenium_opts
|
41
45
|
end
|
42
46
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
%i[open_timeout read_timeout client_timeout].each do |t|
|
51
|
-
next if http_client.nil? || !respond_to?(t)
|
52
|
-
|
53
|
-
msg = "You can pass #{t} value directly into Watir::Browser opt without needing to use :http_client"
|
54
|
-
Watir.logger.warn msg, ids: %i[http_client use_capabilities]
|
47
|
+
def process_http_client
|
48
|
+
http_client = @options.delete(:http_client) || Watir::HttpClient.new
|
49
|
+
if http_client.is_a?(Hash)
|
50
|
+
http_client = Watir::HttpClient.new(http_client)
|
51
|
+
elsif !http_client.is_a?(Selenium::WebDriver::Remote::Http::Common)
|
52
|
+
raise TypeError, ':http_client must be a Hash or a Selenium HTTP Client instance'
|
55
53
|
end
|
56
54
|
|
57
|
-
http_client
|
55
|
+
unless http_client.is_a?(Watir::HttpClient)
|
56
|
+
Watir.logger.warn 'Check out the new Watir::HttpClient and let us know if there are missing features you need',
|
57
|
+
ids: [:watir_client]
|
58
|
+
end
|
58
59
|
|
59
|
-
http_client
|
60
|
-
http_client.open_timeout = open_timeout if open_timeout
|
61
|
-
http_client.read_timeout = read_timeout if read_timeout
|
60
|
+
process_http_client_timeouts(http_client)
|
62
61
|
@selenium_opts[:http_client] = http_client
|
63
62
|
end
|
64
63
|
|
65
|
-
# TODO: - this will get addressed with Capabilities Update
|
66
|
-
# rubocop:disable Metrics/AbcSize
|
67
|
-
# rubocop:disable Metrics/MethodLength
|
68
|
-
# rubocop:disable Metrics/PerceivedComplexity:
|
69
|
-
# rubocop:disable Metrics/CyclomaticComplexity::
|
70
64
|
def process_browser_options
|
71
65
|
browser_options = @options.delete(:options) || {}
|
66
|
+
process_w3c_capabilities(browser_options)
|
72
67
|
|
73
|
-
case @
|
68
|
+
case @browser
|
74
69
|
when :chrome
|
75
|
-
|
76
|
-
browser_options ||= {}
|
77
|
-
browser_options[:args] = (@options.delete(:args) || @options.delete(:switches)).dup
|
78
|
-
end
|
79
|
-
if @options.delete(:headless)
|
80
|
-
browser_options ||= {}
|
81
|
-
browser_options[:args] ||= []
|
82
|
-
browser_options[:args] += ['--headless', '--disable-gpu']
|
83
|
-
end
|
84
|
-
@selenium_opts[:options] = browser_options if browser_options.is_a? Selenium::WebDriver::Chrome::Options
|
85
|
-
@selenium_opts[:options] ||= Selenium::WebDriver::Chrome::Options.new(browser_options)
|
70
|
+
process_chrome_options(browser_options)
|
86
71
|
when :firefox
|
87
|
-
|
88
|
-
if browser_options.is_a? Selenium::WebDriver::Firefox::Options
|
89
|
-
@selenium_opts[:options] = browser_options
|
90
|
-
if profile
|
91
|
-
msg = 'Initializing Browser with both :profile and :option', ':profile as a key inside :option'
|
92
|
-
Watir.logger.deprecate msg, ids: [:firefox_profile]
|
93
|
-
end
|
94
|
-
end
|
95
|
-
if @options.delete(:headless)
|
96
|
-
browser_options ||= {}
|
97
|
-
browser_options[:args] ||= []
|
98
|
-
browser_options[:args] += ['--headless']
|
99
|
-
end
|
100
|
-
@selenium_opts[:options] ||= Selenium::WebDriver::Firefox::Options.new(browser_options)
|
101
|
-
@selenium_opts[:options].profile = profile if profile
|
72
|
+
process_firefox_options(browser_options)
|
102
73
|
when :safari
|
103
|
-
|
104
|
-
when :
|
105
|
-
|
106
|
-
args = @options.delete(:args) || @options.delete(:switches) || []
|
107
|
-
@options['chromeOptions'] = {'args' => args + ['--headless', '--disable-gpu']}
|
108
|
-
end
|
109
|
-
if @browser == :firefox && @options.delete(:headless)
|
110
|
-
args = @options.delete(:args) || @options.delete(:switches) || []
|
111
|
-
@options[Selenium::WebDriver::Firefox::Options::KEY] = {'args' => args + ['--headless']}
|
112
|
-
end
|
113
|
-
if @browser == :safari && @options.delete(:technology_preview)
|
114
|
-
@options['safari.options'] = {'technologyPreview' => true}
|
115
|
-
end
|
116
|
-
when :ie
|
117
|
-
if @options.key?(:args)
|
118
|
-
browser_options ||= {}
|
119
|
-
browser_options[:args] = @options.delete(:args).dup
|
120
|
-
end
|
121
|
-
unless browser_options.is_a? Selenium::WebDriver::IE::Options
|
122
|
-
ie_caps = browser_options.select { |k| Selenium::WebDriver::IE::Options::CAPABILITIES.include?(k) }
|
123
|
-
browser_options = Selenium::WebDriver::IE::Options.new(browser_options)
|
124
|
-
ie_caps.each { |k, v| browser_options.add_option(k, v) }
|
125
|
-
end
|
126
|
-
@selenium_opts[:options] = browser_options
|
74
|
+
process_safari_options(browser_options)
|
75
|
+
when :ie, :internet_explorer
|
76
|
+
process_ie_options(browser_options)
|
127
77
|
end
|
128
78
|
end
|
129
|
-
# rubocop:enable Metrics/AbcSize
|
130
|
-
# rubocop:enable Metrics/MethodLength
|
131
|
-
# rubocop:enable Metrics/PerceivedComplexity:
|
132
|
-
# rubocop:enable Metrics/CyclomaticComplexity::
|
133
79
|
|
134
80
|
def process_capabilities
|
135
|
-
caps = @options.delete(:
|
81
|
+
caps = @options.delete(:capabilities)
|
82
|
+
|
83
|
+
unless @options.empty?
|
84
|
+
Watir.logger.deprecate('passing unrecognized arguments into Browser constructor',
|
85
|
+
'appropriate keyword to nest all arguments',
|
86
|
+
ids: %i[unknown_keyword capabilities],
|
87
|
+
reference: 'http://watir.com/guides/capabilities.html')
|
88
|
+
end
|
136
89
|
|
137
90
|
if caps
|
138
|
-
msg = 'You can pass values directly into Watir::Browser opt without needing to use :desired_capabilities'
|
139
|
-
Watir.logger.warn msg,
|
140
|
-
ids: [:use_capabilities]
|
141
91
|
@selenium_opts.merge!(@options)
|
142
92
|
else
|
143
|
-
caps = Selenium::WebDriver::Remote::Capabilities.send @browser, @options
|
93
|
+
caps = Selenium::WebDriver::Remote::Capabilities.send @browser, @options.merge(@w3c_caps)
|
144
94
|
end
|
145
95
|
|
146
96
|
@selenium_opts[:desired_capabilities] = caps
|
147
97
|
end
|
98
|
+
|
99
|
+
def deprecate_desired_capabilities
|
100
|
+
return unless @options.key?(:desired_capabilities)
|
101
|
+
|
102
|
+
Watir.logger.deprecate(':desired_capabilities to initialize Browser',
|
103
|
+
':capabilities or preferably :options',
|
104
|
+
ids: [:desired_capabilities],
|
105
|
+
reference: 'http://watir.com/guides/capabilities.html')
|
106
|
+
@options[:capabilities] = @options.delete(:desired_capabilities)
|
107
|
+
end
|
108
|
+
|
109
|
+
def deprecate_url_service
|
110
|
+
Watir.logger.deprecate('allowing Browser initialization with both :url & :service',
|
111
|
+
'just :service',
|
112
|
+
ids: [:url_service],
|
113
|
+
reference: 'http://watir.com/guides/capabilities.html')
|
114
|
+
end
|
115
|
+
|
116
|
+
def process_http_client_timeouts(http_client)
|
117
|
+
deprecate_client_timeout(http_client) if @options.key? :client_timeout
|
118
|
+
deprecate_open_timeout(http_client) if @options.key? :open_timeout
|
119
|
+
deprecate_read_timeout(http_client) if @options.key? :read_timeout
|
120
|
+
end
|
121
|
+
|
122
|
+
def deprecate_client_timeout(http_client)
|
123
|
+
Watir.logger.deprecate(':client_timeout to initialize Browser',
|
124
|
+
':open_timeout and/or :read_timeout in a Hash with :http_client key',
|
125
|
+
ids: [:http_client_timeout],
|
126
|
+
reference: 'http://watir.com/guides/capabilities.html')
|
127
|
+
timeout = @options.delete(:client_timeout)
|
128
|
+
http_client.open_timeout = timeout
|
129
|
+
http_client.read_timeout = timeout
|
130
|
+
end
|
131
|
+
|
132
|
+
def deprecate_open_timeout(http_client)
|
133
|
+
Watir.logger.deprecate(':open_timeout to initialize Browser',
|
134
|
+
':open_timeout in a Hash with :http_client key',
|
135
|
+
ids: %i[http_open_timeout capabilities],
|
136
|
+
reference: 'http://watir.com/guides/capabilities.html')
|
137
|
+
http_client.open_timeout = @options.delete(:open_timeout)
|
138
|
+
end
|
139
|
+
|
140
|
+
def deprecate_read_timeout(http_client)
|
141
|
+
Watir.logger.deprecate(':read_timeout to initialize Browser',
|
142
|
+
':read_timeout in a Hash with :http_client key',
|
143
|
+
ids: %i[http_read_timeout capabilities],
|
144
|
+
reference: 'http://watir.com/guides/capabilities.html')
|
145
|
+
http_client.read_timeout = @options.delete(:read_timeout)
|
146
|
+
end
|
147
|
+
|
148
|
+
def process_chrome_options(browser_options)
|
149
|
+
@selenium_opts[:options] = browser_options if browser_options.is_a? Selenium::WebDriver::Chrome::Options
|
150
|
+
@selenium_opts[:options] ||= Selenium::WebDriver::Chrome::Options.new(**browser_options)
|
151
|
+
|
152
|
+
process_args
|
153
|
+
|
154
|
+
return unless @options.delete(:headless)
|
155
|
+
|
156
|
+
@selenium_opts[:options].args << '--headless'
|
157
|
+
@selenium_opts[:options].args << '--disable-gpu'
|
158
|
+
end
|
159
|
+
|
160
|
+
def process_firefox_options(browser_options)
|
161
|
+
@selenium_opts[:options] = browser_options if browser_options.is_a? Selenium::WebDriver::Firefox::Options
|
162
|
+
|
163
|
+
@selenium_opts[:options] ||= Selenium::WebDriver::Firefox::Options.new(**browser_options)
|
164
|
+
if @options.key?(:profile)
|
165
|
+
new = 'Initializing Browser with both :profile and :option'
|
166
|
+
old = ':profile as a key inside :option'
|
167
|
+
Watir.logger.deprecate new, old, ids: [:firefox_profile]
|
168
|
+
|
169
|
+
@selenium_opts[:options].profile = @options.delete(:profile)
|
170
|
+
end
|
171
|
+
|
172
|
+
@selenium_opts[:options].args << '--headless' if @options.delete(:headless)
|
173
|
+
end
|
174
|
+
|
175
|
+
def process_safari_options(browser_options)
|
176
|
+
@selenium_opts[:options] = browser_options if browser_options.is_a? Selenium::WebDriver::Safari::Options
|
177
|
+
@selenium_opts[:options] ||= Selenium::WebDriver::Safari::Options.new(**browser_options)
|
178
|
+
Selenium::WebDriver::Safari.technology_preview! if @options.delete(:technology_preview)
|
179
|
+
end
|
180
|
+
|
181
|
+
def process_ie_options(browser_options)
|
182
|
+
@selenium_opts[:options] = browser_options if browser_options.is_a? Selenium::WebDriver::IE::Options
|
183
|
+
@selenium_opts[:options] ||= Selenium::WebDriver::IE::Options.new(**browser_options)
|
184
|
+
|
185
|
+
process_args
|
186
|
+
end
|
187
|
+
|
188
|
+
def process_service(service)
|
189
|
+
service = deprecate_service_keywords if service.nil?
|
190
|
+
|
191
|
+
@selenium_opts[:service] = case service
|
192
|
+
when Hash
|
193
|
+
return if service.empty?
|
194
|
+
|
195
|
+
Selenium::WebDriver::Service.send(@browser, service)
|
196
|
+
when Selenium::WebDriver::Service
|
197
|
+
service
|
198
|
+
else
|
199
|
+
raise TypeError, "#{service} needs to be Selenium Service or Hash instance"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def deprecate_service_keywords
|
204
|
+
service = {}
|
205
|
+
if @options.key?(:port)
|
206
|
+
Watir.logger.deprecate(':port to initialize Browser',
|
207
|
+
':port in a Hash with :service key',
|
208
|
+
ids: %i[port_keyword capabilities],
|
209
|
+
reference: 'http://watir.com/guides/capabilities.html')
|
210
|
+
service[:port] = @options.delete(:port)
|
211
|
+
end
|
212
|
+
if @options.key?(:driver_opts)
|
213
|
+
Watir.logger.deprecate(':driver_opts to initialize Browser',
|
214
|
+
':args as Array in a Hash with :service key',
|
215
|
+
ids: %i[driver_opts_keyword capabilities],
|
216
|
+
reference: 'http://watir.com/guides/capabilities.html')
|
217
|
+
service[:args] = @options.delete(:driver_opts)
|
218
|
+
end
|
219
|
+
service
|
220
|
+
end
|
221
|
+
|
222
|
+
def process_args
|
223
|
+
args = if @options.key?(:args)
|
224
|
+
deprecate_args
|
225
|
+
@options.delete(:args)
|
226
|
+
elsif @options.key?(:switches)
|
227
|
+
deprecate_switches
|
228
|
+
@options.delete(:switches)
|
229
|
+
else
|
230
|
+
[]
|
231
|
+
end
|
232
|
+
args.each { |arg| @selenium_opts[:options].args << arg }
|
233
|
+
end
|
234
|
+
|
235
|
+
def deprecate_args
|
236
|
+
Watir.logger.deprecate(':args to initialize Browser',
|
237
|
+
':args inside Hash with :options key',
|
238
|
+
ids: %i[args_keyword capabilities],
|
239
|
+
reference: 'http://watir.com/guides/capabilities.html')
|
240
|
+
end
|
241
|
+
|
242
|
+
def deprecate_switches
|
243
|
+
Watir.logger.deprecate(':switches to initialize Browser',
|
244
|
+
':switches inside Hash with :options key',
|
245
|
+
ids: %i[switches_keyword capabilities],
|
246
|
+
reference: 'http://watir.com/guides/capabilities.html')
|
247
|
+
end
|
248
|
+
|
249
|
+
def deprecate_remote(browser)
|
250
|
+
return unless browser == :remote
|
251
|
+
|
252
|
+
Watir.logger.deprecate(':remote to initialize Browser',
|
253
|
+
'browser key along with remote url',
|
254
|
+
ids: %i[remote_keyword capabilities],
|
255
|
+
reference: 'http://watir.com/guides/capabilities.html')
|
256
|
+
infer_browser
|
257
|
+
end
|
258
|
+
|
259
|
+
def infer_browser
|
260
|
+
if @options.key?(:browser)
|
261
|
+
@options.delete(:browser)
|
262
|
+
elsif @options.key?(:capabilities)
|
263
|
+
@options[:capabilities].browser_name.tr(' ', '_').to_sym
|
264
|
+
elsif @options.key?(:options)
|
265
|
+
@options[:options].class.to_s.split('::')[-2].downcase.to_sym
|
266
|
+
else
|
267
|
+
:chrome
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def process_w3c_capabilities(opts)
|
272
|
+
@w3c_caps = {}
|
273
|
+
return unless opts.is_a?(Hash)
|
274
|
+
|
275
|
+
w3c_keys = %i[browser_version platform_name accept_insecure_certs page_load_strategy proxy set_window_rect
|
276
|
+
timeouts unhandled_prompt_behavior strict_file_interactibility]
|
277
|
+
|
278
|
+
opts.each do |key, _val|
|
279
|
+
next unless key.to_s.include?(':') || w3c_keys.include?(key)
|
280
|
+
|
281
|
+
@w3c_caps[key] = opts.delete(key)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def deprecate_options_capabilities
|
286
|
+
return unless @options.key?(:capabilities) && @options.key?(:options)
|
287
|
+
|
288
|
+
old = 'initializing Browser with both options and capabilities'
|
289
|
+
new = 'Hash with :options, Selenium Options instance with :options or' \
|
290
|
+
'Selenium Capabilities instance with :capabilities'
|
291
|
+
Watir.logger.deprecate(old,
|
292
|
+
new,
|
293
|
+
ids: %i[options_capabilities capabilities],
|
294
|
+
reference: 'http://watir.com/guides/capabilities.html')
|
295
|
+
end
|
148
296
|
end
|
149
297
|
end
|