selenium-webdriver 4.0.0.rc3 → 4.13.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 (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +338 -0
  3. data/Gemfile +2 -0
  4. data/LICENSE +1 -1
  5. data/NOTICE +1 -1
  6. data/README.md +2 -2
  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 +90 -79
  11. data/lib/selenium/webdriver/atoms/findElements.js +5 -6
  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/{common/driver_extensions/has_location.rb → bidi/log/filter_by.rb} +14 -11
  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 +4 -19
  32. data/lib/selenium/webdriver/chrome.rb +0 -16
  33. data/lib/selenium/webdriver/chromium/driver.rb +60 -0
  34. data/lib/selenium/webdriver/chromium/features.rb +103 -0
  35. data/lib/selenium/webdriver/chromium/options.rb +243 -0
  36. data/lib/selenium/webdriver/chromium/profile.rb +113 -0
  37. data/lib/selenium/webdriver/chromium.rb +29 -0
  38. data/lib/selenium/webdriver/common/action_builder.rb +62 -22
  39. data/lib/selenium/webdriver/common/child_process.rb +124 -0
  40. data/lib/selenium/webdriver/common/driver.rb +31 -81
  41. data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +0 -2
  42. data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +0 -1
  43. data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +0 -2
  44. data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +0 -2
  45. data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +0 -2
  46. data/lib/selenium/webdriver/common/driver_extensions/{has_remote_status.rb → has_bidi.rb} +10 -5
  47. data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +10 -1
  48. data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +0 -2
  49. data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +1 -4
  50. data/lib/selenium/webdriver/common/driver_extensions/has_debugger.rb +0 -2
  51. data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +0 -2
  52. data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +0 -2
  53. data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +1 -2
  54. data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +9 -2
  55. data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +2 -69
  56. data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +0 -2
  57. data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +1 -3
  58. data/lib/selenium/webdriver/common/driver_finder.rb +45 -0
  59. data/lib/selenium/webdriver/common/element.rb +8 -8
  60. data/lib/selenium/webdriver/common/error.rb +28 -5
  61. data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +2 -2
  62. data/lib/selenium/webdriver/common/interactions/input_device.rb +10 -4
  63. data/lib/selenium/webdriver/common/interactions/interaction.rb +12 -25
  64. data/lib/selenium/webdriver/common/interactions/interactions.rb +24 -4
  65. data/lib/selenium/webdriver/common/interactions/key_actions.rb +5 -1
  66. data/lib/selenium/webdriver/common/interactions/key_input.rb +11 -27
  67. data/lib/selenium/webdriver/common/interactions/none_input.rb +10 -8
  68. data/lib/selenium/webdriver/common/interactions/pause.rb +49 -0
  69. data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +59 -70
  70. data/lib/selenium/webdriver/common/{driver_extensions/has_network_connection.rb → interactions/pointer_cancel.rb} +19 -11
  71. data/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb +63 -0
  72. data/lib/selenium/webdriver/common/interactions/pointer_input.rb +15 -84
  73. data/lib/selenium/webdriver/common/interactions/pointer_move.rb +60 -0
  74. data/lib/selenium/webdriver/common/interactions/pointer_press.rb +85 -0
  75. data/lib/selenium/webdriver/common/interactions/scroll.rb +59 -0
  76. data/lib/selenium/webdriver/common/interactions/scroll_origin.rb +48 -0
  77. data/lib/selenium/webdriver/common/interactions/typing_interaction.rb +54 -0
  78. data/lib/selenium/webdriver/common/interactions/wheel_actions.rb +113 -0
  79. data/lib/selenium/webdriver/common/interactions/wheel_input.rb +42 -0
  80. data/lib/selenium/webdriver/common/keys.rb +1 -0
  81. data/lib/selenium/webdriver/common/local_driver.rb +46 -0
  82. data/lib/selenium/webdriver/common/logger.rb +90 -25
  83. data/lib/selenium/webdriver/common/manager.rb +0 -27
  84. data/lib/selenium/webdriver/common/options.rb +14 -20
  85. data/lib/selenium/webdriver/common/platform.rb +5 -51
  86. data/lib/selenium/webdriver/common/port_prober.rb +1 -1
  87. data/lib/selenium/webdriver/common/profile_helper.rb +2 -8
  88. data/lib/selenium/webdriver/common/proxy.rb +2 -2
  89. data/lib/selenium/webdriver/common/search_context.rb +0 -6
  90. data/lib/selenium/webdriver/common/selenium_manager.rb +134 -0
  91. data/lib/selenium/webdriver/common/service.rb +21 -30
  92. data/lib/selenium/webdriver/common/service_manager.rb +8 -15
  93. data/lib/selenium/webdriver/common/shadow_root.rb +2 -3
  94. data/lib/selenium/webdriver/common/socket_lock.rb +3 -3
  95. data/lib/selenium/webdriver/common/socket_poller.rb +31 -20
  96. data/lib/selenium/webdriver/common/takes_screenshot.rb +2 -3
  97. data/lib/selenium/webdriver/common/target_locator.rb +2 -3
  98. data/lib/selenium/webdriver/common/timeouts.rb +2 -2
  99. data/lib/selenium/webdriver/common/virtual_authenticator/credential.rb +85 -0
  100. data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb +72 -0
  101. data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb +62 -0
  102. data/lib/selenium/webdriver/common/websocket_connection.rb +164 -0
  103. data/lib/selenium/webdriver/common/window.rb +6 -6
  104. data/lib/selenium/webdriver/common/zipper.rb +4 -10
  105. data/lib/selenium/webdriver/common.rb +21 -5
  106. data/lib/selenium/webdriver/devtools/console_event.rb +0 -2
  107. data/lib/selenium/webdriver/devtools/exception_event.rb +0 -2
  108. data/lib/selenium/webdriver/devtools/mutation_event.rb +0 -2
  109. data/lib/selenium/webdriver/devtools/network_interceptor.rb +173 -0
  110. data/lib/selenium/webdriver/devtools/pinned_script.rb +0 -2
  111. data/lib/selenium/webdriver/devtools/request.rb +1 -3
  112. data/lib/selenium/webdriver/devtools/response.rb +1 -3
  113. data/lib/selenium/webdriver/devtools.rb +17 -103
  114. data/lib/selenium/webdriver/edge/driver.rb +9 -3
  115. data/lib/selenium/webdriver/edge/features.rb +4 -4
  116. data/lib/selenium/webdriver/edge/options.rb +17 -5
  117. data/lib/selenium/webdriver/edge/profile.rb +2 -2
  118. data/lib/selenium/webdriver/edge/service.rb +8 -7
  119. data/lib/selenium/webdriver/edge.rb +0 -2
  120. data/lib/selenium/webdriver/firefox/driver.rb +9 -2
  121. data/lib/selenium/webdriver/firefox/features.rb +6 -6
  122. data/lib/selenium/webdriver/firefox/options.rb +9 -14
  123. data/lib/selenium/webdriver/firefox/profile.rb +8 -12
  124. data/lib/selenium/webdriver/firefox/service.rb +0 -18
  125. data/lib/selenium/webdriver/firefox/util.rb +46 -0
  126. data/lib/selenium/webdriver/firefox.rb +1 -14
  127. data/lib/selenium/webdriver/ie/driver.rb +7 -1
  128. data/lib/selenium/webdriver/ie/options.rb +2 -1
  129. data/lib/selenium/webdriver/ie/service.rb +0 -22
  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 +70 -37
  133. data/lib/selenium/webdriver/remote/capabilities.rb +3 -53
  134. data/lib/selenium/webdriver/remote/driver.rb +31 -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 +8 -14
  138. data/lib/selenium/webdriver/remote/response.rb +2 -3
  139. data/lib/selenium/webdriver/remote/server_error.rb +1 -1
  140. data/lib/selenium/webdriver/remote.rb +5 -5
  141. data/lib/selenium/webdriver/safari/driver.rb +7 -1
  142. data/lib/selenium/webdriver/safari/features.rb +0 -2
  143. data/lib/selenium/webdriver/safari/options.rb +5 -1
  144. data/lib/selenium/webdriver/safari/service.rb +10 -4
  145. data/lib/selenium/webdriver/safari.rb +1 -15
  146. data/lib/selenium/webdriver/support/color.rb +22 -22
  147. data/lib/selenium/webdriver/support/guards/guard.rb +0 -2
  148. data/lib/selenium/webdriver/support/guards/guard_condition.rb +1 -3
  149. data/lib/selenium/webdriver/support/guards.rb +1 -1
  150. data/lib/selenium/webdriver/support/relative_locator.rb +0 -1
  151. data/lib/selenium/webdriver/support/select.rb +4 -2
  152. data/lib/selenium/webdriver/version.rb +1 -1
  153. data/lib/selenium/webdriver.rb +7 -5
  154. data/selenium-webdriver.gemspec +15 -13
  155. metadata +79 -65
  156. data/lib/selenium/webdriver/remote/http/persistent.rb +0 -65
  157. data/lib/selenium/webdriver/support/cdp/domain.rb.erb +0 -63
  158. 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,46 @@
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(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, service)
28
+ url = service_url(service)
29
+
30
+ [caps, url]
31
+ end
32
+
33
+ def process_options(options, service)
34
+ default_options = Options.send(browser)
35
+ options ||= default_options
36
+
37
+ unless options.is_a?(default_options.class)
38
+ raise ArgumentError, ":options must be an instance of #{default_options.class}"
39
+ end
40
+
41
+ service.executable_path ||= WebDriver::DriverFinder.path(options, service.class)
42
+ options.as_json
43
+ end
44
+ end
45
+ end
46
+ 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
- :error, :error?,
44
+ :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,64 @@ 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
+ discard_or_log(:info, message, id, &block)
131
+ end
102
132
 
103
- @logger.warn { msg }
133
+ #
134
+ # Used to supply information that suggests an error occurred
135
+ #
136
+ # @param [String] message
137
+ # @param [Symbol, Array<Sybmol>] id
138
+ # @yield see #deprecate
139
+ #
140
+ def error(message, id: [], &block)
141
+ discard_or_log(:error, message, id, &block)
142
+ end
143
+
144
+ #
145
+ # Used to supply information that suggests action be taken by user
146
+ #
147
+ # @param [String] message
148
+ # @param [Symbol, Array<Sybmol>] id
149
+ # @yield see #deprecate
150
+ #
151
+ def warn(message, id: [], &block)
152
+ discard_or_log(:warn, message, id, &block)
104
153
  end
105
154
 
106
155
  #
@@ -114,11 +163,11 @@ module Selenium
114
163
  #
115
164
  def deprecate(old, new = nil, id: [], reference: '', &block)
116
165
  id = Array(id)
117
- return if @ignored.include?(:deprecations) || (@ignored & id).any?
166
+ return if @ignored.include?(:deprecations)
118
167
 
119
- ids = id.empty? ? '' : "[#{id.map(&:inspect).join(', ')}] "
168
+ id << :deprecations if @allowed.include?(:deprecations)
120
169
 
121
- message = +"[DEPRECATION] #{ids}#{old} is deprecated"
170
+ message = +"[DEPRECATION] #{old} is deprecated"
122
171
  message << if new
123
172
  ". Use #{new} instead."
124
173
  else
@@ -126,15 +175,15 @@ module Selenium
126
175
  end
127
176
  message << " See explanation for this deprecation: #{reference}." unless reference.empty?
128
177
 
129
- warn message, &block
178
+ discard_or_log(:warn, message, id, &block)
130
179
  end
131
180
 
132
181
  private
133
182
 
134
- def create_logger(name)
183
+ def create_logger(name, level:)
135
184
  logger = ::Logger.new($stdout)
136
185
  logger.progname = name
137
- logger.level = default_level
186
+ logger.level = level
138
187
  logger.formatter = proc do |severity, time, progname, msg|
139
188
  "#{time.strftime('%F %T')} #{severity} #{progname} #{msg}\n"
140
189
  end
@@ -142,8 +191,24 @@ module Selenium
142
191
  logger
143
192
  end
144
193
 
145
- def default_level
146
- $DEBUG || ENV.key?('DEBUG') ? :debug : :warn
194
+ def discard_or_log(level, message, id)
195
+ id = Array(id)
196
+ return if (@ignored & id).any?
197
+ return if @allowed.any? && (@allowed & id).none?
198
+
199
+ return if ::Logger::Severity.const_get(level.upcase) < @logger.level
200
+
201
+ unless @first_warning
202
+ @first_warning = true
203
+ info("Details on how to use and modify Selenium logger:\n", id: [:logger_info]) do
204
+ "https://selenium.dev/documentation/webdriver/troubleshooting/logging\n"
205
+ end
206
+ end
207
+
208
+ msg = id.empty? ? message : "[#{id.map(&:inspect).join(', ')}] #{message} "
209
+ msg += " #{yield}" if block_given?
210
+
211
+ @logger.send(level) { msg }
147
212
  end
148
213
  end # Logger
149
214
  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,7 @@ 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)
