watir 6.18.0 → 6.19.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29eeb6548d5f5f91ee744107d1e3c79f0d2baf8b688c9588752e25b75fa696ef
4
- data.tar.gz: 27502c2b89585471b25751b5564c08784578585d3c196f132f56b52243645735
3
+ metadata.gz: 249f59d4a6bd6bff5ddd7e49d32e2cc5a3ecd887586de1a41d51aecc37c6946a
4
+ data.tar.gz: 407024609aa1b7e0eb052ecbcc279ebdfcb6e486e326ee8f1dd0994b79f4be75
5
5
  SHA512:
6
- metadata.gz: d2a90695c68c0db0493d1fdeac5ab90ab51604a0916b4b6cbf0abeae595c6680f62269da98b9920c7ee7db4448e70c6afe31caa280ae76234bae2fc0b51c2912
7
- data.tar.gz: 645305ed2b0ae8b5777995c6620055e37850dcefdb3b5a5b609d98b4ce30f8d0cd14155a79fb2032a46862d8c10ad92e9c0112fc7fe68e31dac01b6da44cbbd9
6
+ metadata.gz: f89c38c9bd61bef959ebb41672e729be867ad7991530f6f432dddae7900db15c31dfd717d413cc500f5f2708a3ce500b3d9687091d603ca4e4acbfbbc5af20cc
7
+ data.tar.gz: 34f9dc6a5e675c734c4a2e5e5c234695204b23ba887268f523c95d72f33a0b5b02c843fcd61033592c8e937b721d86bc80b790e9b06c4c9ca4d03f7b55df7357
@@ -18,7 +18,13 @@ jobs:
18
18
  with:
19
19
  ruby-version: ${{ matrix.ruby }}
20
20
  - run: bundle install
21
- - run: bundle exec rake spec:unit
21
+ - uses: ./.github/actions/install-chrome
22
+ - run: Xvfb :99 &
23
+ - run: |
24
+ bundle exec rake spec:unit
25
+ env:
26
+ DISPLAY: :99
27
+
22
28
  linter-test:
23
29
  name: Rubocop Tests
24
30
  runs-on: ubuntu-latest
data/CHANGES.md CHANGED
@@ -1,3 +1,20 @@
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
+
1
18
  ### 6.18.0 (2021-02-26)
2
19
 
3
20
  * Implement `WindowCollection` to manage multiple `Window` objects
