selenium-webdriver 4.1.0 → 4.9.1

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 (157) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +234 -1
  3. data/Gemfile +2 -0
  4. data/LICENSE +1 -1
  5. data/NOTICE +1 -1
  6. data/README.md +1 -1
  7. data/bin/linux/selenium-manager +0 -0
  8. data/bin/macos/selenium-manager +0 -0
  9. data/bin/windows/selenium-manager.exe +0 -0
  10. data/lib/selenium/server.rb +36 -27
  11. data/lib/selenium/webdriver/atoms/findElements.js +0 -0
  12. data/lib/selenium/webdriver/atoms/getAttribute.js +0 -0
  13. data/lib/selenium/webdriver/atoms/isDisplayed.js +0 -0
  14. data/lib/selenium/webdriver/atoms/mutationListener.js +0 -0
  15. data/lib/selenium/webdriver/atoms.rb +2 -3
  16. data/lib/selenium/webdriver/bidi/browsing_context.rb +88 -0
  17. data/lib/selenium/webdriver/bidi/browsing_context_info.rb +35 -0
  18. data/lib/selenium/webdriver/bidi/log/base_log_entry.rb +35 -0
  19. data/lib/selenium/webdriver/bidi/log/console_log_entry.rb +35 -0
  20. data/lib/selenium/webdriver/bidi/log/filter_by.rb +40 -0
  21. data/lib/selenium/webdriver/bidi/log/generic_log_entry.rb +33 -0
  22. data/lib/selenium/webdriver/bidi/log/javascript_log_entry.rb +33 -0
  23. data/lib/selenium/webdriver/bidi/log_inspector.rb +143 -0
  24. data/lib/selenium/webdriver/bidi/navigate_result.rb +33 -0
  25. data/lib/selenium/webdriver/bidi/session.rb +51 -0
  26. data/lib/selenium/webdriver/bidi.rb +56 -0
  27. data/lib/selenium/webdriver/chrome/driver.rb +9 -29
  28. data/lib/selenium/webdriver/chrome/features.rb +6 -68
  29. data/lib/selenium/webdriver/chrome/options.rb +3 -223
  30. data/lib/selenium/webdriver/chrome/profile.rb +3 -83
  31. data/lib/selenium/webdriver/chrome/service.rb +3 -23
  32. data/lib/selenium/webdriver/chrome.rb +0 -14
  33. data/lib/selenium/webdriver/chromium/driver.rb +61 -0
  34. data/lib/selenium/webdriver/chromium/features.rb +103 -0
  35. data/lib/selenium/webdriver/chromium/options.rb +261 -0
  36. data/lib/selenium/webdriver/chromium/profile.rb +113 -0
  37. data/lib/selenium/webdriver/chromium/service.rb +42 -0
  38. data/lib/selenium/webdriver/chromium.rb +32 -0
  39. data/lib/selenium/webdriver/common/action_builder.rb +64 -22
  40. data/lib/selenium/webdriver/common/child_process.rb +124 -0
  41. data/lib/selenium/webdriver/common/driver.rb +36 -74
  42. data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +0 -2
  43. data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +0 -1
  44. data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +0 -2
  45. data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +0 -2
  46. data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +0 -2
  47. data/lib/selenium/webdriver/common/driver_extensions/{has_remote_status.rb → has_bidi.rb} +10 -5
  48. data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +10 -1
  49. data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +0 -2
  50. data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +1 -4
  51. data/lib/selenium/webdriver/common/driver_extensions/has_debugger.rb +0 -2
  52. data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +0 -2
  53. data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +0 -2
  54. data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +1 -2
  55. data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +1 -2
  56. data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +0 -2
  57. data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +2 -69
  58. data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +0 -2
  59. data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +1 -3
  60. data/lib/selenium/webdriver/common/driver_finder.rb +44 -0
  61. data/lib/selenium/webdriver/common/element.rb +8 -8
  62. data/lib/selenium/webdriver/common/error.rb +1 -3
  63. data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +2 -2
  64. data/lib/selenium/webdriver/common/interactions/input_device.rb +10 -4
  65. data/lib/selenium/webdriver/common/interactions/interaction.rb +12 -25
  66. data/lib/selenium/webdriver/common/interactions/interactions.rb +24 -4
  67. data/lib/selenium/webdriver/common/interactions/key_actions.rb +5 -1
  68. data/lib/selenium/webdriver/common/interactions/key_input.rb +11 -27
  69. data/lib/selenium/webdriver/common/interactions/none_input.rb +10 -8
  70. data/lib/selenium/webdriver/common/interactions/pause.rb +49 -0
  71. data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +59 -70
  72. data/lib/selenium/webdriver/common/interactions/pointer_cancel.rb +45 -0
  73. data/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb +63 -0
  74. data/lib/selenium/webdriver/common/interactions/pointer_input.rb +15 -84
  75. data/lib/selenium/webdriver/common/interactions/pointer_move.rb +60 -0
  76. data/lib/selenium/webdriver/common/interactions/pointer_press.rb +85 -0
  77. data/lib/selenium/webdriver/common/interactions/scroll.rb +59 -0
  78. data/lib/selenium/webdriver/common/interactions/scroll_origin.rb +48 -0
  79. data/lib/selenium/webdriver/common/interactions/typing_interaction.rb +54 -0
  80. data/lib/selenium/webdriver/common/interactions/wheel_actions.rb +113 -0
  81. data/lib/selenium/webdriver/common/interactions/wheel_input.rb +42 -0
  82. data/lib/selenium/webdriver/common/keys.rb +1 -0
  83. data/lib/selenium/webdriver/common/local_driver.rb +55 -0
  84. data/lib/selenium/webdriver/common/logger.rb +76 -24
  85. data/lib/selenium/webdriver/common/manager.rb +0 -27
  86. data/lib/selenium/webdriver/common/options.rb +32 -17
  87. data/lib/selenium/webdriver/common/platform.rb +8 -5
  88. data/lib/selenium/webdriver/common/port_prober.rb +1 -1
  89. data/lib/selenium/webdriver/common/profile_helper.rb +1 -1
  90. data/lib/selenium/webdriver/common/proxy.rb +1 -1
  91. data/lib/selenium/webdriver/common/search_context.rb +0 -6
  92. data/lib/selenium/webdriver/common/selenium_manager.rb +108 -0
  93. data/lib/selenium/webdriver/common/service.rb +20 -23
  94. data/lib/selenium/webdriver/common/service_manager.rb +8 -15
  95. data/lib/selenium/webdriver/common/shadow_root.rb +2 -3
  96. data/lib/selenium/webdriver/common/socket_lock.rb +3 -3
  97. data/lib/selenium/webdriver/common/socket_poller.rb +2 -2
  98. data/lib/selenium/webdriver/common/takes_screenshot.rb +2 -3
  99. data/lib/selenium/webdriver/common/target_locator.rb +2 -3
  100. data/lib/selenium/webdriver/common/timeouts.rb +2 -2
  101. data/lib/selenium/webdriver/common/virtual_authenticator/credential.rb +85 -0
  102. data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb +72 -0
  103. data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb +62 -0
  104. data/lib/selenium/webdriver/common/websocket_connection.rb +164 -0
  105. data/lib/selenium/webdriver/common/window.rb +6 -6
  106. data/lib/selenium/webdriver/common/zipper.rb +1 -1
  107. data/lib/selenium/webdriver/common.rb +21 -3
  108. data/lib/selenium/webdriver/devtools/console_event.rb +0 -2
  109. data/lib/selenium/webdriver/devtools/exception_event.rb +0 -2
  110. data/lib/selenium/webdriver/devtools/mutation_event.rb +0 -2
  111. data/lib/selenium/webdriver/devtools/network_interceptor.rb +173 -0
  112. data/lib/selenium/webdriver/devtools/pinned_script.rb +0 -2
  113. data/lib/selenium/webdriver/devtools/request.rb +1 -3
  114. data/lib/selenium/webdriver/devtools/response.rb +1 -3
  115. data/lib/selenium/webdriver/devtools.rb +17 -114
  116. data/lib/selenium/webdriver/edge/driver.rb +9 -3
  117. data/lib/selenium/webdriver/edge/features.rb +4 -4
  118. data/lib/selenium/webdriver/edge/options.rb +3 -5
  119. data/lib/selenium/webdriver/edge/profile.rb +2 -2
  120. data/lib/selenium/webdriver/edge/service.rb +2 -6
  121. data/lib/selenium/webdriver/firefox/driver.rb +9 -2
  122. data/lib/selenium/webdriver/firefox/features.rb +6 -6
  123. data/lib/selenium/webdriver/firefox/options.rb +9 -3
  124. data/lib/selenium/webdriver/firefox/profile.rb +8 -12
  125. data/lib/selenium/webdriver/firefox/service.rb +0 -6
  126. data/lib/selenium/webdriver/firefox/util.rb +46 -0
  127. data/lib/selenium/webdriver/firefox.rb +1 -14
  128. data/lib/selenium/webdriver/ie/driver.rb +7 -1
  129. data/lib/selenium/webdriver/ie/service.rb +1 -7
  130. data/lib/selenium/webdriver/ie.rb +0 -14
  131. data/lib/selenium/webdriver/remote/{commands.rb → bridge/commands.rb} +15 -8
  132. data/lib/selenium/webdriver/remote/bridge.rb +65 -35
  133. data/lib/selenium/webdriver/remote/capabilities.rb +34 -12
  134. data/lib/selenium/webdriver/remote/driver.rb +19 -14
  135. data/lib/selenium/webdriver/remote/http/common.rb +3 -3
  136. data/lib/selenium/webdriver/remote/http/curb.rb +1 -3
  137. data/lib/selenium/webdriver/remote/http/default.rb +7 -12
  138. data/lib/selenium/webdriver/remote/response.rb +2 -3
  139. data/lib/selenium/webdriver/remote.rb +0 -1
  140. data/lib/selenium/webdriver/safari/driver.rb +7 -1
  141. data/lib/selenium/webdriver/safari/features.rb +0 -2
  142. data/lib/selenium/webdriver/safari/options.rb +5 -1
  143. data/lib/selenium/webdriver/safari/service.rb +0 -4
  144. data/lib/selenium/webdriver/safari.rb +1 -15
  145. data/lib/selenium/webdriver/support/color.rb +22 -22
  146. data/lib/selenium/webdriver/support/guards/guard.rb +0 -2
  147. data/lib/selenium/webdriver/support/guards/guard_condition.rb +1 -3
  148. data/lib/selenium/webdriver/support/guards.rb +1 -1
  149. data/lib/selenium/webdriver/support/relative_locator.rb +0 -1
  150. data/lib/selenium/webdriver/support/select.rb +3 -1
  151. data/lib/selenium/webdriver/version.rb +1 -1
  152. data/lib/selenium/webdriver.rb +5 -4
  153. data/selenium-webdriver.gemspec +13 -12
  154. metadata +70 -73
  155. data/lib/selenium/webdriver/remote/http/persistent.rb +0 -65
  156. data/lib/selenium/webdriver/support/cdp/domain.rb.erb +0 -63
  157. data/lib/selenium/webdriver/support/cdp_client_generator.rb +0 -108
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Licensed to the Software Freedom Conservancy (SFC) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The SFC licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
20
+ module Selenium
21
+ module WebDriver
22
+ module WheelActions
23
+ class ScrollOrigin
24
+ class << self
25
+ def element(element, x_offset = 0, y_offset = 0)
26
+ new(element, x_offset, y_offset)
27
+ end
28
+
29
+ def viewport(x_offset = 0, y_offset = 0)
30
+ new(:viewport, x_offset, y_offset)
31
+ end
32
+ end
33
+
34
+ attr_reader :origin, :x_offset, :y_offset
35
+
36
+ #
37
+ # Use a static method to access
38
+ # @api private
39
+ #
40
+ def initialize(origin, x_offset, y_offset)
41
+ @origin = origin
42
+ @x_offset = x_offset
43
+ @y_offset = y_offset
44
+ end
45
+ end # ScrollOrigin
46
+ end # WheelActions
47
+ end # WebDriver
48
+ end # Selenium
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Licensed to the Software Freedom Conservancy (SFC) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The SFC licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
20
+ module Selenium
21
+ module WebDriver
22
+ module Interactions
23
+ #
24
+ # Actions related to pressing keys.
25
+ #
26
+ # @api private
27
+ #
28
+
29
+ class TypingInteraction < Interaction
30
+ attr_reader :type
31
+
32
+ def initialize(source, type, key)
33
+ super(source)
34
+ @type = assert_type(type)
35
+ @key = Keys.encode_key(key)
36
+ end
37
+
38
+ def assert_source(source)
39
+ raise TypeError, "#{source.type} is not a valid input type" unless source.is_a? KeyInput
40
+ end
41
+
42
+ def assert_type(type)
43
+ raise TypeError, "#{type.inspect} is not a valid key subtype" unless KeyInput::SUBTYPES.key? type
44
+
45
+ KeyInput::SUBTYPES[type]
46
+ end
47
+
48
+ def encode
49
+ {type: @type, value: @key}
50
+ end
51
+ end # TypingInteraction
52
+ end # Interactions
53
+ end # WebDriver
54
+ end # Selenium
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Licensed to the Software Freedom Conservancy (SFC) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The SFC licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
20
+ module Selenium
21
+ module WebDriver
22
+ module WheelActions
23
+ attr_writer :default_scroll_duration
24
+
25
+ #
26
+ # By default this is set to 250ms in the ActionBuilder constructor
27
+ # It can be overridden with default_scroll_duration=
28
+ #
29
+
30
+ def default_scroll_duration
31
+ @default_scroll_duration ||= @duration / 1000.0 # convert ms to seconds
32
+ end
33
+
34
+ #
35
+ # If the element is outside the viewport, scrolls the bottom of the element to the bottom of the viewport.
36
+ #
37
+ # @example Scroll to element
38
+ # el = driver.find_element(id: "some_id")
39
+ # driver.action.scroll_to(element).perform
40
+ #
41
+ # @param [Object] Which element to scroll into the viewport.
42
+ # @return [Selenium::WebDriver::WheelActions] A self reference.
43
+ def scroll_to(element, device: nil)
44
+ scroll(origin: element, device: device)
45
+ end
46
+
47
+ #
48
+ # Scrolls by provided amounts with the origin in the top left corner of the viewport.
49
+ #
50
+ # @example Scroll viewport by a specified amount
51
+ # el = driver.find_element(id: "some_id")
52
+ # driver.action.scroll_by(100, 200).perform
53
+ #
54
+ # @param [Integer] delta_x Distance along X axis to scroll using the wheel. A negative value scrolls left.
55
+ # @param [Integer] delta_y Distance along Y axis to scroll using the wheel. A negative value scrolls up.
56
+ # @return [Selenium::WebDriver::WheelActions] A self reference.
57
+ def scroll_by(delta_x, delta_y, device: nil)
58
+ scroll(delta_x: delta_x, delta_y: delta_y, device: device)
59
+ end
60
+
61
+ #
62
+ # Scrolls by provided amount based on a provided origin.
63
+ #
64
+ # The scroll origin is either the center of an element or the upper left of the viewport plus any offsets.
65
+ # If the origin is an element, and the element is not in the viewport, the bottom of the element will first
66
+ # be scrolled to the bottom of the viewport.
67
+ #
68
+ # @example Scroll from element by a specified amount
69
+ # el = driver.find_element(id: "some_id")
70
+ # origin = WheelActions::ScrollOrigin.element(el)
71
+ # driver.action.scroll_from(origin, 0, 200).perform
72
+ #
73
+ # @example Scroll from element by a specified amount with an offset
74
+ # el = driver.find_element(id: "some_id")
75
+ # origin = WheelActions::ScrollOrigin.element(el, 10, 10)
76
+ # driver.action.scroll_from(origin, 100, 200).perform
77
+ #
78
+ # @example Scroll viewport by a specified amount with an offset
79
+ # origin = WheelActions::ScrollOrigin.viewport(10, 10)
80
+ # driver.action.scroll_from(origin, 0, 200).perform
81
+ #
82
+ # @param [ScrollOrigin] scroll_origin Where scroll originates (viewport or element center) plus provided offsets.
83
+ # @param [Integer] delta_x Distance along X axis to scroll using the wheel. A negative value scrolls left.
84
+ # @param [Integer] delta_y Distance along Y axis to scroll using the wheel. A negative value scrolls up.
85
+ # @return [Selenium::WebDriver::WheelActions] A self reference.
86
+ # @raise [Error::MoveTargetOutOfBoundsError] If the origin with offset is outside the viewport.
87
+ def scroll_from(scroll_origin, delta_x, delta_y, device: nil)
88
+ raise TypeError, "#{scroll_origin.inspect} isn't a valid ScrollOrigin" unless scroll_origin.is_a?(ScrollOrigin)
89
+
90
+ scroll(x: scroll_origin.x_offset,
91
+ y: scroll_origin.y_offset,
92
+ delta_x: delta_x,
93
+ delta_y: delta_y,
94
+ origin: scroll_origin.origin,
95
+ device: device)
96
+ end
97
+
98
+ private
99
+
100
+ def scroll(**opts)
101
+ opts[:duration] = default_scroll_duration
102
+ wheel = wheel_input(opts.delete(:device))
103
+ wheel.create_scroll(**opts)
104
+ tick(wheel)
105
+ self
106
+ end
107
+
108
+ def wheel_input(name = nil)
109
+ device(name: name, type: Interactions::WHEEL) || add_wheel_input('wheel')
110
+ end
111
+ end # WheelActions
112
+ end # WebDriver
113
+ end # Selenium
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Licensed to the Software Freedom Conservancy (SFC) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The SFC licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
20
+ module Selenium
21
+ module WebDriver
22
+ module Interactions
23
+ #
24
+ # Creates actions specific to Pointer Input devices
25
+ #
26
+ # @api private
27
+ #
28
+
29
+ class WheelInput < InputDevice
30
+ def initialize(name = nil)
31
+ super(name)
32
+ @type = Interactions::WHEEL
33
+ end
34
+
35
+ def create_scroll(**opts)
36
+ opts[:source] = self
37
+ add_action(Scroll.new(**opts))
38
+ end
39
+ end # PointerInput
40
+ end # Interactions
41
+ end # WebDriver
42
+ end # Selenium
@@ -90,6 +90,7 @@ module Selenium
90
90
  meta: "\ue03D",