96
89
  @options[name] = value
97
90
  end
98
91
 
@@ -102,7 +95,7 @@ module Selenium
102
95
  as_json == other.as_json
103
96
  end
104
97
 
105
- alias_method :eql?, :==
98
+ alias eql? ==
106
99
 
107
100
  #
108
101
  # @api private
@@ -113,11 +106,14 @@ module Selenium
113
106
 
114
107
  w3c_options = process_w3c_options(options)
115
108
 
116
- self.class::CAPABILITIES.each do |capability_alias, capability_name|
109
+ browser_options = self.class::CAPABILITIES.each_with_object({}) do |(capability_alias, capability_name), hash|
117
110
  capability_value = options.delete(capability_alias)
118
- options[capability_name] = capability_value if !capability_value.nil? && !options.key?(capability_name)
111
+ hash[capability_name] = capability_value unless capability_value.nil?
119
112
  end
120
- browser_options = defined?(self.class::KEY) ? {self.class::KEY => options} : options
113
+
114
+ raise Error::WebDriverError, "These options are not w3c compliant: #{options}" unless options.empty?
115
+
116
+ browser_options = {self.class::KEY => browser_options} if defined?(self.class::KEY)
121
117
 
122
118
  process_browser_options(browser_options)
123
119
  generate_as_json(w3c_options.merge(browser_options))
@@ -130,7 +126,7 @@ module Selenium
130
126
  end
131
127
 
132
128
  def process_w3c_options(options)
133
- w3c_options = options.select { |key, _val| w3c?(key) }
129
+ w3c_options = options.select { |key, val| w3c?(key) && !val.nil? }
134
130
  w3c_options[:unhandled_prompt_behavior] &&= w3c_options[:unhandled_prompt_behavior]&.to_s&.tr('_', ' ')
135
131
  options.delete_if { |key, _val| w3c?(key) }
136
132
  w3c_options
@@ -179,8 +175,6 @@ module Selenium
179
175
  def camel_case(str)
180
176
  str.gsub(/_([a-z])/) { Regexp.last_match(1).upcase }
181
177
  end
182
- end
183
-
184
- # Options
178
+ end # Options
185
179
  end # WebDriver
186
180
  end # Selenium