data/README.md CHANGED
@@ -3,12 +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
- [![Unit Tests](https://github.com/titusfortner/watir/workflows/Unit%20Tests/badge.svg)](https://github.com/watir/watir/actions?query=workflow%3A%22Unit+Tests%22)
7
- [![Mac Tests](https://github.com/titusfortner/watir/workflows/Mac%20Tests/badge.svg)](https://github.com/watir/watir/actions?query=workflow%3A%22Mac+Tests%22)
8
- [![Windows Tests](https://github.com/titusfortner/watir/workflows/Windows%20Tests/badge.svg)](https://github.com/watir/watir/actions?query=workflow%3A%22Windows+Tests%22)
9
- [![Linux Tests](https://github.com/titusfortner/watir/workflows/Linux%20Tests/badge.svg)](https://github.com/watir/watir/actions?query=workflow%3A%22Linux+Tests%22)
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)
10
10
  [![Code Climate](https://codeclimate.com/github/watir/watir.svg)](https://codeclimate.com/github/watir/watir)
11
- [![Coverage Status](https://coveralls.io/repos/github/watir/watir/badge.svg?branch=main)](https://coveralls.io/github/watir/watir?branch=master)
11
+ [![Coverage Status](https://coveralls.io/repos/github/watir/watir/badge.svg?branch=main)](https://coveralls.io/github/watir/watir?branch=main)
12
12
 
13
13
  ## Using Watir
14
14
 
data/lib/watir.rb CHANGED
@@ -14,12 +14,14 @@ require 'watir/alert'
14
14
  require 'watir/js_snippets'
15
15
  require 'watir/container'
16
16
  require 'watir/cookies'
17
+ require 'watir/http_client'
17
18
  require 'watir/capabilities'
18
19
  require 'watir/navigation'
19
20
  require 'watir/browser'
20
21
  require 'watir/screenshot'
21
22
  require 'watir/after_hooks'
22
23
  require 'watir/logger'
24
+ require 'watir/version'
23
25
 
24
26
  module Watir
25
27
  @relaxed_locate = true
@@ -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,19 +28,15 @@ module Watir
24
28
  private
25
29
 
26
30
  def process_arguments
27
- url = @options.delete(:url)
28
- if url
29
- @selenium_opts[:url] = url
30
- elsif @options.key?(:service)
31
- @selenium_opts[:service] = options.delete(:service)
32
- end
33
-
34
- create_http_client
35
-
36
- @selenium_opts[:port] = @options.delete(:port) if @options.key?(:port)
37
- @selenium_opts[:driver_opts] = @options.delete(:driver_opts) if @options.key?(:driver_opts)
38
31
  @selenium_opts[:listener] = @options.delete(:listener) if @options.key?(:listener)
39
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
40
40
  process_browser_options
41
41
  process_capabilities
42
42
  Watir.logger.info "Creating Browser instance with Watir processed options: #{@selenium_opts.inspect}"
@@ -44,109 +44,254 @@ module Watir
44
44
  @selenium_opts
45
45
  end
46
46
 
47
- def create_http_client
48
- client_timeout = @options.delete(:client_timeout)
49
- open_timeout = @options.delete(:open_timeout)
50
- read_timeout = @options.delete(:read_timeout)
51
-
52
- http_client = @options.delete(:http_client)
53
-
54
- %i[open_timeout read_timeout client_timeout].each do |t|
55
- next if http_client.nil? || !respond_to?(t)
56
-
57
- msg = "You can pass #{t} value directly into Watir::Browser opt without needing to use :http_client"
58
- 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'
59
53
  end
60
54
 
61
- http_client ||= Selenium::WebDriver::Remote::Http::Default.new
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
62
59
 
63
- http_client.timeout = client_timeout if client_timeout
64
- http_client.open_timeout = open_timeout if open_timeout
65
- http_client.read_timeout = read_timeout if read_timeout
60
+ process_http_client_timeouts(http_client)
66
61
  @selenium_opts[:http_client] = http_client
67
62
  end
68
63
 
69
- # TODO: - this will get addressed with Capabilities Update
70
- # rubocop:disable Metrics/MethodLength
71
- # rubocop:disable Metrics/PerceivedComplexity:
72
- # rubocop:disable Metrics/CyclomaticComplexity::
73
64
  def process_browser_options
74
65
  browser_options = @options.delete(:options) || {}
66
+ process_w3c_capabilities(browser_options)
75
67
 
76
- case @selenium_browser
68
+ case @browser
77
69
  when :chrome
78
- if @options.key?(:args) || @options.key?(:switches)
79
- browser_options ||= {}
80
- browser_options[:args] = (@options.delete(:args) || @options.delete(:switches)).dup
81
- end
82
- if @options.delete(:headless)
83
- browser_options ||= {}
84
- browser_options[:args] ||= []
85
- browser_options[:args] += ['--headless', '--disable-gpu']
86
- end
87
- @selenium_opts[:options] = browser_options if browser_options.is_a? Selenium::WebDriver::Chrome::Options
88
- @selenium_opts[:options] ||= Selenium::WebDriver::Chrome::Options.new(**browser_options)
70
+ process_chrome_options(browser_options)
89
71
  when :firefox
90
- profile = @options.delete(:profile)
91
- if browser_options.is_a? Selenium::WebDriver::Firefox::Options
92
- @selenium_opts[:options] = browser_options
93
- if profile
94
- msg = 'Initializing Browser with both :profile and :option', ':profile as a key inside :option'
95
- Watir.logger.deprecate msg, ids: [:firefox_profile]
96
- end
97
- end
98
- if @options.delete(:headless)
99
- browser_options ||= {}
100
- browser_options[:args] ||= []
101
- browser_options[:args] += ['--headless']
102
- end
103
- @selenium_opts[:options] ||= Selenium::WebDriver::Firefox::Options.new(**browser_options)
104
- @selenium_opts[:options].profile = profile if profile
72
+ process_firefox_options(browser_options)
105
73
  when :safari
106
- Selenium::WebDriver::Safari.technology_preview! if @options.delete(:technology_preview)
107
- when :remote
108
- if @browser == :chrome && @options.delete(:headless)
109
- args = @options.delete(:args) || @options.delete(:switches) || []
110
- @options['chromeOptions'] = {'args' => args + ['--headless', '--disable-gpu']}
111
- end
112
- if @browser == :firefox && @options.delete(:headless)
113
- args = @options.delete(:args) || @options.delete(:switches) || []
114
- @options[Selenium::WebDriver::Firefox::Options::KEY] = {'args' => args + ['--headless']}
115
- end
116
- if @browser == :safari && @options.delete(:technology_preview)
117
- @options['safari.options'] = {'technologyPreview' => true}
118
- end
119
- when :ie
120
- if @options.key?(:args)
121
- browser_options ||= {}
122
- browser_options[:args] = @options.delete(:args).dup
123
- end
124
- unless browser_options.is_a? Selenium::WebDriver::IE::Options
125
- ie_caps = browser_options.select { |k| Selenium::WebDriver::IE::Options::CAPABILITIES.include?(k) }
126
- browser_options = Selenium::WebDriver::IE::Options.new(**browser_options)
127
- ie_caps.each { |k, v| browser_options.add_option(k, v) }
128
- end
129
- @selenium_opts[:options] = browser_options
74
+ process_safari_options(browser_options)
75
+ when :ie, :internet_explorer
76
+ process_ie_options(browser_options)
130
77
  end
131
78
  end
132
79
 
133
- # rubocop:enable Metrics/MethodLength
134
- # rubocop:enable Metrics/PerceivedComplexity:
135
- # rubocop:enable Metrics/CyclomaticComplexity::
136
-
137
80
  def process_capabilities
138
- caps = @options.delete(:desired_capabilities)
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
139
89
 
140
90
  if caps
141
- msg = 'You can pass values directly into Watir::Browser opt without needing to use :desired_capabilities'
142
- Watir.logger.warn msg,
143
- ids: [:use_capabilities]
144
91
  @selenium_opts.merge!(@options)
145
92
  else
146
- caps = Selenium::WebDriver::Remote::Capabilities.send @browser, @options
93
+ caps = Selenium::WebDriver::Remote::Capabilities.send @browser, @options.merge(@w3c_caps)
147
94
  end
148
95
 
149
96
  @selenium_opts[:desired_capabilities] = caps
150
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
151
296
  end
152
297
  end