91
91
  command: "\ue03D", # alias
92
92
  left_meta: "\ue03D", # alias
93
+ zenkaku_hankaku: "\uE040",
93
94
  right_shift: "\ue050",
94
95
  right_control: "\ue051",
95
96
  right_alt: "\ue052",
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Licensed to the Software Freedom Conservancy (SFC) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The SFC licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
20
+ module Selenium
21
+ module WebDriver
22
+ module LocalDriver
23
+ def initialize_local_driver(capabilities, options, service, url)
24
+ raise ArgumentError, "Can't initialize #{self.class} with :url" if url
25
+
26
+ service ||= Service.send(browser)
27
+ caps = process_options(options, capabilities, service)
28
+ url = service_url(service)
29
+
30
+ [caps, url]
31
+ end
32
+
33
+ def process_options(options, capabilities, service)
34
+ default_options = Options.send(browser)
35
+
36
+ if options && capabilities
37
+ msg = "Don't use both :options and :capabilities when initializing #{self.class}, prefer :options"
38
+ raise ArgumentError, msg
39
+ elsif options && !options.is_a?(default_options.class)
40
+ raise ArgumentError, ":options must be an instance of #{default_options.class}"
41
+ elsif capabilities
42
+ WebDriver.logger.deprecate("The :capabilities parameter for #{self.class}",
43
+ ":options argument with an instance of #{self.class}",
44
+ id: :capabilities)
45
+ service.executable_path ||= WebDriver::DriverFinder.path(capabilities, service.class)
46
+ generate_capabilities(capabilities)
47
+ else
48
+ options ||= default_options
49
+ service.executable_path ||= WebDriver::DriverFinder.path(options, service.class)
50
+ options.as_json
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -38,19 +38,31 @@ module Selenium
38
38
 
