Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webp screenshot support #473

Merged
merged 1 commit into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
32 changes: 24 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,24 @@ 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
screenshot_format = screenshot_format.to_s
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