-
Notifications
You must be signed in to change notification settings - Fork 169
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds "upload to s3" capabilities if configured
- Introduces an S3Saver that's a transparent facade over a Saver - Refactors all saver instantiation behind saver "factory method" which dynamically chooses whether to give you an S3Saver depending on if you have configured s3 upload - Defaults to 'us-east-1' region if not specified
- Loading branch information
Showing
11 changed files
with
268 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
require 'aws-sdk' | ||
|
||
module Capybara | ||
module Screenshot | ||
class S3Saver | ||
DEFAULT_REGION = 'us-east-1' | ||
|
||
def initialize(saver, s3_client, bucket_name) | ||
@saver = saver | ||
@s3_client = s3_client | ||
@bucket_name = bucket_name | ||
end | ||
|
||
def self.new_with_configuration(saver, configuration) | ||
default_s3_client_credentials = { | ||
region: DEFAULT_REGION | ||
} | ||
|
||
s3_client_credentials = default_s3_client_credentials.merge( | ||
configuration.fetch(:s3_client_credentials) | ||
) | ||
|
||
s3_client = Aws::S3::Client.new(s3_client_credentials) | ||
bucket_name = configuration.fetch(:bucket_name) | ||
|
||
new(saver, s3_client, bucket_name) | ||
rescue KeyError | ||
raise "Invalid S3 Configuration #{configuration}. Please refer to the documentation for the necessary configurations." | ||
end | ||
|
||
def save_and_upload_screenshot | ||
save_and do |local_file_path| | ||
File.open(local_file_path) do |file| | ||
s3_client.put_object( | ||
bucket: bucket_name, | ||
key: File.basename(local_file_path), | ||
body: file | ||
) | ||
end | ||
end | ||
end | ||
alias_method :save, :save_and_upload_screenshot | ||
|
||
def method_missing(method, *args) | ||
# Need to use @saver instead of S3Saver#saver attr_reader method because | ||
# using the method goes into infinite loop. Maybe attr_reader implements | ||
# its methods via method_missing? | ||
@saver.send(method, *args) | ||
end | ||
|
||
private | ||
attr_reader :saver, | ||
:s3_client, | ||
:bucket_name | ||
|
||
def save_and | ||
saver.save | ||
|
||
yield(saver.html_path) if block_given? && saver.html_saved? | ||
yield(saver.screenshot_path) if block_given? && saver.screenshot_saved? | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
require 'spec_helper' | ||
require 'capybara-screenshot/s3_saver' | ||
|
||
describe Capybara::Screenshot::S3Saver do | ||
let(:saver) { double('saver') } | ||
let(:bucket_name) { double('bucket_name') } | ||
let(:s3_client) { double('s3_client') } | ||
|
||
let(:s3_saver) { Capybara::Screenshot::S3Saver.new(saver, s3_client, bucket_name) } | ||
|
||
describe '.new_with_configuration' do | ||
let(:access_key_id) { double('access_key_id') } | ||
let(:secret_access_key) { double('secret_access_key') } | ||
let(:s3_client_credentials_using_defaults) { | ||
{ | ||
access_key_id: access_key_id, | ||
secret_access_key: secret_access_key | ||
} | ||
} | ||
|
||
let(:region) { double('region') } | ||
let(:s3_client_credentials) { | ||
s3_client_credentials_using_defaults.merge(region: region) | ||
} | ||
|
||
it 'destructures the configuration into its components' do | ||
allow(Aws::S3::Client).to receive(:new).and_return(s3_client) | ||
allow(Capybara::Screenshot::S3Saver).to receive(:new) | ||
|
||
Capybara::Screenshot::S3Saver.new_with_configuration(saver, { | ||
s3_client_credentials: s3_client_credentials, | ||
bucket_name: bucket_name | ||
}) | ||
|
||
expect(Aws::S3::Client).to have_received(:new).with(s3_client_credentials) | ||
expect(Capybara::Screenshot::S3Saver).to have_received(:new).with(saver, s3_client, bucket_name) | ||
end | ||
|
||
it 'defaults the region to us-east-1' do | ||
default_region = 'us-east-1' | ||
|
||
allow(Aws::S3::Client).to receive(:new).and_return(s3_client) | ||
allow(Capybara::Screenshot::S3Saver).to receive(:new) | ||
|
||
Capybara::Screenshot::S3Saver.new_with_configuration(saver, { | ||
s3_client_credentials: s3_client_credentials_using_defaults, | ||
bucket_name: bucket_name | ||
}) | ||
|
||
expect(Aws::S3::Client).to have_received(:new).with( | ||
s3_client_credentials.merge(region: default_region) | ||
) | ||
|
||
expect(Capybara::Screenshot::S3Saver).to have_received(:new).with(saver, s3_client, bucket_name) | ||
end | ||
end | ||
|
||
describe '#save' do | ||
before do | ||
allow(saver).to receive(:html_saved?).and_return(false) | ||
allow(saver).to receive(:screenshot_saved?).and_return(false) | ||
allow(saver).to receive(:save) | ||
end | ||
|
||
it 'calls save on the underlying saver' do | ||
expect(saver).to receive(:save) | ||
|
||
s3_saver.save | ||
end | ||
|
||
it 'uploads the html' do | ||
html_path = '/foo/bar.html' | ||
expect(saver).to receive(:html_path).and_return(html_path) | ||
expect(saver).to receive(:html_saved?).and_return(true) | ||
|
||
html_file = double('html_file') | ||
|
||
expect(File).to receive(:open).with(html_path).and_yield(html_file) | ||
|
||
expect(s3_client).to receive(:put_object).with( | ||
bucket: bucket_name, | ||
key: 'bar.html', | ||
body: html_file | ||
) | ||
|
||
s3_saver.save | ||
end | ||
|
||
it 'uploads the screenshot' do | ||
screenshot_path = '/baz/bim.jpg' | ||
expect(saver).to receive(:screenshot_path).and_return(screenshot_path) | ||
expect(saver).to receive(:screenshot_saved?).and_return(true) | ||
|
||
screenshot_file = double('screenshot_file') | ||
|
||
expect(File).to receive(:open).with(screenshot_path).and_yield(screenshot_file) | ||
|
||
expect(s3_client).to receive(:put_object).with( | ||
bucket: bucket_name, | ||
key: 'bim.jpg', | ||
body: screenshot_file | ||
) | ||
|
||
s3_saver.save | ||
end | ||
end | ||
|
||
# Needed because we cannot depend on Verifying Doubles | ||
# in older RSpec versions | ||
describe 'an actual saver' do | ||
it 'implements the methods needed by the s3 saver' do | ||
instance_methods = Capybara::Screenshot::Saver.instance_methods | ||
|
||
expect(instance_methods).to include(:save) | ||
expect(instance_methods).to include(:html_saved?) | ||
expect(instance_methods).to include(:html_path) | ||
expect(instance_methods).to include(:screenshot_saved?) | ||
expect(instance_methods).to include(:screenshot_path) | ||
end | ||
end | ||
|
||
describe 'any other method' do | ||
it 'transparently passes through to the saver' do | ||
allow(saver).to receive(:foo_bar) | ||
|
||
args = double('args') | ||
s3_saver.foo_bar(*args) | ||
|
||
expect(saver).to have_received(:foo_bar).with(*args) | ||
end | ||
end | ||
end |