watir 6.19.0 → 7.0.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/.github/actions/install-chrome/action.yml +1 -0
  3. data/.github/actions/setup-linux/action.yml +8 -0
  4. data/.github/workflows/tests.yml +104 -0
  5. data/.rubocop.yml +2 -7
  6. data/CHANGES.md +38 -0
  7. data/README.md +1 -4
  8. data/Rakefile +1 -1
  9. data/lib/watir.rb +1 -45
  10. data/lib/watir/alert.rb +3 -8
  11. data/lib/watir/browser.rb +18 -4
  12. data/lib/watir/capabilities.rb +79 -224
  13. data/lib/watir/cell_container.rb +4 -4
  14. data/lib/watir/container.rb +4 -26
  15. data/lib/watir/elements/checkbox.rb +4 -4
  16. data/lib/watir/elements/date_field.rb +4 -4
  17. data/lib/watir/elements/date_time_field.rb +4 -4
  18. data/lib/watir/elements/element.rb +44 -52
  19. data/lib/watir/elements/file_field.rb +4 -4
  20. data/lib/watir/elements/font.rb +5 -4
  21. data/lib/watir/elements/hidden.rb +4 -4
  22. data/lib/watir/elements/html_elements.rb +444 -445
  23. data/lib/watir/elements/iframe.rb +4 -5
  24. data/lib/watir/elements/radio.rb +6 -6
  25. data/lib/watir/elements/select.rb +60 -103
  26. data/lib/watir/elements/svg_elements.rb +96 -96
  27. data/lib/watir/elements/text_field.rb +4 -4
  28. data/lib/watir/generator/base/generator.rb +4 -4
  29. data/lib/watir/generator/base/visitor.rb +0 -29
  30. data/lib/watir/generator/html/generator.rb +2 -1
  31. data/lib/watir/has_window.rb +6 -4
  32. data/lib/watir/http_client.rb +0 -8
  33. data/lib/watir/locators.rb +5 -5
  34. data/lib/watir/locators/button/matcher.rb +0 -23
  35. data/lib/watir/locators/button/selector_builder/xpath.rb +4 -15
  36. data/lib/watir/locators/element/matcher.rb +4 -19
  37. data/lib/watir/locators/element/selector_builder.rb +2 -40
  38. data/lib/watir/locators/element/selector_builder/xpath.rb +36 -42
  39. data/lib/watir/locators/option/matcher.rb +24 -0
  40. data/lib/watir/locators/option/selector_builder.rb +8 -0
  41. data/lib/watir/locators/option/selector_builder/xpath.rb +37 -0
  42. data/lib/watir/logger.rb +3 -74
  43. data/lib/watir/radio_set.rb +3 -2
  44. data/lib/watir/row_container.rb +4 -4
  45. data/lib/watir/screenshot.rb +2 -8
  46. data/lib/watir/user_editable.rb +10 -3
  47. data/lib/watir/version.rb +1 -1
  48. data/lib/watir/wait.rb +4 -74
  49. data/lib/watir/window.rb +21 -26
  50. data/lib/watir/window_collection.rb +14 -49
  51. data/lib/watirspec.rb +4 -2
  52. data/lib/watirspec/guards.rb +1 -1
  53. data/lib/watirspec/implementation.rb +4 -0
  54. data/lib/watirspec/server.rb +1 -1
  55. data/spec/spec_helper.rb +1 -16
  56. data/spec/unit/capabilities_spec.rb +247 -924
  57. data/spec/unit/match_elements/button_spec.rb +0 -13
  58. data/spec/unit/match_elements/element_spec.rb +49 -47
  59. data/spec/unit/match_elements/text_field_spec.rb +6 -6
  60. data/spec/unit/selector_builder/element_spec.rb +6 -23
  61. data/spec/unit/selector_builder/text_field_spec.rb +6 -7
  62. data/spec/watirspec/after_hooks_spec.rb +22 -45
  63. data/spec/watirspec/alert_spec.rb +4 -21
  64. data/spec/watirspec/browser_spec.rb +186 -207
  65. data/spec/watirspec/cookies_spec.rb +47 -52
  66. data/spec/watirspec/drag_and_drop_spec.rb +5 -7
  67. data/spec/watirspec/elements/area_spec.rb +1 -5
  68. data/spec/watirspec/elements/button_spec.rb +4 -18
  69. data/spec/watirspec/elements/checkbox_spec.rb +10 -24
  70. data/spec/watirspec/elements/date_field_spec.rb +13 -16
  71. data/spec/watirspec/elements/date_time_field_spec.rb +14 -13
  72. data/spec/watirspec/elements/dd_spec.rb +3 -4
  73. data/spec/watirspec/elements/del_spec.rb +10 -12
  74. data/spec/watirspec/elements/div_spec.rb +45 -84
  75. data/spec/watirspec/elements/divs_spec.rb +2 -2
  76. data/spec/watirspec/elements/dl_spec.rb +4 -12
  77. data/spec/watirspec/elements/element_spec.rb +190 -170
  78. data/spec/watirspec/elements/elements_spec.rb +8 -9
  79. data/spec/watirspec/elements/filefield_spec.rb +5 -7
  80. data/spec/watirspec/elements/form_spec.rb +3 -5
  81. data/spec/watirspec/elements/forms_spec.rb +3 -5
  82. data/spec/watirspec/elements/frame_spec.rb +17 -22
  83. data/spec/watirspec/elements/iframe_spec.rb +21 -27
  84. data/spec/watirspec/elements/ins_spec.rb +10 -12
  85. data/spec/watirspec/elements/link_spec.rb +24 -26
  86. data/spec/watirspec/elements/links_spec.rb +8 -9
  87. data/spec/watirspec/elements/radio_spec.rb +11 -14
  88. data/spec/watirspec/elements/select_list_spec.rb +253 -223
  89. data/spec/watirspec/elements/span_spec.rb +12 -14
  90. data/spec/watirspec/elements/spans_spec.rb +1 -1
  91. data/spec/watirspec/elements/strong_spec.rb +1 -1
  92. data/spec/watirspec/elements/table_nesting_spec.rb +31 -34
  93. data/spec/watirspec/elements/table_spec.rb +11 -13
  94. data/spec/watirspec/elements/tbody_spec.rb +10 -12
  95. data/spec/watirspec/elements/td_spec.rb +4 -6
  96. data/spec/watirspec/elements/text_field_spec.rb +10 -12
  97. data/spec/watirspec/elements/tr_spec.rb +5 -7
  98. data/spec/watirspec/html/non_control_elements.html +8 -3
  99. data/spec/watirspec/html/special_chars.html +3 -0
  100. data/spec/watirspec/special_chars_spec.rb +10 -0
  101. data/spec/watirspec/support/rspec_matchers.rb +1 -32
  102. data/spec/watirspec/user_editable_spec.rb +26 -28
  103. data/spec/watirspec/wait_spec.rb +255 -258
  104. data/spec/watirspec/window_switching_spec.rb +208 -247
  105. data/spec/watirspec_helper.rb +40 -32
  106. data/watir.gemspec +3 -4
  107. metadata +16 -38
  108. data/.github/workflows/linux.yml +0 -61
  109. data/.github/workflows/mac.yml +0 -55
  110. data/.github/workflows/unit.yml +0 -37
  111. data/.github/workflows/windows.yml +0 -39
  112. data/lib/watir/legacy_wait.rb +0 -123
  113. data/spec/implementation_spec.rb +0 -24
  114. data/spec/unit/container_spec.rb +0 -35
  115. data/spec/unit/logger_spec.rb +0 -81
  116. data/spec/watirspec/legacy_wait_spec.rb +0 -216
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 249f59d4a6bd6bff5ddd7e49d32e2cc5a3ecd887586de1a41d51aecc37c6946a
4
- data.tar.gz: 407024609aa1b7e0eb052ecbcc279ebdfcb6e486e326ee8f1dd0994b79f4be75
3
+ metadata.gz: 84196be031b435273f620aea6539dfb373602174b861fe624faf8591b3a803b6
4
+ data.tar.gz: 934de2c077de5657f76fdbc7dc4f6c8c4b9408f278b644b9e01b5c5b7f8d401b
5
5
  SHA512:
