selenium-webdriver 3.142.7 → 4.0.3
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 +5 -5
- data/CHANGES +350 -5
- data/Gemfile +3 -1
- data/LICENSE +1 -1
- data/NOTICE +2 -0
- data/README.md +4 -5
- data/lib/selenium/server.rb +69 -63
- data/lib/selenium/webdriver/atoms/findElements.js +122 -0
- data/lib/selenium/webdriver/atoms/getAttribute.js +100 -7
- data/lib/selenium/webdriver/atoms/isDisplayed.js +76 -78
- data/lib/selenium/webdriver/atoms/mutationListener.js +55 -0
- data/lib/selenium/webdriver/chrome/driver.rb +26 -83
- data/lib/selenium/webdriver/chrome/{bridge.rb → features.rb} +50 -12
- data/lib/selenium/webdriver/chrome/options.rb +129 -58
- data/lib/selenium/webdriver/chrome/profile.rb +6 -3
- data/lib/selenium/webdriver/chrome/service.rb +8 -15
- data/lib/selenium/webdriver/chrome.rb +10 -9
- data/lib/selenium/webdriver/common/action_builder.rb +97 -249
- data/lib/selenium/webdriver/common/driver.rb +112 -23
- data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +43 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +51 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +89 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +77 -0
- data/lib/selenium/webdriver/common/driver_extensions/{has_touch_screen.rb → has_cdp.rb} +10 -8
- data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +45 -0
- data/lib/selenium/webdriver/{firefox/util.rb → common/driver_extensions/has_devtools.rb} +16 -19
- data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +38 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +5 -8
- data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +144 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_logs.rb +30 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +17 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +6 -27
- data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +136 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +11 -11
- data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +77 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +1 -0
- data/lib/selenium/webdriver/common/driver_extensions/{rotatable.rb → prints_page.rb} +18 -20
- data/lib/selenium/webdriver/common/element.rb +82 -22
- data/lib/selenium/webdriver/common/error.rb +32 -196
- data/lib/selenium/webdriver/common/interactions/interaction.rb +4 -1
- data/lib/selenium/webdriver/common/interactions/key_actions.rb +5 -5
- data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +13 -13
- data/lib/selenium/webdriver/common/log_entry.rb +2 -2
- data/lib/selenium/webdriver/common/logger.rb +50 -15
- data/lib/selenium/webdriver/common/manager.rb +15 -15
- data/lib/selenium/webdriver/common/options.rb +154 -23
- data/lib/selenium/webdriver/common/platform.rb +6 -1
- data/lib/selenium/webdriver/common/port_prober.rb +4 -6
- data/lib/selenium/webdriver/common/profile_helper.rb +11 -9
- data/lib/selenium/webdriver/common/proxy.rb +6 -3
- data/lib/selenium/webdriver/common/search_context.rb +7 -3
- data/lib/selenium/webdriver/common/service.rb +17 -125
- data/lib/selenium/webdriver/common/service_manager.rb +151 -0
- data/lib/selenium/webdriver/common/shadow_root.rb +87 -0
- data/lib/selenium/webdriver/common/socket_lock.rb +2 -2
- data/lib/selenium/webdriver/common/socket_poller.rb +2 -2
- data/lib/selenium/webdriver/common/takes_screenshot.rb +66 -0
- data/lib/selenium/webdriver/common/target_locator.rb +32 -4
- data/lib/selenium/webdriver/common/timeouts.rb +31 -4
- data/lib/selenium/webdriver/common/wait.rb +1 -1
- data/lib/selenium/webdriver/common/window.rb +0 -4
- data/lib/selenium/webdriver/common/zipper.rb +1 -9
- data/lib/selenium/webdriver/common.rb +23 -17
- data/lib/selenium/webdriver/devtools/console_event.rb +38 -0
- data/lib/selenium/webdriver/devtools/exception_event.rb +36 -0
- data/lib/selenium/webdriver/devtools/mutation_event.rb +37 -0
- data/lib/selenium/webdriver/devtools/pinned_script.rb +59 -0
- data/lib/selenium/webdriver/devtools/request.rb +67 -0
- data/lib/selenium/webdriver/devtools/response.rb +66 -0
- data/lib/selenium/webdriver/devtools.rb +182 -0
- data/lib/selenium/webdriver/edge/driver.rb +7 -29
- data/lib/selenium/webdriver/edge/features.rb +44 -0
- data/lib/selenium/webdriver/edge/options.rb +11 -48
- data/lib/selenium/webdriver/{common/w3c_manager.rb → edge/profile.rb} +7 -19
- data/lib/selenium/webdriver/edge/service.rb +10 -26
- data/lib/selenium/webdriver/edge.rb +11 -14
- data/lib/selenium/webdriver/firefox/driver.rb +31 -19
- data/lib/selenium/webdriver/firefox/extension.rb +8 -0
- data/lib/selenium/webdriver/firefox/features.rb +66 -0
- data/lib/selenium/webdriver/firefox/options.rb +70 -49
- data/lib/selenium/webdriver/firefox/profile.rb +21 -71
- data/lib/selenium/webdriver/firefox/service.rb +5 -9
- data/lib/selenium/webdriver/firefox.rb +22 -20
- data/lib/selenium/webdriver/ie/driver.rb +1 -47
- data/lib/selenium/webdriver/ie/options.rb +13 -44
- data/lib/selenium/webdriver/ie/service.rb +13 -15
- data/lib/selenium/webdriver/ie.rb +8 -7
- data/lib/selenium/webdriver/remote/bridge.rb +558 -86
- data/lib/selenium/webdriver/remote/capabilities.rb +159 -123
- data/lib/selenium/webdriver/remote/commands.rb +163 -0
- data/lib/selenium/webdriver/remote/driver.rb +22 -12
- data/lib/selenium/webdriver/remote/http/common.rb +0 -5
- data/lib/selenium/webdriver/remote/http/default.rb +17 -20
- data/lib/selenium/webdriver/remote/http/persistent.rb +11 -6
- data/lib/selenium/webdriver/remote/response.rb +16 -47
- data/lib/selenium/webdriver/remote.rb +15 -13
- data/lib/selenium/webdriver/safari/driver.rb +3 -31
- data/lib/selenium/webdriver/safari/{bridge.rb → features.rb} +3 -3
- data/lib/selenium/webdriver/safari/options.rb +10 -29
- data/lib/selenium/webdriver/safari/service.rb +4 -8
- data/lib/selenium/webdriver/safari.rb +17 -9
- data/lib/selenium/webdriver/support/block_event_listener.rb +1 -1
- data/lib/selenium/webdriver/support/cdp/domain.rb.erb +63 -0
- data/lib/selenium/webdriver/support/cdp_client_generator.rb +108 -0
- data/lib/selenium/webdriver/support/color.rb +2 -2
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +4 -4
- data/lib/selenium/webdriver/support/guards/guard.rb +89 -0
- data/lib/selenium/webdriver/{firefox/marionette/bridge.rb → support/guards/guard_condition.rb} +22 -19
- data/lib/selenium/webdriver/support/guards.rb +95 -0
- data/lib/selenium/webdriver/support/relative_locator.rb +51 -0
- data/lib/selenium/webdriver/support/select.rb +3 -3
- data/lib/selenium/webdriver/support.rb +1 -0
- data/lib/selenium/webdriver/version.rb +1 -1
- data/lib/selenium/webdriver.rb +12 -12
- data/selenium-webdriver.gemspec +28 -12
- metadata +128 -69
- data/lib/selenium/webdriver/common/bridge_helper.rb +0 -82
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +0 -64
- data/lib/selenium/webdriver/common/keyboard.rb +0 -70
- data/lib/selenium/webdriver/common/mouse.rb +0 -89
- data/lib/selenium/webdriver/common/touch_action_builder.rb +0 -78
- data/lib/selenium/webdriver/common/touch_screen.rb +0 -123
- data/lib/selenium/webdriver/common/w3c_action_builder.rb +0 -212
- data/lib/selenium/webdriver/edge/bridge.rb +0 -76
- data/lib/selenium/webdriver/firefox/binary.rb +0 -187
- data/lib/selenium/webdriver/firefox/extension/prefs.json +0 -69
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/lib/selenium/webdriver/firefox/launcher.rb +0 -111
- data/lib/selenium/webdriver/firefox/legacy/driver.rb +0 -83
- data/lib/selenium/webdriver/firefox/marionette/driver.rb +0 -90
- data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
- data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
- data/lib/selenium/webdriver/remote/oss/bridge.rb +0 -594
- data/lib/selenium/webdriver/remote/oss/commands.rb +0 -223
- data/lib/selenium/webdriver/remote/w3c/bridge.rb +0 -605
- data/lib/selenium/webdriver/remote/w3c/capabilities.rb +0 -310
- data/lib/selenium/webdriver/remote/w3c/commands.rb +0 -157
|
@@ -0,0 +1,151 @@
|
|
|
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
|
+
#
|
|
23
|
+
# Base class implementing default behavior of service_manager object,
|
|
24
|
+
# responsible for starting and stopping driver implementations.
|
|
25
|
+
#
|
|
26
|
+
# @api private
|
|
27
|
+
#
|
|
28
|
+
class ServiceManager
|
|
29
|
+
START_TIMEOUT = 20
|
|
30
|
+
SOCKET_LOCK_TIMEOUT = 45
|
|
31
|
+
STOP_TIMEOUT = 20
|
|
32
|
+
|
|
33
|
+
#
|
|
34
|
+
# End users should use a class method for the desired driver, rather than using this directly.
|
|
35
|
+
#
|
|
36
|
+
# @api private
|
|
37
|
+
#
|
|
38
|
+
|
|
39
|
+
def initialize(config)
|
|
40
|
+
@executable_path = config.executable_path
|
|
41
|
+
@host = Platform.localhost
|
|
42
|
+
@port = config.port
|
|
43
|
+
@extra_args = config.extra_args
|
|
44
|
+
@shutdown_supported = config.shutdown_supported
|
|
45
|
+
|
|
46
|
+
raise Error::WebDriverError, "invalid port: #{@port}" if @port < 1
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def start
|
|
50
|
+
raise "already started: #{uri.inspect} #{@executable_path.inspect}" if process_running?
|
|
51
|
+
|
|
52
|
+
Platform.exit_hook(&method(:stop)) # make sure we don't leave the server running
|
|
53
|
+
|
|
54
|
+
socket_lock.locked do
|
|
55
|
+
find_free_port
|
|
56
|
+
start_process
|
|
57
|
+
connect_until_stable
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def stop
|
|
62
|
+
return unless @shutdown_supported
|
|
63
|
+
|
|
64
|
+
stop_server
|
|
65
|
+
@process.poll_for_exit STOP_TIMEOUT
|
|
66
|
+
rescue ChildProcess::TimeoutError
|
|
67
|
+
nil # noop
|
|
68
|
+
ensure
|
|
69
|
+
stop_process
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def uri
|
|
73
|
+
@uri ||= URI.parse("http://#{@host}:#{@port}")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def build_process(*command)
|
|
79
|
+
WebDriver.logger.debug("Executing Process #{command}")
|
|
80
|
+
@process = ChildProcess.build(*command)
|
|
81
|
+
if WebDriver.logger.debug?
|
|
82
|
+
@process.io.stdout = @process.io.stderr = WebDriver.logger.io
|
|
83
|
+
elsif Platform.jruby?
|
|
84
|
+
# Apparently we need to read the output of drivers on JRuby.
|
|
85
|
+
@process.io.stdout = @process.io.stderr = File.new(Platform.null_device, 'w')
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
@process
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def connect_to_server
|
|
92
|
+
Net::HTTP.start(@host, @port) do |http|
|
|
93
|
+
http.open_timeout = STOP_TIMEOUT / 2
|
|
94
|
+
http.read_timeout = STOP_TIMEOUT / 2
|
|
95
|
+
|
|
96
|
+
yield http
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def find_free_port
|
|
101
|
+
@port = PortProber.above(@port)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def start_process
|
|
105
|
+
@process = build_process(@executable_path, "--port=#{@port}", *@extra_args)
|
|
106
|
+
# NOTE: this is a bug only in Windows 7
|
|
107
|
+
@process.leader = true unless Platform.windows?
|
|
108
|
+
@process.start
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def stop_process
|
|
112
|
+
return if process_exited?
|
|
113
|
+
|
|
114
|
+
@process.stop STOP_TIMEOUT
|
|
115
|
+
@process.io.stdout.close if Platform.jruby? && !WebDriver.logger.debug?
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def stop_server
|
|
119
|
+
return if process_exited?
|
|
120
|
+
|
|
121
|
+
connect_to_server do |http|
|
|
122
|
+
headers = WebDriver::Remote::Http::Common::DEFAULT_HEADERS.dup
|
|
123
|
+
http.get('/shutdown', headers)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def process_running?
|
|
128
|
+
defined?(@process) && @process&.alive?
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def process_exited?
|
|
132
|
+
@process.nil? || @process.exited?
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def connect_until_stable
|
|
136
|
+
socket_poller = SocketPoller.new @host, @port, START_TIMEOUT
|
|
137
|
+
return if socket_poller.connected?
|
|
138
|
+
|
|
139
|
+
raise Error::WebDriverError, cannot_connect_error_text
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def cannot_connect_error_text
|
|
143
|
+
"unable to connect to #{@executable_path} #{@host}:#{@port}"
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def socket_lock
|
|
147
|
+
@socket_lock ||= SocketLock.new(@port - 1, SOCKET_LOCK_TIMEOUT)
|
|
148
|
+
end
|
|
149
|
+
end # Service
|
|
150
|
+
end # WebDriver
|
|
151
|
+
end # Selenium
|
|
@@ -0,0 +1,87 @@
|
|
|
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
|
+
class ShadowRoot
|
|
23
|
+
ROOT_KEY = 'shadow-6066-11e4-a52e-4f735466cecf'
|
|
24
|
+
|
|
25
|
+
include SearchContext
|
|
26
|
+
|
|
27
|
+
#
|
|
28
|
+
# Creates a new shadow root
|
|
29
|
+
#
|
|
30
|
+
# @api private
|
|
31
|
+
#
|
|
32
|
+
|
|
33
|
+
def initialize(bridge, id)
|
|
34
|
+
@bridge = bridge
|
|
35
|
+
@id = id
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def inspect
|
|
39
|
+
format '#<%<class>s:0x%<hash>x id=%<id>s>', class: self.class, hash: hash * 2, id: @id.inspect
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def ==(other)
|
|
43
|
+
other.is_a?(self.class) && ref == other.ref
|
|
44
|
+
end
|
|
45
|
+
alias_method :eql?, :==
|
|
46
|
+
|
|
47
|
+
def hash
|
|
48
|
+
@id.hash ^ @bridge.hash
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
#
|
|
52
|
+
# @api private
|
|
53
|
+
# @see SearchContext
|
|
54
|
+
#
|
|
55
|
+
|
|
56
|
+
def ref
|
|
57
|
+
[:shadow_root, @id]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
#
|
|
61
|
+
# Convert to a ShadowRoot JSON Object for transmission over the wire.
|
|
62
|
+
# @see https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#basic-terms-and-concepts
|
|
63
|
+
#
|
|
64
|
+
# @api private
|
|
65
|
+
#
|
|
66
|
+
|
|
67
|
+
def to_json(*)
|
|
68
|
+
JSON.generate as_json
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
#
|
|
72
|
+
# For Rails 3 - http://jonathanjulian.com/2010/04/rails-to_json-or-as_json/
|
|
73
|
+
#
|
|
74
|
+
# @api private
|
|
75
|
+
#
|
|
76
|
+
|
|
77
|
+
def as_json(*)
|
|
78
|
+
{ROOT_KEY => @id}
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
attr_reader :bridge
|
|
84
|
+
|
|
85
|
+
end # ShadowRoot
|
|
86
|
+
end # WebDriver
|
|
87
|
+
end # Selenium
|
|
@@ -69,8 +69,8 @@ module Selenium
|
|
|
69
69
|
ChildProcess.close_on_exec @server
|
|
70
70
|
|
|
71
71
|
true
|
|
72
|
-
rescue SocketError, Errno::EADDRINUSE, Errno::EBADF =>
|
|
73
|
-
WebDriver.logger.debug("#{self}: #{
|
|
72
|
+
rescue SocketError, Errno::EADDRINUSE, Errno::EBADF => e
|
|
73
|
+
WebDriver.logger.debug("#{self}: #{e.message}")
|
|
74
74
|
false
|
|
75
75
|
end
|
|
76
76
|
|
|
@@ -66,8 +66,8 @@ module Selenium
|
|
|
66
66
|
}.freeze
|
|
67
67
|
|
|
68
68
|
if Platform.jruby?
|
|
69
|
-
# we use a plain TCPSocket here since JRuby has issues
|
|
70
|
-
# see
|
|
69
|
+
# we use a plain TCPSocket here since JRuby has issues closing socket
|
|
70
|
+
# see https://github.com/jruby/jruby/issues/5709
|
|
71
71
|
def listening?
|
|
72
72
|
TCPSocket.new(@host, @port).close
|
|
73
73
|
true
|
|
@@ -0,0 +1,66 @@
|
|
|
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
|
+
#
|
|
23
|
+
# @api private
|
|
24
|
+
#
|
|
25
|
+
module TakesScreenshot
|
|
26
|
+
#
|
|
27
|
+
# Save a PNG screenshot of the viewport to the given path
|
|
28
|
+
#
|
|
29
|
+
# @api public
|
|
30
|
+
#
|
|
31
|
+
|
|
32
|
+
def save_screenshot(png_path, full_page: false)
|
|
33
|
+
extension = File.extname(png_path).downcase
|
|
34
|
+
if extension != '.png'
|
|
35
|
+
WebDriver.logger.warn "name used for saved screenshot does not match file type. "\
|
|
36
|
+
"It should end with .png extension",
|
|
37
|
+
id: :screenshot
|
|
38
|
+
end
|
|
39
|
+
File.open(png_path, 'wb') { |f| f << screenshot_as(:png, full_page: full_page) }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
#
|
|
43
|
+
# Return a PNG screenshot in the given format as a string
|
|
44
|
+
#
|
|
45
|
+
# @param [:base64, :png] format
|
|
46
|
+
# @param [Boolean] full_page allows taking full page screenshots if supported
|
|
47
|
+
# @return String screenshot
|
|
48
|
+
#
|
|
49
|
+
# @api public
|
|
50
|
+
|
|
51
|
+
def screenshot_as(format, full_page: false)
|
|
52
|
+
case format
|
|
53
|
+
when :base64
|
|
54
|
+
full_page ? full_screenshot : screenshot
|
|
55
|
+
when :png
|
|
56
|
+
screenshot_as(:base64, full_page: full_page).unpack1('m')
|
|
57
|
+
else
|
|
58
|
+
raise Error::UnsupportedOperationError, "unsupported format: #{format.inspect}"
|
|
59
|
+
end
|
|
60
|
+
rescue NameError
|
|
61
|
+
raise Error::UnsupportedOperationError, "Full Page Screenshots are not supported for #{inspect}"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end # TakesScreenshot
|
|
65
|
+
end # WebDriver
|
|
66
|
+
end # Selenium
|
|
@@ -44,6 +44,34 @@ module Selenium
|
|
|
44
44
|
@bridge.switch_to_parent_frame
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
+
#
|
|
48
|
+
# Switch to a new top-level browsing context
|
|
49
|
+
#
|
|
50
|
+
# @param type either :tab or :window
|
|
51
|
+
#
|
|
52
|
+
|
|
53
|
+
def new_window(type = :window)
|
|
54
|
+
unless %i[window tab].include?(type)
|
|
55
|
+
raise ArgumentError, "Valid types are :tab and :window, received: #{type.inspect}"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
handle = @bridge.new_window(type)['handle']
|
|
59
|
+
|
|
60
|
+
if block_given?
|
|
61
|
+
execute_and_close = proc do
|
|
62
|
+
yield(self)
|
|
63
|
+
begin
|
|
64
|
+
@bridge.close
|
|
65
|
+
rescue Error::NoSuchWindowError
|
|
66
|
+
# window already closed
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
window(handle, &execute_and_close)
|
|
70
|
+
else
|
|
71
|
+
window(handle)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
47
75
|
#
|
|
48
76
|
# switch to the given window handle
|
|
49
77
|
#
|
|
@@ -57,10 +85,10 @@ module Selenium
|
|
|
57
85
|
def window(id)
|
|
58
86
|
if block_given?
|
|
59
87
|
original = begin
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
88
|
+
@bridge.window_handle
|
|
89
|
+
rescue Error::NoSuchWindowError
|
|
90
|
+
nil
|
|
91
|
+
end
|
|
64
92
|
|
|
65
93
|
unless @bridge.window_handles.include? id
|
|
66
94
|
raise Error::NoSuchWindowError, "The specified identifier '#{id}' is not found in the window handle list"
|
|
@@ -24,22 +24,49 @@ module Selenium
|
|
|
24
24
|
@bridge = bridge
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
#
|
|
28
|
+
# Gets the amount of time the driver should wait when searching for elements.
|
|
29
|
+
#
|
|
30
|
+
|
|
31
|
+
def implicit_wait
|
|
32
|
+
Float(@bridge.timeouts['implicit']) / 1000
|
|
33
|
+
end
|
|
34
|
+
|
|
27
35
|
#
|
|
28
36
|
# Set the amount of time the driver should wait when searching for elements.
|
|
29
37
|
#
|
|
30
38
|
|
|
31
39
|
def implicit_wait=(seconds)
|
|
32
|
-
@bridge.
|
|
40
|
+
@bridge.timeouts = {'implicit' => Integer(seconds * 1000)}
|
|
33
41
|
end
|
|
34
42
|
|
|
43
|
+
#
|
|
44
|
+
# Gets the amount of time to wait for an asynchronous script to finish
|
|
45
|
+
# execution before throwing an error.
|
|
46
|
+
#
|
|
47
|
+
|
|
48
|
+
def script
|
|
49
|
+
Float(@bridge.timeouts['script']) / 1000
|
|
50
|
+
end
|
|
51
|
+
alias_method :script_timeout, :script
|
|
52
|
+
|
|
35
53
|
#
|
|
36
54
|
# Sets the amount of time to wait for an asynchronous script to finish
|
|
37
55
|
# execution before throwing an error. If the timeout is negative, then the
|
|
38
56
|
# script will be allowed to run indefinitely.
|
|
39
57
|
#
|
|
40
58
|
|
|
41
|
-
def
|
|
42
|
-
@bridge.
|
|
59
|
+
def script=(seconds)
|
|
60
|
+
@bridge.timeouts = {'script' => Integer(seconds * 1000)}
|
|
61
|
+
end
|
|
62
|
+
alias_method :script_timeout=, :script=
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# Gets the amount of time to wait for a page load to complete before throwing an error.
|
|
66
|
+
#
|
|
67
|
+
|
|
68
|
+
def page_load
|
|
69
|
+
Float(@bridge.timeouts['pageLoad']) / 1000
|
|
43
70
|
end
|
|
44
71
|
|
|
45
72
|
#
|
|
@@ -48,7 +75,7 @@ module Selenium
|
|
|
48
75
|
#
|
|
49
76
|
|
|
50
77
|
def page_load=(seconds)
|
|
51
|
-
@bridge.
|
|
78
|
+
@bridge.timeouts = {'pageLoad' => Integer(seconds * 1000)}
|
|
52
79
|
end
|
|
53
80
|
end # Timeouts
|
|
54
81
|
end # WebDriver
|
|
@@ -72,16 +72,8 @@ module Selenium
|
|
|
72
72
|
private
|
|
73
73
|
|
|
74
74
|
def with_tmp_zip(&blk)
|
|
75
|
-
|
|
76
|
-
# can't use Dir.mktmpdir(&blk) because of http://jira.codehaus.org/browse/JRUBY-4082
|
|
77
|
-
tmp_dir = Dir.mktmpdir
|
|
78
|
-
zip_path = File.join(tmp_dir, 'webdriver-zip')
|
|
79
|
-
|
|
80
|
-
begin
|
|
75
|
+
Tempfile.create do |zip_path|
|
|
81
76
|
Zip::File.open(zip_path, Zip::File::CREATE, &blk)
|
|
82
|
-
ensure
|
|
83
|
-
FileUtils.rm_rf tmp_dir
|
|
84
|
-
FileUtils.rm_rf zip_path
|
|
85
77
|
end
|
|
86
78
|
end
|
|
87
79
|
|
|
@@ -23,15 +23,13 @@ require 'selenium/webdriver/common/proxy'
|
|
|
23
23
|
require 'selenium/webdriver/common/log_entry'
|
|
24
24
|
require 'selenium/webdriver/common/file_reaper'
|
|
25
25
|
require 'selenium/webdriver/common/service'
|
|
26
|
+
require 'selenium/webdriver/common/service_manager'
|
|
26
27
|
require 'selenium/webdriver/common/socket_lock'
|
|
27
28
|
require 'selenium/webdriver/common/socket_poller'
|
|
28
29
|
require 'selenium/webdriver/common/port_prober'
|
|
29
30
|
require 'selenium/webdriver/common/zipper'
|
|
30
31
|
require 'selenium/webdriver/common/wait'
|
|
31
32
|
require 'selenium/webdriver/common/alert'
|
|
32
|
-
require 'selenium/webdriver/common/mouse'
|
|
33
|
-
require 'selenium/webdriver/common/keyboard'
|
|
34
|
-
require 'selenium/webdriver/common/touch_screen'
|
|
35
33
|
require 'selenium/webdriver/common/target_locator'
|
|
36
34
|
require 'selenium/webdriver/common/navigation'
|
|
37
35
|
require 'selenium/webdriver/common/timeouts'
|
|
@@ -39,39 +37,47 @@ require 'selenium/webdriver/common/window'
|
|
|
39
37
|
require 'selenium/webdriver/common/logger'
|
|
40
38
|
require 'selenium/webdriver/common/logs'
|
|
41
39
|
require 'selenium/webdriver/common/manager'
|
|
42
|
-
require 'selenium/webdriver/common/w3c_manager'
|
|
43
40
|
require 'selenium/webdriver/common/search_context'
|
|
44
|
-
require 'selenium/webdriver/common/action_builder'
|
|
45
41
|
require 'selenium/webdriver/common/interactions/key_actions'
|
|
46
42
|
require 'selenium/webdriver/common/interactions/pointer_actions'
|
|
47
|
-
require 'selenium/webdriver/common/
|
|
48
|
-
require 'selenium/webdriver/common/
|
|
43
|
+
require 'selenium/webdriver/common/interactions/interactions'
|
|
44
|
+
require 'selenium/webdriver/common/interactions/input_device'
|
|
45
|
+
require 'selenium/webdriver/common/interactions/interaction'
|
|
46
|
+
require 'selenium/webdriver/common/interactions/none_input'
|
|
47
|
+
require 'selenium/webdriver/common/interactions/key_input'
|
|
48
|
+
require 'selenium/webdriver/common/interactions/pointer_input'
|
|
49
|
+
require 'selenium/webdriver/common/action_builder'
|
|
49
50
|
require 'selenium/webdriver/common/html5/shared_web_storage'
|
|
50
51
|
require 'selenium/webdriver/common/html5/local_storage'
|
|
51
52
|
require 'selenium/webdriver/common/html5/session_storage'
|
|
52
|
-
require 'selenium/webdriver/common/driver_extensions/takes_screenshot'
|
|
53
|
-
require 'selenium/webdriver/common/driver_extensions/rotatable'
|
|
54
53
|
require 'selenium/webdriver/common/driver_extensions/has_web_storage'
|
|
55
54
|
require 'selenium/webdriver/common/driver_extensions/downloads_files'
|
|
56
55
|
require 'selenium/webdriver/common/driver_extensions/has_location'
|
|
57
56
|
require 'selenium/webdriver/common/driver_extensions/has_session_id'
|
|
58
|
-
require 'selenium/webdriver/common/driver_extensions/has_touch_screen'
|
|
59
57
|
require 'selenium/webdriver/common/driver_extensions/has_remote_status'
|
|
60
58
|
require 'selenium/webdriver/common/driver_extensions/has_network_conditions'
|
|
61
59
|
require 'selenium/webdriver/common/driver_extensions/has_network_connection'
|
|
60
|
+
require 'selenium/webdriver/common/driver_extensions/has_network_interception'
|
|
61
|
+
require 'selenium/webdriver/common/driver_extensions/has_apple_permissions'
|
|
62
62
|
require 'selenium/webdriver/common/driver_extensions/has_permissions'
|
|
63
63
|
require 'selenium/webdriver/common/driver_extensions/has_debugger'
|
|
64
|
+
require 'selenium/webdriver/common/driver_extensions/has_context'
|
|
65
|
+
require 'selenium/webdriver/common/driver_extensions/prints_page'
|
|
64
66
|
require 'selenium/webdriver/common/driver_extensions/uploads_files'
|
|
67
|
+
require 'selenium/webdriver/common/driver_extensions/full_page_screenshot'
|
|
65
68
|
require 'selenium/webdriver/common/driver_extensions/has_addons'
|
|
66
|
-
require 'selenium/webdriver/common/
|
|
67
|
-
require 'selenium/webdriver/common/
|
|
68
|
-
require 'selenium/webdriver/common/
|
|
69
|
-
require 'selenium/webdriver/common/
|
|
70
|
-
require 'selenium/webdriver/common/
|
|
71
|
-
require 'selenium/webdriver/common/
|
|
69
|
+
require 'selenium/webdriver/common/driver_extensions/has_devtools'
|
|
70
|
+
require 'selenium/webdriver/common/driver_extensions/has_authentication'
|
|
71
|
+
require 'selenium/webdriver/common/driver_extensions/has_logs'
|
|
72
|
+
require 'selenium/webdriver/common/driver_extensions/has_log_events'
|
|
73
|
+
require 'selenium/webdriver/common/driver_extensions/has_pinned_scripts'
|
|
74
|
+
require 'selenium/webdriver/common/driver_extensions/has_cdp'
|
|
75
|
+
require 'selenium/webdriver/common/driver_extensions/has_casting'
|
|
76
|
+
require 'selenium/webdriver/common/driver_extensions/has_launching'
|
|
72
77
|
require 'selenium/webdriver/common/keys'
|
|
73
|
-
require 'selenium/webdriver/common/bridge_helper'
|
|
74
78
|
require 'selenium/webdriver/common/profile_helper'
|
|
75
79
|
require 'selenium/webdriver/common/options'
|
|
80
|
+
require 'selenium/webdriver/common/takes_screenshot'
|
|
76
81
|
require 'selenium/webdriver/common/driver'
|
|
77
82
|
require 'selenium/webdriver/common/element'
|
|
83
|
+
require 'selenium/webdriver/common/shadow_root'
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
class DevTools
|
|
23
|
+
class ConsoleEvent
|
|
24
|
+
|
|
25
|
+
attr_accessor :type, :timestamp, :args
|
|
26
|
+
|
|
27
|
+
def initialize(type:, timestamp:, args:)
|
|
28
|
+
@type = type.to_sym
|
|
29
|
+
@timestamp = Time.at(timestamp / 1000)
|
|
30
|
+
@args = args.map do |arg|
|
|
31
|
+
arg.key?('value') ? arg['value'] : arg
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end # ConsoleEvent
|
|
36
|
+
end # DevTools
|
|
37
|
+
end # WebDriver
|
|
38
|
+
end # Selenium
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
class DevTools
|
|
23
|
+
class ExceptionEvent
|
|
24
|
+
|
|
25
|
+
attr_accessor :description, :timestamp, :stacktrace
|
|
26
|
+
|
|
27
|
+
def initialize(description:, timestamp:, stacktrace:)
|
|
28
|
+
@description = description
|
|
29
|
+
@timestamp = Time.at(timestamp / 1000)
|
|
30
|
+
@stacktrace = stacktrace
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end # ExceptionEvent
|
|
34
|
+
end # DevTools
|
|
35
|
+
end # WebDriver
|
|
36
|
+
end # Selenium
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
class DevTools
|
|
23
|
+
class MutationEvent
|
|
24
|
+
|
|
25
|
+
attr_accessor :element, :attribute_name, :current_value, :old_value
|
|
26
|
+
|
|
27
|
+
def initialize(element:, attribute_name:, current_value:, old_value:)
|
|
28
|
+
@element = element
|
|
29
|
+
@attribute_name = attribute_name
|
|
30
|
+
@current_value = current_value
|
|
31
|
+
@old_value = old_value
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end # MutationEvent
|
|
35
|
+
end # DevTools
|
|
36
|
+
end # WebDriver
|
|
37
|
+
end # Selenium
|