selenium-webdriver 4.0.0.alpha6 → 4.0.0.beta4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +137 -4
- data/Gemfile +3 -1
- data/LICENSE +1 -1
- data/NOTICE +2 -0
- data/README.md +4 -5
- data/lib/selenium/server.rb +18 -26
- data/lib/selenium/webdriver.rb +1 -4
- data/lib/selenium/webdriver/atoms/findElements.js +93 -93
- data/lib/selenium/webdriver/atoms/getAttribute.js +75 -59
- data/lib/selenium/webdriver/atoms/isDisplayed.js +72 -72
- data/lib/selenium/webdriver/atoms/mutationListener.js +55 -0
- data/lib/selenium/webdriver/chrome.rb +1 -1
- data/lib/selenium/webdriver/chrome/driver.rb +25 -10
- data/lib/selenium/webdriver/chrome/{bridge.rb → features.rb} +3 -3
- data/lib/selenium/webdriver/chrome/options.rb +51 -39
- data/lib/selenium/webdriver/chrome/profile.rb +6 -3
- data/lib/selenium/webdriver/chrome/service.rb +4 -2
- data/lib/selenium/webdriver/common.rb +8 -2
- data/lib/selenium/webdriver/common/driver.rb +36 -8
- data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +43 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +89 -0
- data/lib/selenium/webdriver/{edge_html/driver.rb → common/driver_extensions/has_cdp.rb} +12 -13
- data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +6 -1
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +5 -8
- data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +149 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_logs.rb +30 -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 +67 -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 +66 -12
- data/lib/selenium/webdriver/common/interactions/interaction.rb +4 -1
- data/lib/selenium/webdriver/common/logger.rb +5 -2
- data/lib/selenium/webdriver/common/manager.rb +6 -1
- data/lib/selenium/webdriver/common/options.rb +76 -14
- data/lib/selenium/webdriver/common/platform.rb +3 -1
- data/lib/selenium/webdriver/common/proxy.rb +6 -3
- data/lib/selenium/webdriver/common/search_context.rb +4 -1
- data/lib/selenium/webdriver/common/service.rb +1 -8
- data/lib/selenium/webdriver/common/service_manager.rb +1 -1
- data/lib/selenium/webdriver/common/socket_poller.rb +19 -30
- data/lib/selenium/webdriver/common/takes_screenshot.rb +66 -0
- data/lib/selenium/webdriver/common/target_locator.rb +4 -4
- data/lib/selenium/webdriver/devtools.rb +44 -18
- 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/{console.rb → request.rb} +22 -22
- data/lib/selenium/webdriver/edge.rb +7 -29
- data/lib/selenium/webdriver/{edge_chrome → edge}/driver.rb +8 -6
- data/lib/selenium/webdriver/{edge_chrome/bridge.rb → edge/features.rb} +9 -7
- data/lib/selenium/webdriver/{edge_chrome → edge}/options.rb +11 -4
- data/lib/selenium/webdriver/{edge_chrome → edge}/profile.rb +2 -2
- data/lib/selenium/webdriver/{edge_chrome → edge}/service.rb +2 -2
- data/lib/selenium/webdriver/firefox.rb +5 -1
- data/lib/selenium/webdriver/firefox/driver.rb +18 -5
- data/lib/selenium/webdriver/firefox/{bridge.rb → features.rb} +9 -4
- data/lib/selenium/webdriver/firefox/options.rb +20 -21
- data/lib/selenium/webdriver/firefox/profile.rb +12 -2
- data/lib/selenium/webdriver/firefox/service.rb +1 -1
- data/lib/selenium/webdriver/ie/driver.rb +1 -2
- data/lib/selenium/webdriver/ie/options.rb +1 -11
- data/lib/selenium/webdriver/ie/service.rb +4 -2
- data/lib/selenium/webdriver/remote/bridge.rb +48 -30
- data/lib/selenium/webdriver/remote/capabilities.rb +105 -64
- data/lib/selenium/webdriver/remote/commands.rb +3 -0
- data/lib/selenium/webdriver/remote/driver.rb +10 -3
- data/lib/selenium/webdriver/remote/http/common.rb +0 -5
- data/lib/selenium/webdriver/remote/http/default.rb +8 -7
- data/lib/selenium/webdriver/remote/http/persistent.rb +6 -0
- data/lib/selenium/webdriver/safari.rb +8 -1
- data/lib/selenium/webdriver/safari/driver.rb +3 -8
- data/lib/selenium/webdriver/safari/{bridge.rb → features.rb} +3 -3
- data/lib/selenium/webdriver/safari/options.rb +0 -25
- 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 +44 -13
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +1 -1
- data/lib/selenium/webdriver/support/guards.rb +95 -0
- data/lib/selenium/webdriver/support/guards/guard.rb +89 -0
- data/lib/selenium/webdriver/support/guards/guard_condition.rb +52 -0
- data/lib/selenium/webdriver/support/select.rb +2 -2
- data/lib/selenium/webdriver/version.rb +1 -1
- data/selenium-webdriver.gemspec +26 -12
- metadata +91 -108
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +0 -65
- data/lib/selenium/webdriver/devtools/accessibility.rb +0 -62
- data/lib/selenium/webdriver/devtools/animation.rb +0 -98
- data/lib/selenium/webdriver/devtools/application_cache.rb +0 -64
- data/lib/selenium/webdriver/devtools/audits.rb +0 -61
- data/lib/selenium/webdriver/devtools/background_service.rb +0 -67
- data/lib/selenium/webdriver/devtools/browser.rb +0 -123
- data/lib/selenium/webdriver/devtools/cache_storage.rb +0 -73
- data/lib/selenium/webdriver/devtools/cast.rb +0 -70
- data/lib/selenium/webdriver/devtools/css.rb +0 -165
- data/lib/selenium/webdriver/devtools/database.rb +0 -64
- data/lib/selenium/webdriver/devtools/debugger.rb +0 -229
- data/lib/selenium/webdriver/devtools/device_orientation.rb +0 -53
- data/lib/selenium/webdriver/devtools/dom.rb +0 -320
- data/lib/selenium/webdriver/devtools/domdebugger.rb +0 -93
- data/lib/selenium/webdriver/devtools/domsnapshot.rb +0 -65
- data/lib/selenium/webdriver/devtools/domstorage.rb +0 -79
- data/lib/selenium/webdriver/devtools/emulation.rb +0 -180
- data/lib/selenium/webdriver/devtools/fetch.rb +0 -97
- data/lib/selenium/webdriver/devtools/headless_experimental.rb +0 -61
- data/lib/selenium/webdriver/devtools/heap_profiler.rb +0 -107
- data/lib/selenium/webdriver/devtools/indexed_db.rb +0 -100
- data/lib/selenium/webdriver/devtools/input.rb +0 -140
- data/lib/selenium/webdriver/devtools/inspector.rb +0 -55
- data/lib/selenium/webdriver/devtools/io.rb +0 -59
- data/lib/selenium/webdriver/devtools/layer_tree.rb +0 -95
- data/lib/selenium/webdriver/devtools/log.rb +0 -66
- data/lib/selenium/webdriver/devtools/media.rb +0 -57
- data/lib/selenium/webdriver/devtools/memory.rb +0 -86
- data/lib/selenium/webdriver/devtools/network.rb +0 -228
- data/lib/selenium/webdriver/devtools/overlay.rb +0 -157
- data/lib/selenium/webdriver/devtools/page.rb +0 -374
- data/lib/selenium/webdriver/devtools/performance.rb +0 -63
- data/lib/selenium/webdriver/devtools/profiler.rb +0 -111
- data/lib/selenium/webdriver/devtools/runtime.rb +0 -193
- data/lib/selenium/webdriver/devtools/schema.rb +0 -46
- data/lib/selenium/webdriver/devtools/security.rb +0 -71
- data/lib/selenium/webdriver/devtools/service_worker.rb +0 -116
- data/lib/selenium/webdriver/devtools/storage.rb +0 -95
- data/lib/selenium/webdriver/devtools/system_info.rb +0 -50
- data/lib/selenium/webdriver/devtools/target.rb +0 -141
- data/lib/selenium/webdriver/devtools/tethering.rb +0 -55
- data/lib/selenium/webdriver/devtools/tracing.rb +0 -76
- data/lib/selenium/webdriver/devtools/web_audio.rb +0 -70
- data/lib/selenium/webdriver/devtools/web_authn.rb +0 -94
- data/lib/selenium/webdriver/edge_html/options.rb +0 -84
- data/lib/selenium/webdriver/edge_html/service.rb +0 -47
|
@@ -57,6 +57,8 @@ module Selenium
|
|
|
57
57
|
:jenkins
|
|
58
58
|
elsif ENV['APPVEYOR']
|
|
59
59
|
:appveyor
|
|
60
|
+
elsif ENV['GITHUB_ACTIONS']
|
|
61
|
+
:github
|
|
60
62
|
end
|
|
61
63
|
end
|
|
62
64
|
|
|
@@ -95,7 +97,7 @@ module Selenium
|
|
|
95
97
|
def wsl?
|
|
96
98
|
return false unless linux?
|
|
97
99
|
|
|
98
|
-
File.read('/proc/version').include?('
|
|
100
|
+
File.read('/proc/version').downcase.include?('microsoft')
|
|
99
101
|
rescue Errno::EACCES
|
|
100
102
|
# the file cannot be accessed on Linux on DeX
|
|
101
103
|
false
|
|
@@ -127,7 +127,10 @@ module Selenium
|
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
def type=(type)
|
|
130
|
-
|
|
130
|
+
unless TYPES.key? type
|
|
131
|
+
raise ArgumentError,
|
|
132
|
+
"invalid proxy type: #{type.inspect}, expected one of #{TYPES.keys.inspect}"
|
|
133
|
+
end
|
|
131
134
|
|
|
132
135
|
if defined?(@type) && type != @type
|
|
133
136
|
raise ArgumentError, "incompatible proxy type #{type.inspect} (already set to #{@type.inspect})"
|
|
@@ -138,10 +141,10 @@ module Selenium
|
|
|
138
141
|
|
|
139
142
|
def as_json(*)
|
|
140
143
|
json_result = {
|
|
141
|
-
'proxyType' => TYPES[type],
|
|
144
|
+
'proxyType' => TYPES[type].downcase,
|
|
142
145
|
'ftpProxy' => ftp,
|
|
143
146
|
'httpProxy' => http,
|
|
144
|
-
'noProxy' => no_proxy,
|
|
147
|
+
'noProxy' => no_proxy.is_a?(String) ? no_proxy.split(', ') : no_proxy,
|
|
145
148
|
'proxyAutoconfigUrl' => pac,
|
|
146
149
|
'sslProxy' => ssl,
|
|
147
150
|
'autodetect' => auto_detect,
|
|
@@ -93,7 +93,10 @@ module Selenium
|
|
|
93
93
|
when 1
|
|
94
94
|
arg = args.first
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
unless arg.respond_to?(:shift)
|
|
97
|
+
raise ArgumentError,
|
|
98
|
+
"expected #{arg.inspect}:#{arg.class} to respond to #shift"
|
|
99
|
+
end
|
|
97
100
|
|
|
98
101
|
# this will be a single-entry hash, so use #shift over #first or #[]
|
|
99
102
|
arr = arg.dup.shift
|
|
@@ -44,14 +44,7 @@ module Selenium
|
|
|
44
44
|
def edge(**opts)
|
|
45
45
|
Edge::Service.new(**opts)
|
|
46
46
|
end
|
|
47
|
-
|
|
48
|
-
def edge_chrome(**opts)
|
|
49
|
-
EdgeChrome::Service.new(**opts)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def edge_html(**opts)
|
|
53
|
-
EdgeHtml::Service.new(**opts)
|
|
54
|
-
end
|
|
47
|
+
alias_method :microsoftedge, :edge
|
|
55
48
|
|
|
56
49
|
def safari(**opts)
|
|
57
50
|
Safari::Service.new(**opts)
|
|
@@ -103,7 +103,7 @@ module Selenium
|
|
|
103
103
|
|
|
104
104
|
def start_process
|
|
105
105
|
@process = build_process(@executable_path, "--port=#{@port}", *@extra_args)
|
|
106
|
-
#
|
|
106
|
+
# NOTE: this is a bug only in Windows 7
|
|
107
107
|
@process.leader = true unless Platform.windows?
|
|
108
108
|
@process.start
|
|
109
109
|
end
|
|
@@ -65,37 +65,26 @@ module Selenium
|
|
|
65
65
|
arr << Errno::EALREADY if Platform.wsl?
|
|
66
66
|
}.freeze
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
|
81
|
-
sockaddr = Socket.pack_sockaddr_in(@port, addr[0][3])
|
|
82
|
-
|
|
83
|
-
begin
|
|
84
|
-
sock.connect_nonblock sockaddr
|
|
85
|
-
rescue Errno::EINPROGRESS
|
|
86
|
-
retry if socket_writable?(sock) && conn_completed?(sock)
|
|
87
|
-
raise Errno::ECONNREFUSED
|
|
88
|
-
rescue *CONNECTED_ERRORS
|
|
89
|
-
# yay!
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
sock.close
|
|
93
|
-
true
|
|
94
|
-
rescue *NOT_CONNECTED_ERRORS
|
|
95
|
-
sock&.close
|
|
96
|
-
WebDriver.logger.debug("polling for socket on #{[@host, @port].inspect}")
|
|
97
|
-
false
|
|
68
|
+
def listening?
|
|
69
|
+
addr = Socket.getaddrinfo(@host, @port, Socket::AF_INET, Socket::SOCK_STREAM)
|
|
70
|
+
sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
|
71
|
+
sockaddr = Socket.pack_sockaddr_in(@port, addr[0][3])
|
|
72
|
+
|
|
73
|
+
begin
|
|
74
|
+
sock.connect_nonblock sockaddr
|
|
75
|
+
rescue Errno::EINPROGRESS
|
|
76
|
+
retry if socket_writable?(sock) && conn_completed?(sock)
|
|
77
|
+
raise Errno::ECONNREFUSED
|
|
78
|
+
rescue *CONNECTED_ERRORS
|
|
79
|
+
# yay!
|
|
98
80
|
end
|
|
81
|
+
|
|
82
|
+
sock.close
|
|
83
|
+
true
|
|
84
|
+
rescue *NOT_CONNECTED_ERRORS
|
|
85
|
+
sock&.close
|
|
86
|
+
WebDriver.logger.debug("polling for socket on #{[@host, @port].inspect}")
|
|
87
|
+
false
|
|
99
88
|
end
|
|
100
89
|
|
|
101
90
|
def socket_writable?(sock)
|
|
@@ -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
|
|
@@ -57,10 +57,10 @@ module Selenium
|
|
|
57
57
|
def window(id)
|
|
58
58
|
if block_given?
|
|
59
59
|
original = begin
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
@bridge.window_handle
|
|
61
|
+
rescue Error::NoSuchWindowError
|
|
62
|
+
nil
|
|
63
|
+
end
|
|
64
64
|
|
|
65
65
|
unless @bridge.window_handles.include? id
|
|
66
66
|
raise Error::NoSuchWindowError, "The specified identifier '#{id}' is not found in the window handle list"
|
|
@@ -17,21 +17,22 @@
|
|
|
17
17
|
# specific language governing permissions and limitations
|
|
18
18
|
# under the License.
|
|
19
19
|
|
|
20
|
-
Dir["#{__dir__}/devtools/*"].sort.each { |f| require f }
|
|
21
|
-
|
|
22
20
|
module Selenium
|
|
23
21
|
module WebDriver
|
|
24
22
|
class DevTools
|
|
23
|
+
autoload :ConsoleEvent, 'selenium/webdriver/devtools/console_event'
|
|
24
|
+
autoload :ExceptionEvent, 'selenium/webdriver/devtools/exception_event'
|
|
25
|
+
autoload :MutationEvent, 'selenium/webdriver/devtools/mutation_event'
|
|
26
|
+
autoload :Request, 'selenium/webdriver/devtools/request'
|
|
25
27
|
|
|
26
|
-
def initialize(url)
|
|
28
|
+
def initialize(url:)
|
|
27
29
|
@messages = []
|
|
28
|
-
@
|
|
30
|
+
@session_id = nil
|
|
31
|
+
@url = url
|
|
29
32
|
|
|
30
33
|
process_handshake
|
|
31
34
|
attach_socket_listener
|
|
32
|
-
|
|
33
|
-
target.attach_to_target(target_id: page_target['id'])
|
|
34
|
-
target.set_auto_attach(auto_attach: true, wait_for_debugger_on_start: false)
|
|
35
|
+
start_session
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def callbacks
|
|
@@ -40,7 +41,10 @@ module Selenium
|
|
|
40
41
|
|
|
41
42
|
def send_cmd(method, **params)
|
|
42
43
|
id = next_id
|
|
43
|
-
data =
|
|
44
|
+
data = {id: id, method: method, params: params.reject { |_, v| v.nil? }}
|
|
45
|
+
data[:sessionId] = @session_id if @session_id
|
|
46
|
+
data = JSON.generate(data)
|
|
47
|
+
WebDriver.logger.debug "DevTools -> #{data}"
|
|
44
48
|
|
|
45
49
|
out_frame = WebSocket::Frame::Outgoing::Client.new(version: ws.version, data: data, type: 'text')
|
|
46
50
|
socket.write(out_frame.to_s)
|
|
@@ -54,6 +58,24 @@ module Selenium
|
|
|
54
58
|
message
|
|
55
59
|
end
|
|
56
60
|
|
|
61
|
+
def method_missing(method, *_args)
|
|
62
|
+
desired_class = "Selenium::DevTools::V#{Selenium::DevTools.version}::#{method.capitalize}"
|
|
63
|
+
return unless Object.const_defined?(desired_class)
|
|
64
|
+
|
|
65
|
+
self.class.class_eval do
|
|
66
|
+
define_method(method) do
|
|
67
|
+
Object.const_get(desired_class).new(self)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
send(method)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def respond_to_missing?(method, *_args)
|
|
75
|
+
desired_class = "Selenium::DevTools::V#{Selenium::DevTools.version}::#{method.capitalize}"
|
|
76
|
+
Object.const_defined?(desired_class)
|
|
77
|
+
end
|
|
78
|
+
|
|
57
79
|
private
|
|
58
80
|
|
|
59
81
|
def process_handshake
|
|
@@ -67,12 +89,17 @@ module Selenium
|
|
|
67
89
|
incoming_frame << socket.readpartial(1024)
|
|
68
90
|
|
|
69
91
|
while (frame = incoming_frame.next)
|
|
92
|
+
# Firefox will periodically fail on unparsable empty frame
|
|
93
|
+
break if frame.to_s.empty?
|
|
94
|
+
|
|
70
95
|
message = JSON.parse(frame.to_s)
|
|
71
96
|
@messages << message
|
|
97
|
+
WebDriver.logger.debug "DevTools <- #{message}"
|
|
72
98
|
next unless message['method']
|
|
73
99
|
|
|
74
100
|
callbacks[message['method']].each do |callback|
|
|
75
|
-
|
|
101
|
+
params = message['params'] # take in current thread!
|
|
102
|
+
Thread.new { callback.call(params) }
|
|
76
103
|
end
|
|
77
104
|
end
|
|
78
105
|
end
|
|
@@ -80,6 +107,13 @@ module Selenium
|
|
|
80
107
|
socket_listener.abort_on_exception = true
|
|
81
108
|
end
|
|
82
109
|
|
|
110
|
+
def start_session
|
|
111
|
+
targets = target.get_targets.dig('result', 'targetInfos')
|
|
112
|
+
page_target = targets.find { |target| target['type'] == 'page' }
|
|
113
|
+
session = target.attach_to_target(target_id: page_target['targetId'], flatten: true)
|
|
114
|
+
@session_id = session.dig('result', 'sessionId')
|
|
115
|
+
end
|
|
116
|
+
|
|
83
117
|
def incoming_frame
|
|
84
118
|
@incoming_frame ||= WebSocket::Frame::Incoming::Client.new(version: ws.version)
|
|
85
119
|
end
|
|
@@ -93,15 +127,7 @@ module Selenium
|
|
|
93
127
|
end
|
|
94
128
|
|
|
95
129
|
def ws
|
|
96
|
-
@ws ||= WebSocket::Handshake::Client.new(url:
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def page_target
|
|
100
|
-
@page_target ||= begin
|
|
101
|
-
response = Net::HTTP.get(@uri.hostname, '/json', @uri.port)
|
|
102
|
-
targets = JSON.parse(response)
|
|
103
|
-
targets.find { |target| target['type'] == 'page' }
|
|
104
|
-
end
|
|
130
|
+
@ws ||= WebSocket::Handshake::Client.new(url: @url)
|
|
105
131
|
end
|
|
106
132
|
|
|
107
133
|
def next_id
|
|
@@ -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
|