39
39
  def_delegators :@logger,
40
40
  :close,
41
- :debug, :debug?,
42
- :info, :info?,
41
+ :debug?,
42
+ :info?,
43
43
  :warn?,
44
44
  :error, :error?,
45
45
  :fatal, :fatal?,
46
- :level, :level=
46
+ :level
47
47
 
48
48
  #
49
49
  # @param [String] progname Allow child projects to use Selenium's Logger pattern
50
50
  #
51
- def initialize(progname = 'Selenium')
52
- @logger = create_logger(progname)
53
- @ignored = []
51
+ def initialize(progname = 'Selenium', default_level: nil, ignored: nil, allowed: nil)
52
+ default_level ||= $DEBUG || ENV.key?('DEBUG') ? :debug : :warn
53
+
54
+ @logger = create_logger(progname, level: default_level)
55
+ @ignored = Array(ignored)
56
+ @allowed = Array(allowed)
57
+ @first_warning = false
58
+ end
59
+
60
+ def level=(level)
61
+ if level == :info && @logger.level == :info
62
+ info(':info is now the default log level, to see additional logging, set log level to :debug')
63
+ end
64
+
65
+ @logger.level = level
54
66
  end
55
67
 
56
68
  #
@@ -80,27 +92,60 @@ module Selenium
80
92
  #
