Skip to content

Commit

Permalink
Support webp in screenshot
Browse files Browse the repository at this point in the history
  • Loading branch information
erickguan committed Jul 4, 2024
1 parent 19767d0 commit 6410b68
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- `Ferrum::Node#exists?` check whether the node in ruby world still exists in the DOM tree.
- `Ferrum::Cookies#store` stores all cookies of current page in a file.
- `Ferrum::Cookies#load` Loads all cookies from the file and sets them for current page.
- `Ferrum::Page#screenshot` supports webp image format

### Changed

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ Saves screenshot on a disk or returns it as base64.
`:binary` automatically
* :encoding `Symbol` `:base64` | `:binary` you can set it to return image as
Base64
* :format `String` "jpeg" | "png"
* :format `String` "jpeg" ("jpg") | "png" | "webp"
* :quality `Integer` 0-100 works for jpeg only
* :full `Boolean` whether you need full page screenshot or a viewport
* :selector `String` css selector for given element, optional
Expand Down
31 changes: 23 additions & 8 deletions lib/ferrum/page/screenshot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ module Screenshot
FULL_WARNING = "Ignoring :selector or :area in #screenshot since full: true was given at %s"
AREA_WARNING = "Ignoring :area in #screenshot since selector: was given at %s"

DEFAULT_SCREENSHOT_FORMAT = "png"
SUPPORTED_SCREENSHOT_FORMAT = %w[png jpeg jpg webp].freeze

DEFAULT_PDF_OPTIONS = {
landscape: false,
paper_width: 8.5,
Expand Down Expand Up @@ -41,7 +44,7 @@ module Screenshot
# @option opts [:base64, :binary] :encoding
# The encoding the image should be returned in.
#
# @option opts ["jpeg", "png"] :format
# @option opts ["jpeg", "jpg", "png", "webp"] :format
# The format the image should be returned in.
#
# @option opts [Integer] :quality
Expand Down Expand Up @@ -71,8 +74,11 @@ module Screenshot
# @example Save on the disk in JPG:
# page.screenshot(path: "google.jpg") # => 30902
#
# @example Save to Base64 in WebP with reduce quality:
# page.screenshot(format: 'webp', quality: 60) # "iVBORw0KGgoAAAANS...
#
# @example Save to Base64 the whole page not only viewport and reduce quality:
# page.screenshot(full: true, quality: 60) # "iVBORw0KGgoAAAANS...
# page.screenshot(full: true, format: 'jpeg', quality: 60) # "iVBORw0KGgoAAAANS...
#
# @example Save with specific background color:
# page.screenshot(background_color: Ferrum::RGBA.new(0, 0, 0, 0.0))
Expand Down Expand Up @@ -210,14 +216,23 @@ def screenshot_options(path = nil, format: nil, scale: 1.0, **options)
screenshot_options
end

def format_options(format, path, quality)
format ||= path ? File.extname(path).delete(".") : "png"
format = "jpeg" if format == "jpg"
raise "Not supported options `:format` #{format}. jpeg | png" if format !~ /jpeg|png/i
def format_options(screenshot_format, path, quality)
if !screenshot_format && path # try to infer from path
extension = File.extname(path).delete(".")&.downcase
screenshot_format = extension if extension && !extension.empty?
end

screenshot_format ||= DEFAULT_SCREENSHOT_FORMAT
unless SUPPORTED_SCREENSHOT_FORMAT.include?(screenshot_format)
raise "Not supported options `:format` #{screenshot_format}. #{SUPPORTED_SCREENSHOT_FORMAT.join(' | ')}"
end

screenshot_format = "jpeg" if screenshot_format == "jpg"

quality ||= 75 if format == "jpeg"
# Chrome supports screenshot qualities for JPEG and WebP
quality ||= 75 if screenshot_format != "png"

[format, quality]
[screenshot_format, quality]
end

def area_options(full, selector, scale, area = nil)
Expand Down
11 changes: 11 additions & 0 deletions spec/page/screenshot_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,17 @@ def create_screenshot(**options)
FileUtils.rm_f(file)
end

it "supports screenshotting the page to webp file" do
file = "#{PROJECT_ROOT}/spec/tmp/screenshot.webp"
browser.go_to

browser.screenshot(path: file, format: "webp")

expect(File.exist?(file)).to be true
ensure
FileUtils.rm_f(file)
end

it "supports screenshotting the page with different quality settings" do
file2 = "#{PROJECT_ROOT}/spec/tmp/screenshot2.jpeg"
file3 = "#{PROJECT_ROOT}/spec/tmp/screenshot3.jpeg"
Expand Down

0 comments on commit 6410b68

Please sign in to comment.