6
- metadata.gz: f89c38c9bd61bef959ebb41672e729be867ad7991530f6f432dddae7900db15c31dfd717d413cc500f5f2708a3ce500b3d9687091d603ca4e4acbfbbc5af20cc
7
- data.tar.gz: 34f9dc6a5e675c734c4a2e5e5c234695204b23ba887268f523c95d72f33a0b5b02c843fcd61033592c8e937b721d86bc80b790e9b06c4c9ca4d03f7b55df7357
6
+ metadata.gz: 8f51aeb6d0f69bf20150a689b4e29ba5fb6217abd735e9a18c9917ce60dab6810a3d43b10581ae19fb85b23e7231a1cd541fdfd255cc17a80a58c78f308973a6
7
+ data.tar.gz: 5130d9bc13f3ac40b247756d009813c6cb99584e6744a1f883b3beede4a51099a778549e6e9a15f273784aed5fe1849ac384161947e38dfc770deef0b051ec45
@@ -1,4 +1,5 @@
1
1
  name: 'Install Chrome'
2
+ description: 'Install Chrome Stable'
2
3
  runs:
3
4
  using: "composite"
4
5
  steps:
@@ -0,0 +1,8 @@
1
+ name: 'Setup Linux'
2
+ description: 'Run Linux in Virtual Desktop'
3
+ runs:
4
+ using: "composite"
5
+ steps:
6
+ - shell: bash
7
+ run: |
8
+ Xvfb :99 &
@@ -0,0 +1,104 @@
1
+ name: All Tests
2
+
3
+ on:
4
+ - push
5
+ - pull_request
6
+
7
+ jobs:
8
+ documentation-test:
9
+ name: Yard Doctest
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - uses: ruby/setup-ruby@v1
14
+ with:
15
+ ruby-version: 2.6
16
+ - run: bundle install
17
+ - uses: ./.github/actions/install-chrome
18
+ - uses: ./.github/actions/setup-linux
19
+ - run: |
20
+ bundle exec rake yard:doctest
21
+
22
+ unit-test:
23
+ name: Unit Tests
24
+ runs-on: ubuntu-latest
25
+ strategy:
26
+ fail-fast: false
27
+ matrix:
28
+ ruby: ['2.5', '2.6', '2.7', '3.0']
29
+ steps:
30
+ - uses: actions/checkout@v2
31
+ - uses: ruby/setup-ruby@v1
32
+ with:
33
+ ruby-version: ${{ matrix.ruby }}
34
+ - run: bundle install
35
+ - uses: ./.github/actions/install-chrome
36
+ - uses: ./.github/actions/setup-linux
37
+ - run: |
38
+ bundle exec rake spec:unit
39
+ env:
40
+ DISPLAY: :99
41
+
42
+ linter-test:
43
+ name: Rubocop Tests
44
+ runs-on: ubuntu-latest
45
+ steps:
46
+ - uses: actions/checkout@v2
47
+ - uses: ruby/setup-ruby@v1
48
+ with:
49
+ ruby-version: 2.6
50
+ - run: bundle install
51
+ - run: bundle exec rubocop
52
+
53
+ local-tests:
54
+ name: Local Tests
55
+ runs-on: ${{ matrix.os }}
56
+ strategy:
57
+ fail-fast: false
58
+ matrix:
59
+ os: [ubuntu-latest, macos-latest, windows-latest]
60
+ ruby: [ 2.6, 3.0 ]
61
+ task: [ chrome, firefox, edge ]
62
+ include:
63
+ - os: 'macos-latest'
64
+ ruby: 2.6
65
+ task: 'safari'
66
+ - os: 'macos-latest'
67
+ ruby: 3.0
68
+ task: 'safari'
69
+ - os: 'windows-latest'
70
+ ruby: 2.6
71
+ task: 'ie'
72
+ - os: 'windows-latest'
73
+ ruby: 3.0
74
+ task: 'ie'
75
+ exclude:
76
+ - os: 'ubuntu-latest'
77
+ task: 'edge'
78
+ steps:
79
+ - uses: actions/checkout@v2
80
+ - uses: ./.github/actions/install-chrome
81
+ if: |
82
+ matrix.task == 'chrome' &&
83
+ matrix.os == 'ubuntu-latest'
84
+ - uses: ./.github/actions/setup-linux
85
+ if: matrix.os == 'ubuntu-latest'
86
+ - uses: browser-actions/setup-firefox@latest
87
+ with:
88
+ firefox-version: '86.0'
89
+ if: matrix.task == 'firefox'
90
+ - uses: ./.github/actions/enable-safari
91
+ if: matrix.task == 'safari'
92
+ - run: |
93
+ echo "COVERAGE=true" >> $GITHUB_ENV
94
+ if: |
95
+ matrix.os == 'ubuntu-latest' ||
96
+ matrix.os == 'macos-latest'
97
+ - uses: ruby/setup-ruby@v1
98
+ with:
99
+ ruby-version: ${{ matrix.ruby }}
100
+ - run: bundle install
101
+ - run: |
102
+ bundle exec rake spec:${{ matrix.task }}
103
+ env:
104
+ DISPLAY: :99
data/.rubocop.yml CHANGED
@@ -19,17 +19,12 @@ Lint/UnifiedInteger:
19
19
 