81
93
  # Will not log the provided ID.
82
94
  #
83
- # @param [Array, Symbol] id
95
+ # @param [Array, Symbol] ids
96
+ #
97
+ def ignore(*ids)
98
+ @ignored += Array(ids).flatten
99
+ end
100
+
101
+ #
102
+ # Will only log the provided ID.
84
103
  #
85
- def ignore(id)
86
- Array(id).each { |ignore| @ignored << ignore }
104
+ # @param [Array, Symbol] ids
105
+ #
106
+ def allow(ids)
107
+ @allowed += Array(ids).flatten
87
108
  end
88
109
 
89
110
  #
90
- # Overrides default #warn to skip ignored messages by provided id
111
+ # Used to supply information of interest for debugging a problem
112
+ # Overrides default #debug to skip ignored messages by provided id
91
113
  #
92
114
  # @param [String] message
93
115
  # @param [Symbol, Array<Sybmol>] id
94
116
  # @yield see #deprecate
95
117
  #
96
- def warn(message, id: [])
97
- id = Array(id)
98
- return if (@ignored & id).any?
118
+ def debug(message, id: [], &block)
119
+ discard_or_log(:debug, message, id, &block)
120
+ end
99
121
 
100
- msg = id.empty? ? message : "[#{id.map(&:inspect).join(', ')}] #{message} "
101
- msg += " #{yield}" if block_given?
122
+ #
123
+ # Used to supply information of general interest
124
+ #
125
+ # @param [String] message
126
+ # @param [Symbol, Array<Sybmol>] id
127
+ # @yield see #deprecate
128
+ #
129
+ def info(message, id: [], &block)
130
+ unless @first_warning
131
+ @first_warning = true
132
+ info("Details on how to use and modify Selenium logger:\n", id: [:logger_info]) do
133
+ "https://selenium.dev/documentation/webdriver/troubleshooting/logging\n"
134
+ end
135
+ end
102
136
 
