watir 6.19.0 → 7.0.0.beta4

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.
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