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.
- checksums.yaml +4 -4
- data/CHANGES +234 -1
- data/Gemfile +2 -0
- data/LICENSE +1 -1
- data/NOTICE +1 -1
- data/README.md +1 -1
- data/bin/linux/selenium-manager +0 -0
- data/bin/macos/selenium-manager +0 -0
- data/bin/windows/selenium-manager.exe +0 -0
- data/lib/selenium/server.rb +36 -27
- data/lib/selenium/webdriver/atoms/findElements.js +0 -0
- data/lib/selenium/webdriver/atoms/getAttribute.js +0 -0
- data/lib/selenium/webdriver/atoms/isDisplayed.js +0 -0
- data/lib/selenium/webdriver/atoms/mutationListener.js +0 -0
- data/lib/selenium/webdriver/atoms.rb +2 -3
- data/lib/selenium/webdriver/bidi/browsing_context.rb +88 -0
- data/lib/selenium/webdriver/bidi/browsing_context_info.rb +35 -0
- data/lib/selenium/webdriver/bidi/log/base_log_entry.rb +35 -0
- data/lib/selenium/webdriver/bidi/log/console_log_entry.rb +35 -0
- data/lib/selenium/webdriver/bidi/log/filter_by.rb +40 -0
- data/lib/selenium/webdriver/bidi/log/generic_log_entry.rb +33 -0
- data/lib/selenium/webdriver/bidi/log/javascript_log_entry.rb +33 -0
- data/lib/selenium/webdriver/bidi/log_inspector.rb +143 -0
- data/lib/selenium/webdriver/bidi/navigate_result.rb +33 -0
- data/lib/selenium/webdriver/bidi/session.rb +51 -0
- data/lib/selenium/webdriver/bidi.rb +56 -0
- data/lib/selenium/webdriver/chrome/driver.rb +9 -29
- data/lib/selenium/webdriver/chrome/features.rb +6 -68
- data/lib/selenium/webdriver/chrome/options.rb +3 -223
- data/lib/selenium/webdriver/chrome/profile.rb +3 -83
- data/lib/selenium/webdriver/chrome/service.rb +3 -23
- data/lib/selenium/webdriver/chrome.rb +0 -14
- data/lib/selenium/webdriver/chromium/driver.rb +61 -0
- data/lib/selenium/webdriver/chromium/features.rb +103 -0
- data/lib/selenium/webdriver/chromium/options.rb +261 -0
- data/lib/selenium/webdriver/chromium/profile.rb +113 -0
- data/lib/selenium/webdriver/chromium/service.rb +42 -0
- data/lib/selenium/webdriver/chromium.rb +32 -0
- data/lib/selenium/webdriver/common/action_builder.rb +64 -22
- data/lib/selenium/webdriver/common/child_process.rb +124 -0
- data/lib/selenium/webdriver/common/driver.rb +36 -74
- data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +0 -1
- data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/{has_remote_status.rb → has_bidi.rb} +10 -5
- data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +10 -1
- data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +1 -4
- data/lib/selenium/webdriver/common/driver_extensions/has_debugger.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +1 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +1 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +2 -69
- data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +1 -3
- data/lib/selenium/webdriver/common/driver_finder.rb +44 -0
- data/lib/selenium/webdriver/common/element.rb +8 -8
- data/lib/selenium/webdriver/common/error.rb +1 -3
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +2 -2
- data/lib/selenium/webdriver/common/interactions/input_device.rb +10 -4
- data/lib/selenium/webdriver/common/interactions/interaction.rb +12 -25
- data/lib/selenium/webdriver/common/interactions/interactions.rb +24 -4
- data/lib/selenium/webdriver/common/interactions/key_actions.rb +5 -1
- data/lib/selenium/webdriver/common/interactions/key_input.rb +11 -27
- data/lib/selenium/webdriver/common/interactions/none_input.rb +10 -8
- data/lib/selenium/webdriver/common/interactions/pause.rb +49 -0
- data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +59 -70
- data/lib/selenium/webdriver/common/interactions/pointer_cancel.rb +45 -0
- data/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb +63 -0
- data/lib/selenium/webdriver/common/interactions/pointer_input.rb +15 -84
- data/lib/selenium/webdriver/common/interactions/pointer_move.rb +60 -0
- data/lib/selenium/webdriver/common/interactions/pointer_press.rb +85 -0
- data/lib/selenium/webdriver/common/interactions/scroll.rb +59 -0
- data/lib/selenium/webdriver/common/interactions/scroll_origin.rb +48 -0
- data/lib/selenium/webdriver/common/interactions/typing_interaction.rb +54 -0
- data/lib/selenium/webdriver/common/interactions/wheel_actions.rb +113 -0
- data/lib/selenium/webdriver/common/interactions/wheel_input.rb +42 -0
- data/lib/selenium/webdriver/common/keys.rb +1 -0
- data/lib/selenium/webdriver/common/local_driver.rb +55 -0
- data/lib/selenium/webdriver/common/logger.rb +76 -24
- data/lib/selenium/webdriver/common/manager.rb +0 -27
- data/lib/selenium/webdriver/common/options.rb +32 -17
- data/lib/selenium/webdriver/common/platform.rb +8 -5
- data/lib/selenium/webdriver/common/port_prober.rb +1 -1
- data/lib/selenium/webdriver/common/profile_helper.rb +1 -1
- data/lib/selenium/webdriver/common/proxy.rb +1 -1
- data/lib/selenium/webdriver/common/search_context.rb +0 -6
- data/lib/selenium/webdriver/common/selenium_manager.rb +108 -0
- data/lib/selenium/webdriver/common/service.rb +20 -23
- data/lib/selenium/webdriver/common/service_manager.rb +8 -15
- data/lib/selenium/webdriver/common/shadow_root.rb +2 -3
- data/lib/selenium/webdriver/common/socket_lock.rb +3 -3
- data/lib/selenium/webdriver/common/socket_poller.rb +2 -2
- data/lib/selenium/webdriver/common/takes_screenshot.rb +2 -3
- data/lib/selenium/webdriver/common/target_locator.rb +2 -3
- data/lib/selenium/webdriver/common/timeouts.rb +2 -2
- data/lib/selenium/webdriver/common/virtual_authenticator/credential.rb +85 -0
- data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb +72 -0
- data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb +62 -0
- data/lib/selenium/webdriver/common/websocket_connection.rb +164 -0
- data/lib/selenium/webdriver/common/window.rb +6 -6
- data/lib/selenium/webdriver/common/zipper.rb +1 -1
- data/lib/selenium/webdriver/common.rb +21 -3
- data/lib/selenium/webdriver/devtools/console_event.rb +0 -2
- data/lib/selenium/webdriver/devtools/exception_event.rb +0 -2
- data/lib/selenium/webdriver/devtools/mutation_event.rb +0 -2
- data/lib/selenium/webdriver/devtools/network_interceptor.rb +173 -0
- data/lib/selenium/webdriver/devtools/pinned_script.rb +0 -2
- data/lib/selenium/webdriver/devtools/request.rb +1 -3
- data/lib/selenium/webdriver/devtools/response.rb +1 -3
- data/lib/selenium/webdriver/devtools.rb +17 -114
- data/lib/selenium/webdriver/edge/driver.rb +9 -3
- data/lib/selenium/webdriver/edge/features.rb +4 -4
- data/lib/selenium/webdriver/edge/options.rb +3 -5
- data/lib/selenium/webdriver/edge/profile.rb +2 -2
- data/lib/selenium/webdriver/edge/service.rb +2 -6
- data/lib/selenium/webdriver/firefox/driver.rb +9 -2
- data/lib/selenium/webdriver/firefox/features.rb +6 -6
- data/lib/selenium/webdriver/firefox/options.rb +9 -3
- data/lib/selenium/webdriver/firefox/profile.rb +8 -12
- data/lib/selenium/webdriver/firefox/service.rb +0 -6
- data/lib/selenium/webdriver/firefox/util.rb +46 -0
- data/lib/selenium/webdriver/firefox.rb +1 -14
- data/lib/selenium/webdriver/ie/driver.rb +7 -1
- data/lib/selenium/webdriver/ie/service.rb +1 -7
- data/lib/selenium/webdriver/ie.rb +0 -14
- data/lib/selenium/webdriver/remote/{commands.rb → bridge/commands.rb} +15 -8
- data/lib/selenium/webdriver/remote/bridge.rb +65 -35
- data/lib/selenium/webdriver/remote/capabilities.rb +34 -12
- data/lib/selenium/webdriver/remote/driver.rb +19 -14
- data/lib/selenium/webdriver/remote/http/common.rb +3 -3
- data/lib/selenium/webdriver/remote/http/curb.rb +1 -3
- data/lib/selenium/webdriver/remote/http/default.rb +7 -12
- data/lib/selenium/webdriver/remote/response.rb +2 -3
- data/lib/selenium/webdriver/remote.rb +0 -1
- data/lib/selenium/webdriver/safari/driver.rb +7 -1
- data/lib/selenium/webdriver/safari/features.rb +0 -2
- data/lib/selenium/webdriver/safari/options.rb +5 -1
- data/lib/selenium/webdriver/safari/service.rb +0 -4
- data/lib/selenium/webdriver/safari.rb +1 -15
- data/lib/selenium/webdriver/support/color.rb +22 -22
- data/lib/selenium/webdriver/support/guards/guard.rb +0 -2
- data/lib/selenium/webdriver/support/guards/guard_condition.rb +1 -3
- data/lib/selenium/webdriver/support/guards.rb +1 -1
- data/lib/selenium/webdriver/support/relative_locator.rb +0 -1
- data/lib/selenium/webdriver/support/select.rb +3 -1
- data/lib/selenium/webdriver/version.rb +1 -1
- data/lib/selenium/webdriver.rb +5 -4
- data/selenium-webdriver.gemspec +13 -12
- metadata +70 -73
- data/lib/selenium/webdriver/remote/http/persistent.rb +0 -65
- data/lib/selenium/webdriver/support/cdp/domain.rb.erb +0 -63
- 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
|
|
@@ -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
|
|
42
|
-
:info
|
|
41
|
+
:debug?,
|
|
42
|
+
:info?,
|
|
43
43
|
:warn?,
|
|
44
44
|
:error, :error?,
|
|
45
45
|
:fatal, :fatal?,
|
|
46
|
-
: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
|
-
|
|
53
|
-
|
|
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]
|
|
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
|
-
|
|
86
|
-
|
|
104
|
+
# @param [Array, Symbol] ids
|
|
105
|
+
#
|
|
106
|
+
def allow(ids)
|
|
107
|
+
@allowed += Array(ids).flatten
|
|
87
108
|
end
|
|
88
109
|
|
|
89
110
|
#
|
|
90
|
-
#
|
|
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
|
|
97
|
-
|
|
98
|
-
|
|
118
|
+
def debug(message, id: [], &block)
|
|
119
|
+
discard_or_log(:debug, message, id, &block)
|
|
120
|
+
end
|
|
99
121
|
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
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)
|
|
162
|
+
return if @ignored.include?(:deprecations)
|
|
118
163
|
|
|
119
|
-
|
|
164
|
+
id << :deprecations if @allowed.include?(:deprecations)
|
|
120
165
|
|
|
121
|
-
message = +"[DEPRECATION] #{
|
|
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 =
|
|
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
|
|
146
|
-
|
|
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
|
-
|
|
41
|
+
alias internet_explorer ie
|
|
42
42
|
|
|
43
43
|
def edge(**opts)
|
|
44
44
|
Edge::Options.new(**opts)
|
|
45
45
|
end
|
|
46
|
-
|
|
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(
|
|
69
|
+
def initialize(**opts)
|
|
70
70
|
self.class.set_capabilities
|
|
71
71
|
|
|
72
|
-
@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
|
-
|
|
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
|
-
|
|
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.
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
181
|
-
ENV
|
|
182
|
-
ENV
|
|
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
|
|