103
- @logger.warn { msg }
137
+ discard_or_log(:info, message, id, &block)
138
+ end
139
+
140
+ #
141
+ # Used to supply information that suggests action be taken by user
142
+ #
143
+ # @param [String] message
144
+ # @param [Symbol, Array<Sybmol>] id
145
+ # @yield see #deprecate
146
+ #
147
+ def warn(message, id: [], &block)
148
+ discard_or_log(:warn, message, id, &block)
104
149
  end
105
150
 
106
151
  #
@@ -114,11 +159,11 @@ module Selenium
114
159
  #
115
160
  def deprecate(old, new = nil, id: [], reference: '', &block)
116
161
  id = Array(id)
117
- return if @ignored.include?(:deprecations) || (@ignored & id).any?
162
+ return if @ignored.include?(:deprecations)
118
163
 
119
- ids = id.empty? ? '' : "[#{id.map(&:inspect).join(', ')}] "
164
+ id << :deprecations if @allowed.include?(:deprecations)
120
165
 
121
- message = +"[DEPRECATION] #{ids}#{old} is deprecated"
166
+ message = +"[DEPRECATION] #{old} is deprecated"
122
167
  message << if new
123
168
  ". Use #{new} instead."
124
169
  else
@@ -126,15 +171,15 @@ module Selenium
126
171
  end
