ferrum 0.17 → 0.17.2
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/LICENSE +1 -1
- data/README.md +9 -1369
- data/lib/ferrum/browser/options/base.rb +2 -2
- data/lib/ferrum/browser/options/chrome.rb +53 -26
- data/lib/ferrum/browser/options.rb +2 -1
- data/lib/ferrum/browser/process.rb +5 -4
- data/lib/ferrum/browser.rb +7 -1
- data/lib/ferrum/client/web_socket.rb +1 -1
- data/lib/ferrum/client.rb +7 -6
- data/lib/ferrum/context.rb +2 -0
- data/lib/ferrum/contexts.rb +19 -15
- data/lib/ferrum/cookies/cookie.rb +1 -1
- data/lib/ferrum/errors.rb +4 -3
- data/lib/ferrum/frame/runtime.rb +1 -1
- data/lib/ferrum/network/response.rb +14 -1
- data/lib/ferrum/network.rb +1 -1
- data/lib/ferrum/page/animation.rb +2 -2
- data/lib/ferrum/page/screenshot.rb +3 -3
- data/lib/ferrum/page.rb +2 -4
- data/lib/ferrum/utils/platform.rb +1 -1
- data/lib/ferrum/version.rb +1 -1
- metadata +4 -7
|
@@ -26,11 +26,11 @@ module Ferrum
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def except(*keys)
|
|
29
|
-
to_h.
|
|
29
|
+
to_h.except(*keys)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def detect_path
|
|
33
|
-
Binary.find(self.class::PLATFORM_PATH[Utils::Platform.
|
|
33
|
+
Binary.find(self.class::PLATFORM_PATH[Utils::Platform.platform_name])
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def merge_required(flags, options, user_data_dir)
|
|
@@ -5,44 +5,63 @@ module Ferrum
|
|
|
5
5
|
class Options
|
|
6
6
|
class Chrome < Base
|
|
7
7
|
DEFAULT_OPTIONS = {
|
|
8
|
-
"
|
|
9
|
-
"hide-scrollbars" => nil,
|
|
10
|
-
"mute-audio" => nil,
|
|
11
|
-
"enable-automation" => nil,
|
|
12
|
-
"disable-web-security" => nil,
|
|
13
|
-
"disable-session-crashed-bubble" => nil,
|
|
14
|
-
"disable-breakpad" => nil,
|
|
15
|
-
"disable-sync" => nil,
|
|
16
|
-
"no-first-run" => nil,
|
|
17
|
-
"use-mock-keychain" => nil,
|
|
18
|
-
"keep-alive-for-test" => nil,
|
|
19
|
-
"disable-popup-blocking" => nil,
|
|
20
|
-
"disable-extensions" => nil,
|
|
21
|
-
"disable-component-extensions-with-background-pages" => nil,
|
|
22
|
-
"disable-hang-monitor" => nil,
|
|
23
|
-
"disable-features" => "site-per-process,IsolateOrigins,TranslateUI",
|
|
24
|
-
"disable-translate" => nil,
|
|
8
|
+
"allow-pre-commit-input" => nil,
|
|
25
9
|
"disable-background-networking" => nil,
|
|
26
|
-
"enable-features" => "NetworkService,NetworkServiceInProcess",
|
|
27
10
|
"disable-background-timer-throttling" => nil,
|
|
28
11
|
"disable-backgrounding-occluded-windows" => nil,
|
|
12
|
+
"disable-blink-features" => "AutomationControlled",
|
|
13
|
+
"disable-breakpad" => nil,
|
|
29
14
|
"disable-client-side-phishing-detection" => nil,
|
|
15
|
+
"disable-component-extensions-with-background-pages" => nil,
|
|
16
|
+
"disable-component-update" => nil,
|
|
17
|
+
"disable-crash-reporter" => nil,
|
|
30
18
|
"disable-default-apps" => nil,
|
|
31
19
|
"disable-dev-shm-usage" => nil,
|
|
20
|
+
"disable-extensions" => nil,
|
|
21
|
+
"disable-features" => %w[
|
|
22
|
+
site-per-process
|
|
23
|
+
IsolateOrigins
|
|
24
|
+
TranslateUI
|
|
25
|
+
Translate
|
|
26
|
+
MacAppCodeSignClone
|
|
27
|
+
InterestFeedContentSuggestion
|
|
28
|
+
OptimizationHints
|
|
29
|
+
AcceptCHFrame
|
|
30
|
+
MediaRouter
|
|
31
|
+
].join(","),
|
|
32
|
+
"disable-field-trial-config" => nil,
|
|
33
|
+
"disable-hang-monitor" => nil,
|
|
34
|
+
"disable-infobars" => nil,
|
|
32
35
|
"disable-ipc-flooding-protection" => nil,
|
|
36
|
+
"disable-popup-blocking" => nil,
|
|
33
37
|
"disable-prompt-on-repost" => nil,
|
|
34
38
|
"disable-renderer-backgrounding" => nil,
|
|
39
|
+
"disable-search-engine-choice-screen" => nil,
|
|
40
|
+
"disable-session-crashed-bubble" => nil,
|
|
35
41
|
"disable-site-isolation-trials" => nil,
|
|
42
|
+
"disable-smooth-scrolling" => nil,
|
|
43
|
+
"disable-sync" => nil,
|
|
44
|
+
"disable-translate" => nil,
|
|
45
|
+
"disable-web-security" => nil,
|
|
46
|
+
"enable-automation" => nil,
|
|
47
|
+
"enable-features" => %w[
|
|
48
|
+
NetworkService
|
|
49
|
+
NetworkServiceInProcess
|
|
50
|
+
].join(","),
|
|
36
51
|
"force-color-profile" => "srgb",
|
|
52
|
+
"headless" => nil,
|
|
53
|
+
"hide-scrollbars" => nil,
|
|
54
|
+
"keep-alive-for-test" => nil,
|
|
37
55
|
"metrics-recording-only" => nil,
|
|
38
|
-
"
|
|
39
|
-
"
|
|
56
|
+
"mute-audio" => nil,
|
|
57
|
+
"no-crash-upload" => nil,
|
|
58
|
+
"no-default-browser-check" => nil,
|
|
59
|
+
"no-first-run" => nil,
|
|
40
60
|
"no-startup-window" => nil,
|
|
61
|
+
"password-store" => "basic",
|
|
41
62
|
"remote-allow-origins" => "*",
|
|
42
|
-
"disable-
|
|
43
|
-
|
|
44
|
-
# https://github.com/ebidel/lighthouse-ci/blob/master/builder/Dockerfile#L35-L40
|
|
45
|
-
# "no-sandbox" => nil,
|
|
63
|
+
"safebrowsing-disable-auto-update" => nil,
|
|
64
|
+
"use-mock-keychain" => nil
|
|
46
65
|
}.freeze
|
|
47
66
|
|
|
48
67
|
MAC_BIN_PATH = [
|
|
@@ -76,15 +95,23 @@ module Ferrum
|
|
|
76
95
|
end
|
|
77
96
|
|
|
78
97
|
def merge_default(flags, options)
|
|
79
|
-
defaults = except("headless", "disable-gpu")
|
|
80
|
-
defaults ||= DEFAULT_OPTIONS
|
|
98
|
+
defaults = options.headless == false ? except("headless", "disable-gpu") : DEFAULT_OPTIONS
|
|
81
99
|
defaults.delete("no-startup-window") if options.incognito == false
|
|
100
|
+
|
|
101
|
+
if options.dockerize || ENV["FERRUM_CHROME_DOCKERIZE"] == "true"
|
|
102
|
+
# NOTE: --no-sandbox is not needed if you properly set up a user in the container.
|
|
103
|
+
# https://github.com/ebidel/lighthouse-ci/blob/master/builder/Dockerfile#L35-L40
|
|
104
|
+
defaults = defaults.merge("no-sandbox" => nil, "disable-setuid-sandbox" => nil)
|
|
105
|
+
end
|
|
106
|
+
|
|
82
107
|
# On Windows, the --disable-gpu flag is a temporary workaround for a few bugs.
|
|
83
108
|
# See https://bugs.chromium.org/p/chromium/issues/detail?id=737678 for more information.
|
|
84
109
|
defaults = defaults.merge("disable-gpu" => nil) if Utils::Platform.windows?
|
|
110
|
+
|
|
85
111
|
# Use Metal on Apple Silicon
|
|
86
112
|
# https://github.com/google/angle#platform-support-via-backing-renderers
|
|
87
113
|
defaults = defaults.merge("use-angle" => "metal") if Utils::Platform.mac_arm?
|
|
114
|
+
|
|
88
115
|
defaults.merge(flags)
|
|
89
116
|
end
|
|
90
117
|
end
|
|
@@ -14,7 +14,7 @@ module Ferrum
|
|
|
14
14
|
attr_reader :window_size, :logger, :ws_max_receive_size,
|
|
15
15
|
:js_errors, :base_url, :slowmo, :pending_connection_errors,
|
|
16
16
|
:url, :ws_url, :env, :process_timeout, :browser_name, :browser_path,
|
|
17
|
-
:save_path, :proxy, :port, :host, :headless, :incognito, :browser_options,
|
|
17
|
+
:save_path, :proxy, :port, :host, :headless, :incognito, :dockerize, :browser_options,
|
|
18
18
|
:ignore_default_browser_options, :xvfb, :flatten
|
|
19
19
|
attr_accessor :timeout, :default_user_agent
|
|
20
20
|
|
|
@@ -28,6 +28,7 @@ module Ferrum
|
|
|
28
28
|
@js_errors = @options.fetch(:js_errors, false)
|
|
29
29
|
@headless = @options.fetch(:headless, true)
|
|
30
30
|
@incognito = @options.fetch(:incognito, true)
|
|
31
|
+
@dockerize = @options.fetch(:dockerize, false)
|
|
31
32
|
@flatten = @options.fetch(:flatten, true)
|
|
32
33
|
@pending_connection_errors = @options.fetch(:pending_connection_errors, true)
|
|
33
34
|
@process_timeout = @options.fetch(:process_timeout, PROCESS_TIMEOUT)
|
|
@@ -18,11 +18,8 @@ module Ferrum
|
|
|
18
18
|
KILL_TIMEOUT = 2
|
|
19
19
|
WAIT_KILLED = 0.05
|
|
20
20
|
|
|
21
|
-
attr_reader :host, :port, :ws_url, :pid, :command,
|
|
22
|
-
:default_user_agent, :browser_version, :protocol_version,
|
|
23
|
-
:v8_version, :webkit_version, :xvfb
|
|
24
|
-
|
|
25
21
|
extend Forwardable
|
|
22
|
+
|
|
26
23
|
delegate path: :command
|
|
27
24
|
|
|
28
25
|
def self.start(*args)
|
|
@@ -61,6 +58,10 @@ module Ferrum
|
|
|
61
58
|
}
|
|
62
59
|
end
|
|
63
60
|
|
|
61
|
+
attr_reader :host, :port, :ws_url, :pid, :command,
|
|
62
|
+
:default_user_agent, :browser_version, :protocol_version,
|
|
63
|
+
:v8_version, :webkit_version, :xvfb
|
|
64
|
+
|
|
64
65
|
def initialize(options)
|
|
65
66
|
@pid = @xvfb = @user_data_dir = nil
|
|
66
67
|
|
data/lib/ferrum/browser.rb
CHANGED
|
@@ -15,6 +15,7 @@ require "ferrum/browser/version_info"
|
|
|
15
15
|
module Ferrum
|
|
16
16
|
class Browser
|
|
17
17
|
extend Forwardable
|
|
18
|
+
|
|
18
19
|
delegate %i[default_context] => :contexts
|
|
19
20
|
delegate %i[targets create_target page pages windows] => :default_context
|
|
20
21
|
delegate %i[go_to goto go back forward refresh reload stop wait_for_reload
|
|
@@ -48,6 +49,9 @@ module Ferrum
|
|
|
48
49
|
# @option options [Boolean] :incognito (true)
|
|
49
50
|
# Create an incognito profile for the browser startup window.
|
|
50
51
|
#
|
|
52
|
+
# @option options [Boolean] :dockerize (false)
|
|
53
|
+
# Add CLI flags to a browser to run in a container.
|
|
54
|
+
#
|
|
51
55
|
# @option options [Boolean] :xvfb (false)
|
|
52
56
|
# Run browser in a virtual framebuffer.
|
|
53
57
|
#
|
|
@@ -77,7 +81,7 @@ module Ferrum
|
|
|
77
81
|
# @option options [Boolean] :js_errors
|
|
78
82
|
# When true, JavaScript errors get re-raised in Ruby.
|
|
79
83
|
#
|
|
80
|
-
# @option options [Boolean] :pending_connection_errors (
|
|
84
|
+
# @option options [Boolean] :pending_connection_errors (false)
|
|
81
85
|
# When main frame is still waiting for slow responses while timeout is
|
|
82
86
|
# reached {PendingConnectionsError} is raised. It's better to figure out
|
|
83
87
|
# why you have slow responses and fix or block them rather than turn this
|
|
@@ -295,6 +299,8 @@ module Ferrum
|
|
|
295
299
|
end
|
|
296
300
|
|
|
297
301
|
def build_remote_debug_url(path:)
|
|
302
|
+
return path if Addressable::URI.parse(path).absolute?
|
|
303
|
+
|
|
298
304
|
"http://#{process.host}:#{process.port}#{path}"
|
|
299
305
|
end
|
|
300
306
|
end
|
|
@@ -19,7 +19,7 @@ module Ferrum
|
|
|
19
19
|
uri = URI.parse(@url)
|
|
20
20
|
port = uri.port || DEFAULT_PORTS[uri.scheme]
|
|
21
21
|
|
|
22
|
-
if port == 443
|
|
22
|
+
if port == 443 || url.scheme == "wss"
|
|
23
23
|
tcp = TCPSocket.new(uri.host, port)
|
|
24
24
|
ssl_context = OpenSSL::SSL::SSLContext.new
|
|
25
25
|
@sock = OpenSSL::SSL::SSLSocket.new(tcp, ssl_context)
|
data/lib/ferrum/client.rb
CHANGED
|
@@ -24,8 +24,8 @@ module Ferrum
|
|
|
24
24
|
@client.send_message(message, async: async)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
def on(event, &
|
|
28
|
-
@client.on(event_name(event), &
|
|
27
|
+
def on(event, &)
|
|
28
|
+
@client.on(event_name(event), &)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def off(event, id)
|
|
@@ -40,8 +40,8 @@ module Ferrum
|
|
|
40
40
|
@client.respond_to?(name, include_private)
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
def method_missing(name,
|
|
44
|
-
@client.send(name,
|
|
43
|
+
def method_missing(name, ...)
|
|
44
|
+
@client.send(name, ...)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def close
|
|
@@ -61,6 +61,7 @@ module Ferrum
|
|
|
61
61
|
|
|
62
62
|
class Client
|
|
63
63
|
extend Forwardable
|
|
64
|
+
|
|
64
65
|
delegate %i[timeout timeout=] => :options
|
|
65
66
|
|
|
66
67
|
attr_reader :ws_url, :options, :subscriber
|
|
@@ -101,8 +102,8 @@ module Ferrum
|
|
|
101
102
|
end
|
|
102
103
|
end
|
|
103
104
|
|
|
104
|
-
def on(event, &
|
|
105
|
-
@subscriber.on(event, &
|
|
105
|
+
def on(event, &)
|
|
106
|
+
@subscriber.on(event, &)
|
|
106
107
|
end
|
|
107
108
|
|
|
108
109
|
def off(event, id)
|
data/lib/ferrum/context.rb
CHANGED
|
@@ -61,6 +61,8 @@ module Ferrum
|
|
|
61
61
|
new_target = Target.new(@client, session_id, params)
|
|
62
62
|
# `put_if_absent` returns nil if added a new value or existing if there was one already
|
|
63
63
|
target = @targets.put_if_absent(new_target.id, new_target) || new_target
|
|
64
|
+
# on first iteration session_id may be nil, then if session is present here we must set it to the target
|
|
65
|
+
target.session_id = session_id if session_id && target.session_id.nil?
|
|
64
66
|
@default_target ||= target
|
|
65
67
|
|
|
66
68
|
new_pending = Concurrent::IVar.new
|
data/lib/ferrum/contexts.rb
CHANGED
|
@@ -22,10 +22,10 @@ module Ferrum
|
|
|
22
22
|
@default_context ||= create
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
def each(&
|
|
25
|
+
def each(&)
|
|
26
26
|
return enum_for(__method__) unless block_given?
|
|
27
27
|
|
|
28
|
-
@contexts.each(&
|
|
28
|
+
@contexts.each(&)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def [](id)
|
|
@@ -48,6 +48,8 @@ module Ferrum
|
|
|
48
48
|
|
|
49
49
|
def dispose(context_id)
|
|
50
50
|
context = @contexts[context_id]
|
|
51
|
+
return unless context
|
|
52
|
+
|
|
51
53
|
context.close_targets_connection
|
|
52
54
|
@client.command("Target.disposeBrowserContext", browserContextId: context.id)
|
|
53
55
|
@contexts.delete(context_id)
|
|
@@ -59,8 +61,9 @@ module Ferrum
|
|
|
59
61
|
end
|
|
60
62
|
|
|
61
63
|
def reset
|
|
62
|
-
|
|
63
|
-
@
|
|
64
|
+
context_ids = @client.command("Target.getBrowserContexts")["browserContextIds"]
|
|
65
|
+
@default_context = nil if context_ids.include?(@default_context&.id)
|
|
66
|
+
@contexts.each_key { |id| dispose(id) if context_ids.include?(id) }
|
|
64
67
|
end
|
|
65
68
|
|
|
66
69
|
def size
|
|
@@ -69,18 +72,13 @@ module Ferrum
|
|
|
69
72
|
|
|
70
73
|
private
|
|
71
74
|
|
|
72
|
-
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
|
73
|
-
def subscribe
|
|
75
|
+
def subscribe # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
|
74
76
|
@client.on("Target.attachedToTarget") do |params|
|
|
75
77
|
info, session_id = params.values_at("targetInfo", "sessionId")
|
|
76
78
|
next unless ALLOWED_TARGET_TYPES.include?(info["type"])
|
|
77
79
|
|
|
78
80
|
context_id = info["browserContextId"]
|
|
79
|
-
|
|
80
|
-
context = Context.new(@client, self, context_id)
|
|
81
|
-
@contexts[context_id] = context
|
|
82
|
-
@default_context ||= context
|
|
83
|
-
end
|
|
81
|
+
add_context(context_id)
|
|
84
82
|
|
|
85
83
|
@contexts[context_id]&.add_target(session_id: session_id, params: info)
|
|
86
84
|
if params["waitingForDebugger"]
|
|
@@ -93,9 +91,10 @@ module Ferrum
|
|
|
93
91
|
next unless ALLOWED_TARGET_TYPES.include?(info["type"])
|
|
94
92
|
|
|
95
93
|
context_id = info["browserContextId"]
|
|
94
|
+
add_context(context_id)
|
|
96
95
|
|
|
97
96
|
if info["type"] == "iframe" &&
|
|
98
|
-
(target = @contexts[context_id]
|
|
97
|
+
(target = @contexts[context_id]&.find_target { |t| t.connected? && t.page.frame_by(id: info["targetId"]) })
|
|
99
98
|
@contexts[context_id]&.add_target(session_id: target.page.client.session_id, params: info)
|
|
100
99
|
else
|
|
101
100
|
@contexts[context_id]&.add_target(params: info)
|
|
@@ -120,16 +119,21 @@ module Ferrum
|
|
|
120
119
|
context&.delete_target(params["targetId"])
|
|
121
120
|
end
|
|
122
121
|
end
|
|
123
|
-
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
|
124
122
|
|
|
125
123
|
def discover
|
|
126
124
|
@client.command("Target.setDiscoverTargets", discover: true)
|
|
127
125
|
end
|
|
128
126
|
|
|
129
127
|
def auto_attach
|
|
130
|
-
return unless @client.options.flatten
|
|
131
|
-
|
|
132
128
|
@client.command("Target.setAutoAttach", autoAttach: true, waitForDebuggerOnStart: true, flatten: true)
|
|
133
129
|
end
|
|
130
|
+
|
|
131
|
+
def add_context(context_id)
|
|
132
|
+
return if @contexts[context_id]
|
|
133
|
+
|
|
134
|
+
context = Context.new(@client, self, context_id)
|
|
135
|
+
@contexts[context_id] = context
|
|
136
|
+
@default_context ||= context # rubocop:disable Naming/MemoizedInstanceVariableName
|
|
137
|
+
end
|
|
134
138
|
end
|
|
135
139
|
end
|
data/lib/ferrum/errors.rb
CHANGED
|
@@ -113,9 +113,10 @@ module Ferrum
|
|
|
113
113
|
class JavaScriptError < BrowserError
|
|
114
114
|
attr_reader :class_name, :message, :stack_trace
|
|
115
115
|
|
|
116
|
-
def initialize(response
|
|
117
|
-
@class_name, @message = response
|
|
118
|
-
@
|
|
116
|
+
def initialize(response)
|
|
117
|
+
@class_name, @message = response["exception"]&.values_at("className", "description")
|
|
118
|
+
@message ||= response["text"]
|
|
119
|
+
@stack_trace = response["stackTrace"]
|
|
119
120
|
super(response.merge("message" => @message))
|
|
120
121
|
end
|
|
121
122
|
end
|
data/lib/ferrum/frame/runtime.rb
CHANGED
|
@@ -124,7 +124,9 @@ module Ferrum
|
|
|
124
124
|
#
|
|
125
125
|
# @return [String]
|
|
126
126
|
#
|
|
127
|
-
|
|
127
|
+
# @raise [Ferrum::BrowserError]
|
|
128
|
+
#
|
|
129
|
+
def body!
|
|
128
130
|
@body ||= begin
|
|
129
131
|
body, encoded = @page.command("Network.getResponseBody", requestId: id)
|
|
130
132
|
.values_at("body", "base64Encoded")
|
|
@@ -132,6 +134,17 @@ module Ferrum
|
|
|
132
134
|
end
|
|
133
135
|
end
|
|
134
136
|
|
|
137
|
+
#
|
|
138
|
+
# The response body.
|
|
139
|
+
#
|
|
140
|
+
# @return [String, nil]
|
|
141
|
+
#
|
|
142
|
+
def body
|
|
143
|
+
body!
|
|
144
|
+
rescue Ferrum::BrowserError
|
|
145
|
+
# nop
|
|
146
|
+
end
|
|
147
|
+
|
|
135
148
|
#
|
|
136
149
|
# @return [Boolean]
|
|
137
150
|
#
|
data/lib/ferrum/network.rb
CHANGED
|
@@ -17,7 +17,7 @@ module Ferrum
|
|
|
17
17
|
SignedExchange Ping CSPViolationReport Preflight Other].freeze
|
|
18
18
|
AUTHORIZE_BLOCK_MISSING = "Block is missing, call `authorize(...) { |r| r.continue } " \
|
|
19
19
|
"or subscribe to `on(:request)` events before calling it"
|
|
20
|
-
AUTHORIZE_TYPE_WRONG = ":type should be in #{AUTHORIZE_TYPE}"
|
|
20
|
+
AUTHORIZE_TYPE_WRONG = ":type should be in #{AUTHORIZE_TYPE}".freeze
|
|
21
21
|
ALLOWED_CONNECTION_TYPE = %w[none cellular2g cellular3g cellular4g bluetooth ethernet wifi wimax other].freeze
|
|
22
22
|
|
|
23
23
|
# Network traffic.
|
|
@@ -6,7 +6,7 @@ module Ferrum
|
|
|
6
6
|
#
|
|
7
7
|
# Returns playback rate for CSS animations, defaults to `1`.
|
|
8
8
|
#
|
|
9
|
-
# @return [
|
|
9
|
+
# @return [Number]
|
|
10
10
|
#
|
|
11
11
|
def playback_rate
|
|
12
12
|
command("Animation.getPlaybackRate")["playbackRate"]
|
|
@@ -15,7 +15,7 @@ module Ferrum
|
|
|
15
15
|
#
|
|
16
16
|
# Sets playback rate of CSS animations.
|
|
17
17
|
#
|
|
18
|
-
# @param [
|
|
18
|
+
# @param [Number] value
|
|
19
19
|
#
|
|
20
20
|
# @example
|
|
21
21
|
# browser = Ferrum::Browser.new
|
|
@@ -266,11 +266,11 @@ module Ferrum
|
|
|
266
266
|
def bounding_rect(selector)
|
|
267
267
|
rect = evaluate_async(%(
|
|
268
268
|
const rect = document
|
|
269
|
-
.querySelector(
|
|
269
|
+
.querySelector(arguments[0])
|
|
270
270
|
.getBoundingClientRect();
|
|
271
271
|
const {x, y, width, height} = rect;
|
|
272
|
-
arguments[
|
|
273
|
-
), timeout)
|
|
272
|
+
arguments[1]([x, y, width, height])
|
|
273
|
+
), timeout, selector)
|
|
274
274
|
|
|
275
275
|
{ x: rect[0], y: rect[1], width: rect[2], height: rect[3] }
|
|
276
276
|
end
|
data/lib/ferrum/page.rb
CHANGED
|
@@ -21,6 +21,7 @@ module Ferrum
|
|
|
21
21
|
GOTO_WAIT = ENV.fetch("FERRUM_GOTO_WAIT", 0.1).to_f
|
|
22
22
|
|
|
23
23
|
extend Forwardable
|
|
24
|
+
|
|
24
25
|
delegate %i[at_css at_xpath css xpath
|
|
25
26
|
current_url current_title url title body doctype content=
|
|
26
27
|
execution_id execution_id! evaluate evaluate_on evaluate_async execute evaluate_func
|
|
@@ -442,10 +443,7 @@ module Ferrum
|
|
|
442
443
|
if @options.js_errors
|
|
443
444
|
on("Runtime.exceptionThrown") do |params|
|
|
444
445
|
# FIXME: https://jvns.ca/blog/2015/11/27/why-rubys-timeout-is-dangerous-and-thread-dot-raise-is-terrifying/
|
|
445
|
-
Thread.main.raise JavaScriptError
|
|
446
|
-
params.dig("exceptionDetails", "exception"),
|
|
447
|
-
params.dig("exceptionDetails", "stackTrace")
|
|
448
|
-
)
|
|
446
|
+
Thread.main.raise JavaScriptError, params["exceptionDetails"]
|
|
449
447
|
end
|
|
450
448
|
end
|
|
451
449
|
|
data/lib/ferrum/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ferrum
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 0.17.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dmitry Vorotilin
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: addressable
|
|
@@ -152,7 +151,6 @@ metadata:
|
|
|
152
151
|
changelog_uri: https://github.com/rubycdp/ferrum/blob/main/CHANGELOG.md
|
|
153
152
|
source_code_uri: https://github.com/rubycdp/ferrum
|
|
154
153
|
rubygems_mfa_required: 'true'
|
|
155
|
-
post_install_message:
|
|
156
154
|
rdoc_options: []
|
|
157
155
|
require_paths:
|
|
158
156
|
- lib
|
|
@@ -160,15 +158,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
160
158
|
requirements:
|
|
161
159
|
- - ">="
|
|
162
160
|
- !ruby/object:Gem::Version
|
|
163
|
-
version:
|
|
161
|
+
version: '3.1'
|
|
164
162
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
163
|
requirements:
|
|
166
164
|
- - ">="
|
|
167
165
|
- !ruby/object:Gem::Version
|
|
168
166
|
version: '0'
|
|
169
167
|
requirements: []
|
|
170
|
-
rubygems_version:
|
|
171
|
-
signing_key:
|
|
168
|
+
rubygems_version: 4.0.6
|
|
172
169
|
specification_version: 4
|
|
173
170
|
summary: Ruby headless Chrome driver
|
|
174
171
|
test_files: []
|