Skip to content

Commit

Permalink
Implement screenshots #11
Browse files Browse the repository at this point in the history
  • Loading branch information
route committed Jan 29, 2019
1 parent 55296fc commit d401cf5
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 27 deletions.
1 change: 1 addition & 0 deletions cuprite.gemspec
Expand Up @@ -31,4 +31,5 @@ Gem::Specification.new do |s|
s.add_development_dependency "launchy", "~> 2.4"
s.add_development_dependency "byebug", "~> 10.0"
s.add_development_dependency "puma", "~> 3.0"
s.add_development_dependency "chunky_png", "~> 1.3"
end
54 changes: 40 additions & 14 deletions lib/capybara/cuprite/browser.rb
Expand Up @@ -90,21 +90,20 @@ def select_file(node, value)
raise NotImplementedError
end

def render(path, _options = {})
# check_render_options!(options)
# options[:full] = !!options[:full]
data = Base64.decode64(render_base64)
File.open(path.to_s, "wb") { |f| f.write(data) }
def render(path, options = {})
format = options.delete(:format)
options = options.merge(path: path)
bin = Base64.decode64(render_base64(format, options))
File.open(path.to_s, "wb") { |f| f.write(bin) }
end

def render_base64(format = "png", _options = {})
# check_render_options!(options)
# options[:full] = !!options[:full]
page.command("Page.captureScreenshot", format: format)["data"]
def render_base64(format, options = {})
options = render_options(format, options)
page.command("Page.captureScreenshot", **options)["data"]
end

def set_zoom_factor(zoom_factor)
raise NotImplementedError
@zoom_factor = zoom_factor.to_f
end

def set_paper_size(size)
Expand Down Expand Up @@ -185,6 +184,7 @@ def clear_memory_cache

def reset
@headers = {}
@zoom_factor = nil
targets.reset
end

Expand Down Expand Up @@ -223,10 +223,36 @@ def start
@client = Client.new(self, @process.ws_url)
end

def check_render_options!(options)
return if !options[:full] || !options.key?(:selector)
warn "Ignoring :selector in #render since :full => true was given at #{caller(1..1).first}"
options.delete(:selector)
def render_options(format, opts)
options = {}

format ||= File.extname(opts[:path]).delete(".") || "png"
format = "jpeg" if format == "jpg"
raise "Not supported format: #{format}. jpeg | png" if format !~ /jpeg|png/i
options.merge!(format: format)

options.merge!(quality: opts[:quality] ? opts[:quality] : 75) if format == "jpeg"

warn "Ignoring :selector in #render since full: true was given at #{caller(1..1).first}" if !!opts[:full] && opts[:selector]

if !!opts[:full]
width, height = page.evaluate("[document.documentElement.offsetWidth, document.documentElement.offsetHeight]")
options.merge!(clip: { x: 0, y: 0, width: width, height: height, scale: @zoom_factor || 1.0 }) if width > 0 && height > 0
elsif opts[:selector]
rect = page.evaluate("document.querySelector('#{opts[:selector]}').getBoundingClientRect()")
options.merge!(clip: { x: rect["x"], y: rect["y"], width: rect["width"], height: rect["height"], scale: @zoom_factor || 1.0 })
end

if @zoom_factor
if !options[:clip]
width, height = page.evaluate("[document.documentElement.clientWidth, document.documentElement.clientHeight]")
options[:clip] = { x: 0, y: 0, width: width, height: height }
end

options[:clip].merge!(scale: @zoom_factor)
end

options
end

def find_all(method, selector, within = nil)
Expand Down
24 changes: 12 additions & 12 deletions spec/integration/driver_spec.rb
Expand Up @@ -3,6 +3,7 @@
require "spec_helper"
require "image_size"
require "pdf/reader"
require "chunky_png"

module Capybara::Cuprite
describe Driver do
Expand Down Expand Up @@ -100,7 +101,7 @@ def session_url(path)
expect(@session.current_window.size).to eq([1366, 768])
end

it "allows custom maximization size", skip: true do
it "allows custom maximization size" do
begin
@driver.options[:screen_size] = [1600, 1200]
@session.visit("/")
Expand Down Expand Up @@ -200,14 +201,14 @@ def session_url(path)
el = @session.find(:css, "#middleish")
# make the page scroll an element into view
el.click
position_script = "document.querySelector("#middleish").getBoundingClientRect()"
position_script = "document.querySelector('#middleish').getBoundingClientRect()"
offset = @session.evaluate_script(position_script)
create_screenshot file
expect(@session.evaluate_script(position_script)).to eq offset
end
end

describe "#save_screenshot", skip: true do
describe "#save_screenshot" do
let(:format) { :png }
let(:file) { CUPRITE_ROOT + "/spec/tmp/screenshot.#{format}" }

Expand Down Expand Up @@ -248,30 +249,29 @@ def create_screenshot(file, *args)
end

it "supports rendering the page with different quality settings" do
file2 = CUPRITE_ROOT + "/spec/tmp/screenshot2.#{format}"
file3 = CUPRITE_ROOT + "/spec/tmp/screenshot3.#{format}"
file2 = CUPRITE_ROOT + "/spec/tmp/screenshot2.jpeg"
file3 = CUPRITE_ROOT + "/spec/tmp/screenshot3.jpeg"
FileUtils.rm_f [file2, file3]

begin
@session.visit("/")
@driver.save_screenshot(file, quality: 0)
@driver.save_screenshot(file, quality: 0) # ignored for png
@driver.save_screenshot(file2) # defaults to a quality of 75
@driver.save_screenshot(file3, quality: 100)
expect(File.size(file)).to be < File.size(file2)
expect(File.size(file)).to be > File.size(file2) # png by defult is bigger
expect(File.size(file2)).to be < File.size(file3)
ensure
FileUtils.rm_f [file2, file3]
end
end

shared_examples "when #zoom_factor= is set" do
let(:format) { :xbm }

it "changes image dimensions" do
@session.visit("/cuprite/zoom_test")

black_pixels_count = lambda { |file|
File.read(file).to_s[/{.*}/m][1...-1].split(/\W/).map { |n| n.hex.to_s(2).count("1") }.reduce(:+)
img = ChunkyPNG::Image.from_file(file)
img.pixels.inject(0) { |i, p| p > 255 ? i + 1 : i }
}
@driver.save_screenshot(file)
before = black_pixels_count[file]
Expand All @@ -294,7 +294,7 @@ def create_screenshot(file, *args)
include_examples "when #zoom_factor= is set"
end

context "when #paper_size= is set" do
context "when #paper_size= is set", skip: true do
let(:format) { :pdf }

it "changes pdf size" do
Expand All @@ -315,7 +315,7 @@ def create_screenshot(file, *args)
include_examples "render screen"
end

describe "#render_base64", skip: true do
describe "#render_base64" do
let(:file) { CUPRITE_ROOT + "/spec/tmp/screenshot.#{format}" }

def create_screenshot(file, *args)
Expand Down
1 change: 0 additions & 1 deletion spec/tmp/a_test_pathname

This file was deleted.

Binary file removed spec/tmp/screenshot.jpeg
Binary file not shown.

0 comments on commit d401cf5

Please sign in to comment.