127
172
  message << " See explanation for this deprecation: #{reference}." unless reference.empty?
128
173
 
129
- warn message, &block
174
+ discard_or_log(:warn, message, id, &block)
130
175
  end
131
176
 
132
177
  private
133
178
 
134
- def create_logger(name)
179
+ def create_logger(name, level:)
135
180
  logger = ::Logger.new($stdout)
136
181
  logger.progname = name
137
- logger.level = default_level
182
+ logger.level = level
138
183
  logger.formatter = proc do |severity, time, progname, msg|
139
184
  "#{time.strftime('%F %T')} #{severity} #{progname} #{msg}\n"
140
185
  end
@@ -142,8 +187,15 @@ module Selenium
142
187
  logger
143
188
  end
144
189
 
145
- def default_level
146
- $DEBUG || ENV.key?('DEBUG') ? :debug : :warn
190
+ def discard_or_log(level, message, id)
191
+ id = Array(id)
192
+ return if (@ignored & id).any?
193
+ return if @allowed.any? && (@allowed & id).none?
194
+
195
+ msg = id.empty? ? message : "[#{id.map(&:inspect).join(', ')}] #{message} "
196
+ msg += " #{yield}" if block_given?
197
+
198
+ @logger.send(level) { msg }
147
199
  end
148
200
  end # Logger
