ferrum 0.15 → 0.17

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.
@@ -8,6 +8,9 @@ module Ferrum
8
8
  FULL_WARNING = "Ignoring :selector or :area in #screenshot since full: true was given at %s"
9
9
  AREA_WARNING = "Ignoring :area in #screenshot since selector: was given at %s"
10
10
 
11
+ DEFAULT_SCREENSHOT_FORMAT = "png"
12
+ SUPPORTED_SCREENSHOT_FORMAT = %w[png jpeg jpg webp].freeze
13
+
11
14
  DEFAULT_PDF_OPTIONS = {
12
15
  landscape: false,
13
16
  paper_width: 8.5,
@@ -41,7 +44,7 @@ module Ferrum
41
44
  # @option opts [:base64, :binary] :encoding
42
45
  # The encoding the image should be returned in.
43
46
  #
44
- # @option opts ["jpeg", "png"] :format
47
+ # @option opts ["jpeg", "jpg", "png", "webp"] :format
45
48
  # The format the image should be returned in.
46
49
  #
47
50
  # @option opts [Integer] :quality
@@ -71,8 +74,11 @@ module Ferrum
71
74
  # @example Save on the disk in JPG:
72
75
  # page.screenshot(path: "google.jpg") # => 30902
73
76
  #
77
+ # @example Save to Base64 in WebP with reduce quality:
78
+ # page.screenshot(format: "webp", quality: 60) # "iVBORw0KGgoAAAANS...
79
+ #
74
80
  # @example Save to Base64 the whole page not only viewport and reduce quality:
75
- # page.screenshot(full: true, quality: 60) # "iVBORw0KGgoAAAANS...
81
+ # page.screenshot(full: true, format: "jpeg", quality: 60) # "iVBORw0KGgoAAAANS...
76
82
  #
77
83
  # @example Save with specific background color:
78
84
  # page.screenshot(background_color: Ferrum::RGBA.new(0, 0, 0, 0.0))
@@ -211,11 +217,19 @@ module Ferrum
211
217
  end
212
218
 
213
219
  def format_options(format, path, quality)
214
- format ||= path ? File.extname(path).delete(".") : "png"
220
+ if !format && path # try to infer from path
221
+ extension = File.extname(path).delete(".").downcase
222
+ format = extension unless extension.empty?
223
+ end
224
+
225
+ format ||= DEFAULT_SCREENSHOT_FORMAT
226
+ format = format.to_s
227
+ raise Ferrum::InvalidScreenshotFormatError, format unless SUPPORTED_SCREENSHOT_FORMAT.include?(format)
228
+
215
229
  format = "jpeg" if format == "jpg"
216
- raise "Not supported options `:format` #{format}. jpeg | png" if format !~ /jpeg|png/i
217
230
 
218
- quality ||= 75 if format == "jpeg"
231
+ # Chrome supports screenshot qualities for JPEG and WebP
232
+ quality ||= 75 if format != "png"
219
233
 
220
234
  [format, quality]
221
235
  end
data/lib/ferrum/page.rb CHANGED
@@ -10,6 +10,7 @@ require "ferrum/dialog"
10
10
  require "ferrum/network"
11
11
  require "ferrum/downloads"
12
12
  require "ferrum/page/frames"
13
+ require "ferrum/page/screencast"
13
14
  require "ferrum/page/screenshot"
14
15
  require "ferrum/page/animation"
15
16
  require "ferrum/page/tracing"
@@ -27,6 +28,7 @@ module Ferrum
27
28
  delegate %i[base_url default_user_agent timeout timeout=] => :@options
28
29
 
29
30
  include Animation
31
+ include Screencast
30
32
  include Screenshot
31
33
  include Frames
32
34
  include Stream
@@ -336,6 +338,20 @@ module Ferrum
336
338
  enabled
337
339
  end
338
340
 
341
+ #
342
+ # Activates (focuses) the target for the given page.
343
+ # When you have multiple tabs you work with, and you need to switch a given one.
344
+ #
345
+ # @return [Boolean]
346
+ #
347
+ # @example
348
+ # page.activate # => true
349
+ #
350
+ def activate
351
+ command("Target.activateTarget", targetId: target_id)
352
+ true
353
+ end
354
+
339
355
  def command(method, wait: 0, slowmoable: false, **params)
340
356
  iteration = @event.reset if wait.positive?
341
357
  sleep(@options.slowmo) if slowmoable && @options.slowmo.positive?
@@ -379,6 +395,19 @@ module Ferrum
379
395
  end
380
396
  end
381
397
 
398
+ def off(name, id)
399
+ case name
400
+ when :dialog
401
+ client.off("Page.javascriptDialogOpening", id)
402
+ when :request
403
+ client.off("Fetch.requestPaused", id)
404
+ when :auth
405
+ client.off("Fetch.authRequired", id)
406
+ else
407
+ client.off(name, id)
408
+ end
409
+ end
410
+
382
411
  def subscribed?(event)
383
412
  client.subscribed?(event)
384
413
  end
@@ -391,7 +420,9 @@ module Ferrum
391
420
  use_proxy? && @proxy_user && @proxy_password
392
421
  end
393
422
 
394
- def document_node_id
423
+ def document_node_id(async: false)
424
+ return client.command("DOM.getDocument", async: true, depth: 0) if async
425
+
395
426
  command("DOM.getDocument", depth: 0).dig("root", "nodeId")
396
427
  end
397
428
 
@@ -459,7 +490,7 @@ module Ferrum
459
490
  # opens a new window for which `frameStoppedLoading` event never
460
491
  # occurs and thus search for nodes cannot be completed. Here we check
461
492
  # the history and if the transitionType for example `link` then
462
- # content is already loaded and we can try to get the document.
493
+ # content is already loaded, and we can try to get the document.
463
494
  document_node_id
464
495
  end
465
496
 
data/lib/ferrum/target.rb CHANGED
@@ -8,7 +8,8 @@ module Ferrum
8
8
  # where we enhance page class and build page ourselves.
9
9
  attr_writer :page
10
10
 
11
- attr_reader :session_id, :options
11
+ attr_reader :options
12
+ attr_accessor :session_id
12
13
 
13
14
  def initialize(browser_client, session_id = nil, params = nil)
14
15
  @page = nil
@@ -67,11 +68,19 @@ module Ferrum
67
68
  !!opener_id
68
69
  end
69
70
 
71
+ def iframe?
72
+ type == "iframe"
73
+ end
74
+
70
75
  def maybe_sleep_if_new_window
71
76
  # Dirty hack because new window doesn't have events at all
72
77
  sleep(NEW_WINDOW_WAIT) if window?
73
78
  end
74
79
 
80
+ def command(...)
81
+ client.command(...)
82
+ end
83
+
75
84
  private
76
85
 
77
86
  def build_client
@@ -9,6 +9,10 @@ module Ferrum
9
9
  @start ||= monotonic_time
10
10
  end
11
11
 
12
+ def reset
13
+ @start = monotonic_time
14
+ end
15
+
12
16
  def elapsed_time(start = nil)
13
17
  monotonic_time - (start || @start)
14
18
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ferrum
4
- VERSION = "0.15"
4
+ VERSION = "0.17"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ferrum
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.15'
4
+ version: '0.17'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Vorotilin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-17 00:00:00.000000000 Z
11
+ date: 2025-05-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: base64
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.2'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: concurrent-ruby
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -115,6 +129,7 @@ files:
115
129
  - lib/ferrum/page.rb
116
130
  - lib/ferrum/page/animation.rb
117
131
  - lib/ferrum/page/frames.rb
132
+ - lib/ferrum/page/screencast.rb
118
133
  - lib/ferrum/page/screenshot.rb
119
134
  - lib/ferrum/page/stream.rb
120
135
  - lib/ferrum/page/tracing.rb
@@ -152,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
167
  - !ruby/object:Gem::Version
153
168
  version: '0'
154
169
  requirements: []
155
- rubygems_version: 3.5.6
170
+ rubygems_version: 3.5.22
156
171
  signing_key:
157
172
  specification_version: 4
158
173
  summary: Ruby headless Chrome driver