20
20
  # Default: 17
21
21
  Metrics/AbcSize:
22
- Max: 20
22
+ Max: 22
23
23
  Exclude:
24
- - 'lib/watir/capabilities.rb'
25
24
  - 'lib/watir/locators/element/selector_builder.rb'
26
- - 'lib/watir/locators/element/selector_builder/regexp_disassembler.rb'
27
- - 'lib/watir/locators/element/selector_builder/xpath.rb'
28
- - 'lib/watir/locators/element/locator.rb'
25
+ - 'lib/watir/locators/element/selector_builder/*.rb'
29
26
  - 'lib/watir/generator/base/generator.rb'
30
- - 'lib/watir/generator/base/visitor.rb'
31
27
  - 'spec/locator_spec_helper.rb'
32
- - 'spec/watirspec_helper.rb'
33
28
 
34
29
  Metrics/BlockLength:
35
30
  Exclude:
data/CHANGES.md CHANGED
@@ -1,3 +1,41 @@
1
+ ### 7.0.0.beta4 (2021-05-29)
2
+
3
+ * Fix Bug in using negative class names within a collection (#934)
4
+
5
+ ### 7.0.0.beta3 (2021-05-05)
6
+
7
+ * Fix Bug preventing proper use of vendor extension capabilities
8
+ * Changed how timeouts are supported in Watir Capabilities (#932)
9
+ * Changed the default Alert Behavior not to automatically get dismissed when an exception happens (#931)
10
+
11
+ ### 7.0.0.beta2 (2021-03-28)
12
+
13
+ * Replace Watir Logger implementation with Selenium Logger subclass
14
+ * Change Watir Guards to use Selenium's new Guards. Tests run as pending when guarded.
15
+ * Implement `#set` as standard interface for each Input Element (#405)
16
+ * Implement `Element#set` to take correct `#set` behavior based on evaluated element (#664)
17
+ * Optimize Performance for Select Lists (#846)
18
+ * Allow user to set values on Select List exclusively by `:label`, `:text`, or `:value` (#846)
19
+ * Allow user to check if option selected in Select List by `:label`, `:text`, or `:value` (#929)
20
+ * Implement `Window#restore!` to return to original Window and close all others (#923)
21
+ * Minor performance improvement for iterating over windows (#923)
22
+ * Implement `Browser#closed?`; same as `Browser#exists?` without the Windows checks (#923)
23
+ * Update methods that use Selenium's Actions class to scroll element into view before acting (#847)
24
+ * Fix bug for `:text` locator with `Regexp` value based on whitespace (#924)
25
+ * Remove executing after hooks when changing frames (#888)
26
+
27
+ ### 7.0.0.beta1 (2021-03-18)
28
+
29
+ * Requires Selenium 4
30
+ * Supports Ruby 3
31
+ * Add support for Microsoft Edge Chromium
32
+ * Remove support for all deprecated functionality
33
+
34
+ ### 6.19.1 (2021-03-17)
35
+
36
+ * Fix bug preventing using Selenium 4
37
+ * Fix bug preventing non-xml characters in attributes (#787)
38
+
1
39
  ### 6.19.0 (2021-03-12)
2
40
 
3
41
  * Create custom Watir HTTP Client
data/README.md CHANGED
@@ -3,10 +3,7 @@
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/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)
6
+ [![All Tests](https://github.com/watir/watir/actions/workflows/tests.yml/badge.svg)](https://github.com/watir/watir/actions/workflows/tests.yml)
10
7
  [![Code Climate](https://codeclimate.com/github/watir/watir.svg)](https://codeclimate.com/github/watir/watir)
11
8
  [![Coverage Status](https://coveralls.io/repos/github/watir/watir/badge.svg?branch=main)](https://coveralls.io/github/watir/watir?branch=main)
12
9
 
data/Rakefile CHANGED
@@ -25,7 +25,7 @@ end
25
25
 
26
26
  {
27
27
  html: 'https://www.w3.org/TR/html52/single-page.html',
28
- svg: 'http://www.w3.org/TR/SVG2/single-page.html'
28
+ svg: 'https://www.w3.org/TR/2018/CR-SVG2-20180807/single-page.html'
29
29
  }.each do |type, spec_uri|
30
30
  namespace type do
31
31
  spec_path = "support/#{type}.html"
data/lib/watir.rb CHANGED
@@ -2,7 +2,6 @@ require 'selenium-webdriver'
2
2
  require 'time'
3
3
 
4
4
  require 'watir/scroll'
5
- require 'watir/legacy_wait'
6
5
  require 'watir/wait'
7
6
  require 'watir/exception'
8
7
  require 'watir/window'
@@ -24,51 +23,8 @@ require 'watir/logger'
24
23
  require 'watir/version'
25
24
 
26
25
  module Watir
27
- @relaxed_locate = true
28
-
29
26
  class << self
30
- attr_writer :relaxed_locate, :always_locate, :default_timeout, :prefer_css
31
-
32
- #
33
- # Whether or not Watir should wait for an element to be found or present
34
- # before taking an action.
35
- # Defaults to true.
36
- #
37
-
38
- def relaxed_locate?
39
- @relaxed_locate
40
- end
41
-
42
- #
43
- # Whether or not Watir should re-locate a stale Element on use.
44
- #
45
-
46
- def always_locate?
47
- always_locate_message
48
- true
49
- end
50
-
51
- def always_locate_message
52
- msg = 'Watir#always_locate'
53
- repl_msg = 'Element#stale? or Element#wait_until(&:stale?) if needed for flow control'
54
- Watir.logger.deprecate msg, repl_msg, ids: [:always_locate]
55
- end
56
-
57
- #
58
- # Whether or not Watir should prefer CSS when translating the Watir selector to Selenium.
59
- #
60
-
61
- def prefer_css?
62
- prefer_css_message
63
- false
64
- end
65
-
66
- def prefer_css_message
67
- msg = 'Watir#prefer_css'
68
- repl_msg = 'watir_css gem - https://github.com/watir/watir_css'
69
-
70
- Watir.logger.deprecate msg, repl_msg, ids: [:prefer_css]
71
- end
27
+ attr_writer :default_timeout
72
28
 
73
29
  #
74
30
  # Default wait time for wait methods.
data/lib/watir/alert.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  module Watir
2
2
  class Alert
3
- include EventuallyPresent
4
3
  include Waitable
5
4
  include Exception
6
5
 
@@ -104,13 +103,9 @@ module Watir
104
103
  end
105
104
 
106
105
  def wait_for_exists
107
- return assert_exists unless Watir.relaxed_locate?
108
-
109
- begin
110
- wait_until(message: 'waiting for alert', &:exists?)
111
- rescue Wait::TimeoutError
112
- raise UnknownObjectException, 'unable to locate alert'
113
- end
106
+ wait_until(message: 'waiting for alert', &:exists?)
107
+ rescue Wait::TimeoutError
108
+ raise UnknownObjectException, 'unable to locate alert'
114
109
  end
115
110
  end # Alert
116
111
  end # Watir
data/lib/watir/browser.rb CHANGED
@@ -55,16 +55,21 @@ module Watir
55
55
  @default_context = true
56
56
  end
57
57
 
58
+ # rubocop:disable Metrics/AbcSize
59
+ # TODO: w3c default behavior does not like checking if alert exists
58
60
  def inspect
59
61
  if alert.exists?
60
62
  format('#<%s:0x%x alert=true>', self.class, hash * 2)
61
63
  else
62
64
  format('#<%s:0x%x url=%s title=%s>', self.class, hash * 2, url.inspect, title.inspect)
63
65
  end
66
+ rescue Selenium::WebDriver::Error::NoSuchWindowError
67
+ format('#<%s:0x%x closed=%s>', self.class, hash * 2, closed?)
64
68
  rescue Errno::ECONNREFUSED
65
69
  format('#<%s:0x%x closed=true>', self.class, hash * 2)
66
70
  end
67
71
  alias selector_string inspect
72
+ # rubocop:enable Metrics/AbcSize
68
73
 
69
74
  #
70
75
  # Returns URL of current page.
@@ -101,13 +106,23 @@ module Watir
101
106
  #
102
107
 
103
108
  def close
104
- return if @closed
109
+ return if closed?
105
110
 
106
111
  @driver.quit
107
112
  @closed = true
108
113
  end
109
114
  alias quit close
110
115
 
116
+ #
117
+ # Returns true if browser is closed and false otherwise.
118
+ #
119
+ # @return [Boolean]
120
+ #
121
+
122
+ def closed?
123
+ @closed
124
+ end
125
+
111
126
  #
112
127
  # Handles cookies.
113
128
  #
@@ -252,12 +267,12 @@ module Watir
252
267
  #
253
268
 
254
269
  def exist?
255
- !@closed && window.present?
270
+ !closed? && window.present?
256
271
  end
257
272
  alias exists? exist?
258
273
 
259
274
  def locate
260
- raise Error, 'browser was closed' if @closed
275
+ raise Error, 'browser was closed' if closed?
261
276
 
262
277
  ensure_context
263
278
  end
@@ -267,7 +282,6 @@ module Watir
267
282
 
268
283
  driver.switch_to.default_content
269
284
  @default_context = true
270
- after_hooks.run
271
285
  end
272
286
 
273
287
  def browser
@@ -11,14 +11,14 @@ module Watir
11
11
  @options = options.dup
12
12
  Watir.logger.info "Creating Browser instance of #{browser} with user provided options: #{@options.inspect}"
13
13
 
14
- deprecate_options_capabilities
15
- deprecate_desired_capabilities
16
- deprecate_url_service if @options.key?(:service) && @options.key?(:url)
14
+ if @options.key?(:capabilities) && @options.key?(:options)
15
+ raise(ArgumentError, ':capabilities and :options are not both allowed')
16
+ end
17
+ raise(ArgumentError, ':url and :service are not both allowed') if @options.key?(:service) && @options.key?(:url)
17
18
 
18
- @browser = deprecate_remote(browser) || browser.nil? && infer_browser || browser.to_sym
19
+ @browser = browser.nil? && infer_browser || browser
19
20
 
20
- @selenium_browser = options[:url] ? :remote : @browser
21
- @selenium_opts = {}
21
+ @selenium_browser = @options.key?(:url) ? :remote : @browser
22
22
  end
23
23
 
24
24
  def to_args
@@ -28,270 +28,125 @@ module Watir
28
28
  private
29
29
 
30
30
  def process_arguments
31
- @selenium_opts[:listener] = @options.delete(:listener) if @options.key?(:listener)
31
+ selenium_opts = {}
32
+ selenium_opts[:listener] = @options.delete(:listener) if @options.key?(:listener)
32
33
 
33
34
  if @options.key?(:url)
34
- @selenium_opts[:url] = @options.delete(:url)
35
+ selenium_opts[:url] = @options.delete(:url)
35
36
  else
36
- process_service(@options.delete(:service))
37
+ service = process_service
38
+ selenium_opts[:service] = service if service
37
39
  end
38
40
 
39
- process_http_client
40
- process_browser_options
41
- process_capabilities
42
- Watir.logger.info "Creating Browser instance with Watir processed options: #{@selenium_opts.inspect}"
41
+ selenium_opts[:http_client] = process_http_client
42
+ selenium_opts[:capabilities] = @options.delete(:capabilities) || process_browser_options
43
43
 
44
- @selenium_opts
44
+ Watir.logger.info "Creating Browser instance with Watir processed options: #{selenium_opts.inspect}"
45
+ selenium_opts
45
46
  end
46
47
 
47
48
  def process_http_client
48
49
  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'
53
- end
54
50
 
55
- unless http_client.is_a?(Watir::HttpClient)
51
+ case http_client
52
+ when Hash
53
+ Watir::HttpClient.new(**http_client)
54
+ when Watir::HttpClient
55
+ http_client
56
+ when Selenium::WebDriver::Remote::Http::Common
56
57
  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
59
-
60
- process_http_client_timeouts(http_client)
61
- @selenium_opts[:http_client] = http_client
62
- end
63
-
64
- def process_browser_options
65
- browser_options = @options.delete(:options) || {}
66
- process_w3c_capabilities(browser_options)
67
-
68
- case @browser
69
- when :chrome
70
- process_chrome_options(browser_options)
71
- when :firefox
72
- process_firefox_options(browser_options)
73
- when :safari
74
- process_safari_options(browser_options)
75
- when :ie, :internet_explorer
76
- process_ie_options(browser_options)
77
- end
78
- end
79
-
80
- def process_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
89
-
90
- if caps
91
- @selenium_opts.merge!(@options)
58
+ id: [:watir_client]
59
+ http_client
92
60
  else
93
- caps = Selenium::WebDriver::Remote::Capabilities.send @browser, @options.merge(@w3c_caps)
61
+ raise TypeError, ':http_client must be a Hash or a Selenium HTTP Client instance'
94
62
  end
95
-
96
- @selenium_opts[:desired_capabilities] = caps
97
63
  end
98
64
 
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
65
+ def process_browser_options
66
+ browser_options = @options.delete(:options).dup || {}
67
+ vendor_caps = process_vendor_capabilities(browser_options)
115
68
 
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
69
+ options = if browser_options.is_a? Selenium::WebDriver::Options
70
+ browser_options
71
+ else
72
+ convert_timeouts(browser_options)
73
+ Selenium::WebDriver::Options.send(@browser, **browser_options)
74
+ end
121
75
 
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
76
+ options.unhandled_prompt_behavior ||= :ignore
77
+ browser_specific_options(options)
78
+ raise ArgumentError, "#{@options} are unrecognized arguments for Browser constructor" unless @options.empty?
131
79
 
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)
80
+ vendor_caps << options
138
81
  end
139
82
 
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)
83
+ def process_vendor_capabilities(opts)
84
+ return [] unless opts.is_a? Hash
155
85
 
156
- @selenium_opts[:options].args << '--headless'
157
- @selenium_opts[:options].args << '--disable-gpu'
86
+ vendor = opts.select { |key, _val| key.to_s.include?(':') && opts.delete(key) }
87
+ vendor.map { |k, v| Selenium::WebDriver::Remote::Capabilities.new(k => v) }
158
88
  end
159
89
 
160
- def process_firefox_options(browser_options)
161
- @selenium_opts[:options] = browser_options if browser_options.is_a? Selenium::WebDriver::Firefox::Options
90
+ def convert_timeouts(browser_options)
91
+ browser_options[:timeouts] ||= {}
92
+ browser_options[:timeouts].keys.each do |key|
93
+ raise(ArgumentError, 'do not set implicit wait, Watir handles waiting automatically') if key.to_s == 'implicit'
162
94
 
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)
95
+ Watir.logger.deprecate('using timeouts directly in options',
96
+ ":#{key}_timeout",
97
+ id: 'timeouts')
98
+ end
99
+ if browser_options.key?(:page_load_timeout)
100
+ browser_options[:timeouts][:page_load] = browser_options.delete(:page_load_timeout) * 1000
170
101
  end
171
102
 
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?
103
+ return unless browser_options.key?(:script_timeout)
194
104
 
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
105
+ browser_options[:timeouts][:script] = browser_options.delete(:script_timeout) * 1000
201
106
  end
202
107
 
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)
108
+ def browser_specific_options(options)
109
+ case @browser
110
+ when :chrome, :edge, :microsoftedge
111
+ if @options.delete(:headless)
112
+ options.args << '--headless'
113
+ options.args << '--disable-gpu'
114
+ options.args << '--no-sandbox'
115
+ end
116
+ when :firefox
117
+ options.headless! if @options.delete(:headless)
118
+ when :safari
119
+ Selenium::WebDriver::Safari.technology_preview! if @options.delete(:technology_preview)
218
120
  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
121
  end
241
122
 
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
123
+ def process_service
124
+ service = @options.delete(:service)
248
125
 
249
- def deprecate_remote(browser)
250
- return unless browser == :remote
126
+ case service
127
+ when nil
128
+ nil
129
+ when Hash
130
+ return if service.empty?
251
131
 
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
132
+ Selenium::WebDriver::Service.send(@browser, **service)
133
+ when Selenium::WebDriver::Service
134
+ service
135
+ else
136
+ raise TypeError, "#{service} needs to be Selenium Service or Hash instance"
137
+ end
257
138
  end
258
139
 
259
140
  def infer_browser
260
141
  if @options.key?(:browser)
261
142
  @options.delete(:browser)
262
143
  elsif @options.key?(:capabilities)
263
- @options[:capabilities].browser_name.tr(' ', '_').to_sym
144
+ @options[:capabilities].browser_name.tr(' ', '_').downcase.to_sym
264
145
  elsif @options.key?(:options)
265
146
  @options[:options].class.to_s.split('::')[-2].downcase.to_sym
266
147
  else
267
148
  :chrome
268
149
  end
269
150
  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
296
151
  end
297
152
  end