149
201
  end # WebDriver
@@ -104,33 +104,6 @@ module Selenium
104
104
  @timeouts ||= Timeouts.new(@bridge)
105
105
  end
106
106
 
107
- def logs
108
- WebDriver.logger.deprecate('Manager#logs', 'Chrome::Driver#logs')
109
- @logs ||= Logs.new(@bridge)
110
- end
111
-
112
- #
113
- # @param type [Symbol] Supports two values: :tab and :window.
114
- # @return [String] The value of the window handle
115
- #
116
- def new_window(type = :tab)
117
- WebDriver.logger.deprecate('Manager#new_window', 'TargetLocator#new_window', id: :new_window) do
118
- 'e.g., `driver.switch_to.new_window(:tab)`'
119
- end
120
- case type
121
- when :tab, :window
122
- result = @bridge.new_window(type)
123
- unless result.key?('handle')
124
- raise UnknownError, "the driver did not return a handle. " \
125
- "The returned result: #{result.inspect}"
126
- end
127
- result['handle']
128
- else
129
- raise ArgumentError, "invalid argument for type. Got: '#{type.inspect}'. " \
130
- "Try :tab or :window"
131
- end
132
- end
133
-
134
107
  def window
135
108
  @window ||= Window.new(@bridge)
136
109
  end
@@ -38,12 +38,12 @@ module Selenium
38
38
  def ie(**opts)
39
39
  IE::Options.new(**opts)
40
40
  end
41
- alias_method :internet_explorer, :ie
41
+ alias internet_explorer ie
42
42
 
43
43
  def edge(**opts)
44
44
  Edge::Options.new(**opts)
45
45
  end
46
- alias_method :microsoftedge, :edge
46
+ alias microsoftedge edge
47
47
 
48
48
  def safari(**opts)
49
49
  Safari::Options.new(**opts)
@@ -66,17 +66,10 @@ module Selenium
66
66
 
67
67
  attr_accessor :options
68
68
 
69
- def initialize(options: nil, **opts)
69
+ def initialize(**opts)
70
70
  self.class.set_capabilities
71
71
 
72
- @options = if options
73
- WebDriver.logger.deprecate(":options as keyword for initializing #{self.class}",
74
- "custom values directly in #new constructor",
75
- id: :options_options)
76
- opts.merge(options)
77
- else
78
- opts
79
- end
72
+ @options = opts
80
73
  @options[:browser_name] = self.class::BROWSER
81
74
  end
82
75
 
@@ -92,7 +85,13 @@ module Selenium
92
85
  #
93
86
 
94
87
  def add_option(name, value = nil)
95
- @options[name.keys.first] = name.values.first if value.nil? && name.is_a?(Hash)
88
+ name, value = name.first if value.nil? && name.is_a?(Hash)
89
+
90
+ unless name.to_s.include?(':')
91
+ WebDriver.logger.deprecate('Options#add_option for w3c or browser specific capabilities',
92
+ 'applicable attribute accessors or pass into constructor',
93
+ id: :add_option)
94
+ end
96
95
  @options[name] = value
97
96
  end
98
97
 
@@ -102,7 +101,7 @@ module Selenium
102
101
  as_json == other.as_json
