ferrum 0.12 → 0.13
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/README.md +15 -20
- data/lib/ferrum/browser/client.rb +4 -4
- data/lib/ferrum/browser/command.rb +5 -6
- data/lib/ferrum/browser/options/base.rb +1 -4
- data/lib/ferrum/browser/options/chrome.rb +14 -9
- data/lib/ferrum/browser/options/firefox.rb +3 -6
- data/lib/ferrum/browser/options.rb +84 -0
- data/lib/ferrum/browser/process.rb +5 -6
- data/lib/ferrum/browser/version_info.rb +71 -0
- data/lib/ferrum/browser/xvfb.rb +1 -1
- data/lib/ferrum/browser.rb +176 -62
- data/lib/ferrum/context.rb +3 -2
- data/lib/ferrum/contexts.rb +2 -2
- data/lib/ferrum/cookies/cookie.rb +126 -0
- data/lib/ferrum/cookies.rb +86 -49
- data/lib/ferrum/dialog.rb +30 -0
- data/lib/ferrum/frame/dom.rb +177 -0
- data/lib/ferrum/frame/runtime.rb +41 -61
- data/lib/ferrum/frame.rb +90 -3
- data/lib/ferrum/headers.rb +28 -0
- data/lib/ferrum/keyboard.rb +45 -2
- data/lib/ferrum/mouse.rb +84 -0
- data/lib/ferrum/network/exchange.rb +86 -5
- data/lib/ferrum/network/request.rb +64 -0
- data/lib/ferrum/network/response.rb +83 -1
- data/lib/ferrum/network.rb +160 -0
- data/lib/ferrum/page/animation.rb +16 -0
- data/lib/ferrum/page/frames.rb +66 -11
- data/lib/ferrum/page/screenshot.rb +91 -0
- data/lib/ferrum/page/tracing.rb +26 -0
- data/lib/ferrum/page.rb +151 -32
- data/lib/ferrum/proxy.rb +91 -2
- data/lib/ferrum/target.rb +6 -4
- data/lib/ferrum/version.rb +1 -1
- metadata +5 -2
data/lib/ferrum/browser.rb
CHANGED
@@ -6,16 +6,14 @@ require "ferrum/page"
|
|
6
6
|
require "ferrum/proxy"
|
7
7
|
require "ferrum/contexts"
|
8
8
|
require "ferrum/browser/xvfb"
|
9
|
+
require "ferrum/browser/options"
|
9
10
|
require "ferrum/browser/process"
|
10
11
|
require "ferrum/browser/client"
|
11
12
|
require "ferrum/browser/binary"
|
13
|
+
require "ferrum/browser/version_info"
|
12
14
|
|
13
15
|
module Ferrum
|
14
16
|
class Browser
|
15
|
-
DEFAULT_TIMEOUT = ENV.fetch("FERRUM_DEFAULT_TIMEOUT", 5).to_i
|
16
|
-
WINDOW_SIZE = [1024, 768].freeze
|
17
|
-
BASE_URL_SCHEMA = %w[http https].freeze
|
18
|
-
|
19
17
|
extend Forwardable
|
20
18
|
delegate %i[default_context] => :contexts
|
21
19
|
delegate %i[targets create_target page pages windows] => :default_context
|
@@ -32,66 +30,146 @@ module Ferrum
|
|
32
30
|
playback_rate playback_rate=] => :page
|
33
31
|
delegate %i[default_user_agent] => :process
|
34
32
|
|
35
|
-
attr_reader :client, :process, :contexts, :
|
36
|
-
|
37
|
-
:proxy_server
|
38
|
-
attr_writer :timeout
|
33
|
+
attr_reader :client, :process, :contexts, :options, :window_size, :base_url
|
34
|
+
attr_accessor :timeout
|
39
35
|
|
36
|
+
#
|
37
|
+
# Initializes the browser.
|
38
|
+
#
|
39
|
+
# @param [Hash{Symbol => Object}, nil] options
|
40
|
+
# Additional browser options.
|
41
|
+
#
|
42
|
+
# @option options [Boolean] :headless (true)
|
43
|
+
# Set browser as headless or not.
|
44
|
+
#
|
45
|
+
# @option options [Boolean] :xvfb (false)
|
46
|
+
# Run browser in a virtual framebuffer.
|
47
|
+
#
|
48
|
+
# @option options [(Integer, Integer)] :window_size ([1024, 768])
|
49
|
+
# The dimensions of the browser window in which to test, expressed as a
|
50
|
+
# 2-element array, e.g. `[1024, 768]`.
|
51
|
+
#
|
52
|
+
# @option options [Array<String, Hash>] :extensions
|
53
|
+
# An array of paths to files or JS source code to be preloaded into the
|
54
|
+
# browser e.g.: `["/path/to/script.js", { source: "window.secret = 'top'" }]`
|
55
|
+
#
|
56
|
+
# @option options [#puts] :logger
|
57
|
+
# When present, debug output is written to this object.
|
58
|
+
#
|
59
|
+
# @option options [Integer, Float] :slowmo
|
60
|
+
# Set a delay in seconds to wait before sending command.
|
61
|
+
# Useful companion of headless option, so that you have time to see
|
62
|
+
# changes.
|
63
|
+
#
|
64
|
+
# @option options [Numeric] :timeout (5)
|
65
|
+
# The number of seconds we'll wait for a response when communicating with
|
66
|
+
# browser.
|
67
|
+
#
|
68
|
+
# @option options [Boolean] :js_errors
|
69
|
+
# When true, JavaScript errors get re-raised in Ruby.
|
70
|
+
#
|
71
|
+
# @option options [Boolean] :pending_connection_errors (true)
|
72
|
+
# When main frame is still waiting for slow responses while timeout is
|
73
|
+
# reached {PendingConnectionsError} is raised. It's better to figure out
|
74
|
+
# why you have slow responses and fix or block them rather than turn this
|
75
|
+
# setting off.
|
76
|
+
#
|
77
|
+
# @option options [:chrome, :firefox] :browser_name (:chrome)
|
78
|
+
# Sets the browser's name. **Note:** only experimental support for
|
79
|
+
# `:firefox` for now.
|
80
|
+
#
|
81
|
+
# @option options [String] :browser_path
|
82
|
+
# Path to Chrome binary, you can also set ENV variable as
|
83
|
+
# `BROWSER_PATH=some/path/chrome bundle exec rspec`.
|
84
|
+
#
|
85
|
+
# @option options [Hash] :browser_options
|
86
|
+
# Additional command line options, [see them all](https://peter.sh/experiments/chromium-command-line-switches/)
|
87
|
+
# e.g. `{ "ignore-certificate-errors" => nil }`
|
88
|
+
#
|
89
|
+
# @option options [Boolean] :ignore_default_browser_options
|
90
|
+
# Ferrum has a number of default options it passes to the browser,
|
91
|
+
# if you set this to `true` then only options you put in
|
92
|
+
# `:browser_options` will be passed to the browser, except required ones
|
93
|
+
# of course.
|
94
|
+
#
|
95
|
+
# @option options [Integer] :port
|
96
|
+
# Remote debugging port for headless Chrome.
|
97
|
+
#
|
98
|
+
# @option options [String] :host
|
99
|
+
# Remote debugging address for headless Chrome.
|
100
|
+
#
|
101
|
+
# @option options [String] :url
|
102
|
+
# URL for a running instance of Chrome. If this is set, a browser process
|
103
|
+
# will not be spawned.
|
104
|
+
#
|
105
|
+
# @option options [Integer] :process_timeout
|
106
|
+
# How long to wait for the Chrome process to respond on startup.
|
107
|
+
#
|
108
|
+
# @option options [Integer] :ws_max_receive_size
|
109
|
+
# How big messages to accept from Chrome over the web socket, in bytes.
|
110
|
+
# Defaults to 64MB. Incoming messages larger this will cause a
|
111
|
+
# {Ferrum::DeadBrowserError}.
|
112
|
+
#
|
113
|
+
# @option options [Hash] :proxy
|
114
|
+
# Specify proxy settings, [read more](https://github.com/rubycdp/ferrum#proxy).
|
115
|
+
#
|
116
|
+
# @option options [String] :save_path
|
117
|
+
# Path to save attachments with [Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)
|
118
|
+
# header.
|
119
|
+
#
|
120
|
+
# @option options [Hash] :env
|
121
|
+
# Environment variables you'd like to pass through to the process.
|
122
|
+
#
|
40
123
|
def initialize(options = nil)
|
41
|
-
options
|
42
|
-
|
43
|
-
@client = nil
|
44
|
-
@window_size = options.fetch(:window_size, WINDOW_SIZE)
|
45
|
-
@original_window_size = @window_size
|
46
|
-
|
47
|
-
@options = Hash(options.merge(window_size: @window_size))
|
48
|
-
@logger, @timeout, @ws_max_receive_size =
|
49
|
-
@options.values_at(:logger, :timeout, :ws_max_receive_size)
|
50
|
-
@js_errors = @options.fetch(:js_errors, false)
|
51
|
-
|
52
|
-
if @options[:proxy]
|
53
|
-
@proxy_options = @options[:proxy]
|
54
|
-
|
55
|
-
if @proxy_options[:server]
|
56
|
-
@proxy_server = Proxy.start(**@proxy_options.slice(:host, :port, :user, :password))
|
57
|
-
@proxy_options.merge!(host: @proxy_server.host, port: @proxy_server.port)
|
58
|
-
end
|
59
|
-
|
60
|
-
@options[:browser_options] ||= {}
|
61
|
-
address = "#{@proxy_options[:host]}:#{@proxy_options[:port]}"
|
62
|
-
@options[:browser_options].merge!("proxy-server" => address)
|
63
|
-
@options[:browser_options].merge!("proxy-bypass-list" => @proxy_options[:bypass]) if @proxy_options[:bypass]
|
64
|
-
end
|
65
|
-
|
66
|
-
@pending_connection_errors = @options.fetch(:pending_connection_errors, true)
|
67
|
-
@slowmo = @options[:slowmo].to_f
|
68
|
-
|
69
|
-
self.base_url = @options[:base_url] if @options.key?(:base_url)
|
70
|
-
|
71
|
-
if ENV.fetch("FERRUM_DEBUG", nil) && !@logger
|
72
|
-
$stdout.sync = true
|
73
|
-
@logger = $stdout
|
74
|
-
@options[:logger] = @logger
|
75
|
-
end
|
124
|
+
@options = Options.new(options)
|
125
|
+
@client = @process = @contexts = nil
|
76
126
|
|
77
|
-
@options.
|
127
|
+
@timeout = @options.timeout
|
128
|
+
@window_size = @options.window_size
|
129
|
+
@base_url = @options.base_url if @options.base_url
|
78
130
|
|
79
131
|
start
|
80
132
|
end
|
81
133
|
|
134
|
+
#
|
135
|
+
# Sets the base URL.
|
136
|
+
#
|
137
|
+
# @param [String] value
|
138
|
+
# The new base URL value.
|
139
|
+
#
|
140
|
+
# @raise [ArgumentError] when path is not absolute or doesn't include schema
|
141
|
+
#
|
142
|
+
# @return [Addressable::URI]
|
143
|
+
# The parsed base URI value.
|
144
|
+
#
|
82
145
|
def base_url=(value)
|
83
|
-
|
84
|
-
unless BASE_URL_SCHEMA.include?(parsed.normalized_scheme)
|
85
|
-
raise "Set `base_url` should be absolute and include schema: #{BASE_URL_SCHEMA}"
|
86
|
-
end
|
87
|
-
|
88
|
-
@base_url = parsed
|
146
|
+
@base_url = options.parse_base_url(value)
|
89
147
|
end
|
90
148
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
149
|
+
#
|
150
|
+
# Creates a new page.
|
151
|
+
#
|
152
|
+
# @param [Boolean] new_context
|
153
|
+
# Whether to create a page in a new context or not.
|
154
|
+
#
|
155
|
+
# @param [Hash] proxy
|
156
|
+
# Whether to use proxy for a page. The page will be created in a new context if so.
|
157
|
+
#
|
158
|
+
# @return [Ferrum::Page]
|
159
|
+
# Created page.
|
160
|
+
#
|
161
|
+
def create_page(new_context: false, proxy: nil)
|
162
|
+
page = if new_context || proxy
|
163
|
+
params = {}
|
164
|
+
|
165
|
+
if proxy
|
166
|
+
options.parse_proxy(proxy)
|
167
|
+
params.merge!(proxyServer: "#{proxy[:host]}:#{proxy[:port]}")
|
168
|
+
params.merge!(proxyBypassList: proxy[:bypass]) if proxy[:bypass]
|
169
|
+
end
|
170
|
+
|
171
|
+
context = contexts.create(**params)
|
172
|
+
context.create_page(proxy: proxy)
|
95
173
|
else
|
96
174
|
default_context.create_page
|
97
175
|
end
|
@@ -105,19 +183,28 @@ module Ferrum
|
|
105
183
|
end
|
106
184
|
|
107
185
|
def extensions
|
108
|
-
@extensions ||= Array(
|
186
|
+
@extensions ||= Array(options.extensions).map do |ext|
|
109
187
|
(ext.is_a?(Hash) && ext[:source]) || File.read(ext)
|
110
188
|
end
|
111
189
|
end
|
112
190
|
|
191
|
+
#
|
192
|
+
# Evaluate JavaScript to modify things before a page load.
|
193
|
+
#
|
194
|
+
# @param [String] expression
|
195
|
+
# The JavaScript to add to each new document.
|
196
|
+
#
|
197
|
+
# @example
|
198
|
+
# browser.evaluate_on_new_document <<~JS
|
199
|
+
# Object.defineProperty(navigator, "languages", {
|
200
|
+
# get: function() { return ["tlh"]; }
|
201
|
+
# });
|
202
|
+
# JS
|
203
|
+
#
|
113
204
|
def evaluate_on_new_document(expression)
|
114
205
|
extensions << expression
|
115
206
|
end
|
116
207
|
|
117
|
-
def timeout
|
118
|
-
@timeout || DEFAULT_TIMEOUT
|
119
|
-
end
|
120
|
-
|
121
208
|
def command(*args)
|
122
209
|
@client.command(*args)
|
123
210
|
rescue DeadBrowserError
|
@@ -125,8 +212,22 @@ module Ferrum
|
|
125
212
|
raise
|
126
213
|
end
|
127
214
|
|
215
|
+
#
|
216
|
+
# Closes browser tabs opened by the `Browser` instance.
|
217
|
+
#
|
218
|
+
# @example
|
219
|
+
# # connect to a long-running Chrome process
|
220
|
+
# browser = Ferrum::Browser.new(url: 'http://localhost:9222')
|
221
|
+
#
|
222
|
+
# browser.go_to("https://github.com/")
|
223
|
+
#
|
224
|
+
# # clean up, lest the tab stays there hanging forever
|
225
|
+
# browser.reset
|
226
|
+
#
|
227
|
+
# browser.quit
|
228
|
+
#
|
128
229
|
def reset
|
129
|
-
@window_size =
|
230
|
+
@window_size = options.window_size
|
130
231
|
contexts.reset
|
131
232
|
end
|
132
233
|
|
@@ -150,12 +251,25 @@ module Ferrum
|
|
150
251
|
command("Browser.crash")
|
151
252
|
end
|
152
253
|
|
254
|
+
#
|
255
|
+
# Gets the version information from the browser.
|
256
|
+
#
|
257
|
+
# @return [VersionInfo]
|
258
|
+
#
|
259
|
+
# @since 0.13
|
260
|
+
#
|
261
|
+
def version
|
262
|
+
VersionInfo.new(command("Browser.getVersion"))
|
263
|
+
end
|
264
|
+
|
153
265
|
private
|
154
266
|
|
155
267
|
def start
|
156
268
|
Utils::ElapsedTime.start
|
157
|
-
@process = Process.start(
|
158
|
-
@client = Client.new(
|
269
|
+
@process = Process.start(options)
|
270
|
+
@client = Client.new(@process.ws_url, self,
|
271
|
+
logger: options.logger,
|
272
|
+
ws_max_receive_size: options.ws_max_receive_size)
|
159
273
|
@contexts = Contexts.new(self)
|
160
274
|
end
|
161
275
|
end
|
data/lib/ferrum/context.rb
CHANGED
data/lib/ferrum/contexts.rb
CHANGED
@@ -23,8 +23,8 @@ module Ferrum
|
|
23
23
|
context
|
24
24
|
end
|
25
25
|
|
26
|
-
def create
|
27
|
-
response = @browser.command("Target.createBrowserContext")
|
26
|
+
def create(**options)
|
27
|
+
response = @browser.command("Target.createBrowserContext", **options)
|
28
28
|
context_id = response["browserContextId"]
|
29
29
|
context = Context.new(@browser, self, context_id)
|
30
30
|
@contexts[context_id] = context
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ferrum
|
4
|
+
class Cookies
|
5
|
+
#
|
6
|
+
# Represents a [cookie value](https://chromedevtools.github.io/devtools-protocol/1-3/Network/#type-Cookie).
|
7
|
+
#
|
8
|
+
class Cookie
|
9
|
+
# The parsed JSON attributes.
|
10
|
+
#
|
11
|
+
# @return [Hash{String => [String, Boolean, nil]}]
|
12
|
+
attr_reader :attributes
|
13
|
+
|
14
|
+
#
|
15
|
+
# Initializes the cookie.
|
16
|
+
#
|
17
|
+
# @param [Hash{String => String}] attributes
|
18
|
+
# The parsed JSON attributes.
|
19
|
+
#
|
20
|
+
def initialize(attributes)
|
21
|
+
@attributes = attributes
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# The cookie's name.
|
26
|
+
#
|
27
|
+
# @return [String]
|
28
|
+
#
|
29
|
+
def name
|
30
|
+
attributes["name"]
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# The cookie's value.
|
35
|
+
#
|
36
|
+
# @return [String]
|
37
|
+
#
|
38
|
+
def value
|
39
|
+
attributes["value"]
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# The cookie's domain.
|
44
|
+
#
|
45
|
+
# @return [String]
|
46
|
+
#
|
47
|
+
def domain
|
48
|
+
attributes["domain"]
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# The cookie's path.
|
53
|
+
#
|
54
|
+
# @return [String]
|
55
|
+
#
|
56
|
+
def path
|
57
|
+
attributes["path"]
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# The `sameSite` configuration.
|
62
|
+
#
|
63
|
+
# @return ["Strict", "Lax", "None", nil]
|
64
|
+
#
|
65
|
+
def samesite
|
66
|
+
attributes["sameSite"]
|
67
|
+
end
|
68
|
+
alias same_site samesite
|
69
|
+
|
70
|
+
#
|
71
|
+
# The cookie's size.
|
72
|
+
#
|
73
|
+
# @return [Integer]
|
74
|
+
#
|
75
|
+
def size
|
76
|
+
attributes["size"]
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# Specifies whether the cookie is secure or not.
|
81
|
+
#
|
82
|
+
# @return [Boolean]
|
83
|
+
#
|
84
|
+
def secure?
|
85
|
+
attributes["secure"]
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# Specifies whether the cookie is HTTP-only or not.
|
90
|
+
#
|
91
|
+
# @return [Boolean]
|
92
|
+
#
|
93
|
+
def httponly?
|
94
|
+
attributes["httpOnly"]
|
95
|
+
end
|
96
|
+
alias http_only? httponly?
|
97
|
+
|
98
|
+
#
|
99
|
+
# Specifies whether the cookie is a session cookie or not.
|
100
|
+
#
|
101
|
+
# @return [Boolean]
|
102
|
+
#
|
103
|
+
def session?
|
104
|
+
attributes["session"]
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# Specifies when the cookie will expire.
|
109
|
+
#
|
110
|
+
# @return [Time, nil]
|
111
|
+
#
|
112
|
+
def expires
|
113
|
+
Time.at(attributes["expires"]) if attributes["expires"].positive?
|
114
|
+
end
|
115
|
+
|
116
|
+
#
|
117
|
+
# Compares different cookie objects.
|
118
|
+
#
|
119
|
+
# @return [Boolean]
|
120
|
+
#
|
121
|
+
def ==(other)
|
122
|
+
other.class == self.class && other.attributes == attributes
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/lib/ferrum/cookies.rb
CHANGED
@@ -1,68 +1,83 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "ferrum/cookies/cookie"
|
4
|
+
|
3
5
|
module Ferrum
|
4
6
|
class Cookies
|
5
|
-
class Cookie
|
6
|
-
attr_reader :attributes
|
7
|
-
|
8
|
-
def initialize(attributes)
|
9
|
-
@attributes = attributes
|
10
|
-
end
|
11
|
-
|
12
|
-
def name
|
13
|
-
@attributes["name"]
|
14
|
-
end
|
15
|
-
|
16
|
-
def value
|
17
|
-
@attributes["value"]
|
18
|
-
end
|
19
|
-
|
20
|
-
def domain
|
21
|
-
@attributes["domain"]
|
22
|
-
end
|
23
|
-
|
24
|
-
def path
|
25
|
-
@attributes["path"]
|
26
|
-
end
|
27
|
-
|
28
|
-
def samesite
|
29
|
-
@attributes["sameSite"]
|
30
|
-
end
|
31
|
-
|
32
|
-
def size
|
33
|
-
@attributes["size"]
|
34
|
-
end
|
35
|
-
|
36
|
-
def secure?
|
37
|
-
@attributes["secure"]
|
38
|
-
end
|
39
|
-
|
40
|
-
def httponly?
|
41
|
-
@attributes["httpOnly"]
|
42
|
-
end
|
43
|
-
|
44
|
-
def session?
|
45
|
-
@attributes["session"]
|
46
|
-
end
|
47
|
-
|
48
|
-
def expires
|
49
|
-
Time.at(@attributes["expires"]) if @attributes["expires"].positive?
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
7
|
def initialize(page)
|
54
8
|
@page = page
|
55
9
|
end
|
56
10
|
|
11
|
+
#
|
12
|
+
# Returns cookies hash.
|
13
|
+
#
|
14
|
+
# @return [Hash{String => Cookie}]
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# browser.cookies.all # => {
|
18
|
+
# # "NID" => #<Ferrum::Cookies::Cookie:0x0000558624b37a40 @attributes={
|
19
|
+
# # "name"=>"NID", "value"=>"...", "domain"=>".google.com", "path"=>"/",
|
20
|
+
# # "expires"=>1583211046.575681, "size"=>178, "httpOnly"=>true, "secure"=>false, "session"=>false
|
21
|
+
# # }>
|
22
|
+
# # }
|
23
|
+
#
|
57
24
|
def all
|
58
25
|
cookies = @page.command("Network.getAllCookies")["cookies"]
|
59
26
|
cookies.to_h { |c| [c["name"], Cookie.new(c)] }
|
60
27
|
end
|
61
28
|
|
29
|
+
#
|
30
|
+
# Returns cookie.
|
31
|
+
#
|
32
|
+
# @param [String] name
|
33
|
+
# The cookie name to fetch.
|
34
|
+
#
|
35
|
+
# @return [Cookie, nil]
|
36
|
+
# The cookie with the matching name.
|
37
|
+
#
|
38
|
+
# @example
|
39
|
+
# browser.cookies["NID"] # =>
|
40
|
+
# # <Ferrum::Cookies::Cookie:0x0000558624b67a88 @attributes={
|
41
|
+
# # "name"=>"NID", "value"=>"...", "domain"=>".google.com",
|
42
|
+
# # "path"=>"/", "expires"=>1583211046.575681, "size"=>178,
|
43
|
+
# # "httpOnly"=>true, "secure"=>false, "session"=>false
|
44
|
+
# # }>
|
45
|
+
#
|
62
46
|
def [](name)
|
63
47
|
all[name]
|
64
48
|
end
|
65
49
|
|
50
|
+
#
|
51
|
+
# Sets a cookie.
|
52
|
+
#
|
53
|
+
# @param [Hash{Symbol => Object}, Cookie] options
|
54
|
+
#
|
55
|
+
# @option options [String] :name
|
56
|
+
#
|
57
|
+
# @option options [String] :value
|
58
|
+
#
|
59
|
+
# @option options [String] :domain
|
60
|
+
#
|
61
|
+
# @option options [String] :path
|
62
|
+
#
|
63
|
+
# @option options [Integer] :expires
|
64
|
+
#
|
65
|
+
# @option options [Integer] :size
|
66
|
+
#
|
67
|
+
# @option options [Boolean] :httponly
|
68
|
+
#
|
69
|
+
# @option options [Boolean] :secure
|
70
|
+
#
|
71
|
+
# @option options [String] :samesite
|
72
|
+
#
|
73
|
+
#
|
74
|
+
# @example
|
75
|
+
# browser.cookies.set(name: "stealth", value: "omg", domain: "google.com") # => true
|
76
|
+
#
|
77
|
+
# @example
|
78
|
+
# nid_cookie = browser.cookies["NID"] # => <Ferrum::Cookies::Cookie:0x0000558624b67a88>
|
79
|
+
# browser.cookies.set(nid_cookie) # => true
|
80
|
+
#
|
66
81
|
def set(options)
|
67
82
|
cookie = (
|
68
83
|
options.is_a?(Cookie) ? options.attributes : options
|
@@ -79,7 +94,21 @@ module Ferrum
|
|
79
94
|
@page.command("Network.setCookie", **cookie)["success"]
|
80
95
|
end
|
81
96
|
|
82
|
-
#
|
97
|
+
#
|
98
|
+
# Removes given cookie.
|
99
|
+
#
|
100
|
+
# @param [String] name
|
101
|
+
#
|
102
|
+
# @param [Hash{Symbol => Object}] options
|
103
|
+
# Additional keyword arguments.
|
104
|
+
#
|
105
|
+
# @option options [String] :domain
|
106
|
+
#
|
107
|
+
# @option options [String] :url
|
108
|
+
#
|
109
|
+
# @example
|
110
|
+
# browser.cookies.remove(name: "stealth", domain: "google.com") # => true
|
111
|
+
#
|
83
112
|
def remove(name:, **options)
|
84
113
|
raise "Specify :domain or :url option" if !options[:domain] && !options[:url] && !default_domain
|
85
114
|
|
@@ -91,6 +120,14 @@ module Ferrum
|
|
91
120
|
true
|
92
121
|
end
|
93
122
|
|
123
|
+
#
|
124
|
+
# Removes all cookies for current page.
|
125
|
+
#
|
126
|
+
# @return [true]
|
127
|
+
#
|
128
|
+
# @example
|
129
|
+
# browser.cookies.clear # => true
|
130
|
+
#
|
94
131
|
def clear
|
95
132
|
@page.command("Network.clearBrowserCookies")
|
96
133
|
true
|
data/lib/ferrum/dialog.rb
CHANGED
@@ -10,6 +10,22 @@ module Ferrum
|
|
10
10
|
@default_prompt = params["defaultPrompt"]
|
11
11
|
end
|
12
12
|
|
13
|
+
#
|
14
|
+
# Accept dialog with given text or default prompt if applicable
|
15
|
+
#
|
16
|
+
# @param [String, nil] prompt_text
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# browser = Ferrum::Browser.new
|
20
|
+
# browser.on(:dialog) do |dialog|
|
21
|
+
# if dialog.match?(/bla-bla/)
|
22
|
+
# dialog.accept
|
23
|
+
# else
|
24
|
+
# dialog.dismiss
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
# browser.go_to("https://google.com")
|
28
|
+
#
|
13
29
|
def accept(prompt_text = nil)
|
14
30
|
options = { accept: true }
|
15
31
|
response = prompt_text || default_prompt
|
@@ -17,6 +33,20 @@ module Ferrum
|
|
17
33
|
@page.command("Page.handleJavaScriptDialog", slowmoable: true, **options)
|
18
34
|
end
|
19
35
|
|
36
|
+
#
|
37
|
+
# Dismiss dialog.
|
38
|
+
#
|
39
|
+
# @example
|
40
|
+
# browser = Ferrum::Browser.new
|
41
|
+
# browser.on(:dialog) do |dialog|
|
42
|
+
# if dialog.match?(/bla-bla/)
|
43
|
+
# dialog.accept
|
44
|
+
# else
|
45
|
+
# dialog.dismiss
|
46
|
+
# end
|
47
|
+
# end
|
48
|
+
# browser.go_to("https://google.com")
|
49
|
+
#
|
20
50
|
def dismiss
|
21
51
|
@page.command("Page.handleJavaScriptDialog", slowmoable: true, accept: false)
|
22
52
|
end
|