103
102
  end
104
103
 
105
- alias_method :eql?, :==
104
+ alias eql? ==
106
105
 
107
106
  #
108
107
  # @api private
@@ -113,11 +112,27 @@ module Selenium
113
112
 
114
113
  w3c_options = process_w3c_options(options)
115
114
 
116
- self.class::CAPABILITIES.each do |capability_alias, capability_name|
117
- capability_value = options.delete(capability_alias)
118
- options[capability_name] = capability_value if !capability_value.nil? && !options.key?(capability_name)
115
+ browser_options = self.class::CAPABILITIES.each_with_object({}) do |(capability_alias, capability_name), hash|
116
+ from_name = options.delete(capability_name)
117
+ from_alias = options.delete(capability_alias)
118
+ capability_value = if !from_name.nil? && capability_alias != capability_name
119
+ WebDriver.logger.deprecate("#{capability_name} as option",
120
+ capability_alias.to_s, id: :option_symbols)
121
+ from_name
122
+ elsif !from_alias.nil?
123
+ from_alias
124
+ end
125
+
126
+ hash[capability_name] = capability_value unless capability_value.nil?
119
127
  end
120
- browser_options = defined?(self.class::KEY) ? {self.class::KEY => options} : options
128
+
129
+ unless options.empty?
130
+ msg = 'These options are not w3c compliant and will result in failures in a future release'
131
+ WebDriver.logger.warn("#{msg}: #{options}", id: :w3c_options)
132
+ browser_options.merge!(options)
133
+ end
134
+
135
+ browser_options = {self.class::KEY => browser_options} if defined?(self.class::KEY)
121
136
 
122
137
  process_browser_options(browser_options)
123
138
  generate_as_json(w3c_options.merge(browser_options))
@@ -78,6 +78,10 @@ module Selenium
78
78
  engine == :jruby
79
79
  end
80
80
 
81
+ def truffleruby?
82
+ engine == :truffleruby
83
+ end
84
+
81
85
  def ruby_version
82
86
  RUBY_VERSION
83
87
  end
@@ -104,8 +108,7 @@ module Selenium
104
108
  end
105
109
 
106
110
  def cygwin?
107
- RUBY_PLATFORM =~ /cygwin/
108
- !Regexp.last_match.nil?
111
+ RUBY_PLATFORM.include?('cygwin')
109
112
  end
110
113
 
111
114
  def null_device
@@ -177,9 +180,9 @@ module Selenium
177
180
 
178
181
  def find_in_program_files(*binary_names)
179
182
  paths = [
180
- ENV['PROGRAMFILES'] || '\\Program Files',
181
- ENV['ProgramFiles(x86)'] || '\\Program Files (x86)',
182
- ENV['ProgramW6432'] || '\\Program Files'
183
+ ENV.fetch('PROGRAMFILES', '\\Program Files'),
184
+ ENV.fetch('ProgramFiles(x86)', '\\Program Files (x86)'),
185
+ ENV.fetch('ProgramW6432', '\\Program Files')
183
186
  ]
184
187
 
185
188
  paths.each do |root|
@@ -34,7 +34,7 @@ module Selenium
34
34
  Platform.interfaces.each do |host|
35
35
  TCPServer.new(host, port).close
36
36
  rescue *IGNORED_ERRORS => e
37
- WebDriver.logger.debug("port prober could not bind to #{host}:#{port} (#{e.message})")
37
+ WebDriver.logger.debug("port prober could not bind to #{host}:#{port} (#{e.message})", id: :driver_service)
38
38
  # ignored - some machines appear unable to bind to some of their interfaces
39
39
  end
40
40
 
@@ -40,7 +40,7 @@ module Selenium
40
40
  end
41
41
 
42
42
  def as_json(*)
43
- {"zip" => encoded}
43
+ {'zip' => encoded}
44
44
  end
45
45
 
46
46
  def to_json(*)
@@ -74,7 +74,7 @@ module Selenium
74
74
  def ==(other)
75
75
  other.is_a?(self.class) && as_json == other.as_json
76
76
  end
77
- alias_method :eql?, :==
77
+ alias eql? ==
78
78
 
79
79
  def ftp=(value)
80
80
  self.type = :manual