diff --git a/README.md b/README.md index ee8bfb6..a86c287 100644 --- a/README.md +++ b/README.md @@ -211,6 +211,30 @@ Capybara::Screenshot.prune_strategy = :keep_last_run Capybara::Screenshot.prune_strategy = { keep: 20 } ``` +Callbacks +--------- + +You can hook your own logic into callbacks after the html/screenshot has been saved. + +```ruby +# after Saver#save_html +Capybara::Screenshot.after_save_html do |path| + mail = Mail.new do + delivery_method :sendmail + from 'capybara-screenshot@example.com' + to 'dev@example.com' + subject 'Capybara Screenshot' + add_file File.read path + end + mail.delivery_method :sendmail + mail.deliver +end + +# after Saver#save_screenshot +Capybara::Screenhot.after_save_screenshot do |path| + # ... +end +``` Information about screenshots in RSpec output --------------------------------------------- diff --git a/lib/capybara-screenshot.rb b/lib/capybara-screenshot.rb index 6b84ca2..cad3e98 100644 --- a/lib/capybara-screenshot.rb +++ b/lib/capybara-screenshot.rb @@ -103,6 +103,14 @@ def self.new_saver(*args) return saver end + def self.after_save_html &block + Saver.after_save_html &block + end + + def self.after_save_screenshot &block + Saver.after_save_screenshot &block + end + private # If the path isn't set, default to the current directory @@ -171,5 +179,6 @@ def self.capybara_tmp_path require 'capybara/util/save_and_open_page' if Capybara::VERSION.match(/^\d+/)[0] == '1' # no longer needed in Capybara version 2 require 'capybara-screenshot/saver' +require 'capybara-screenshot/callbacks/integrations' require 'capybara-screenshot/capybara' require 'capybara-screenshot/pruner' diff --git a/lib/capybara-screenshot/callbacks.rb b/lib/capybara-screenshot/callbacks.rb new file mode 100644 index 0000000..76a8314 --- /dev/null +++ b/lib/capybara-screenshot/callbacks.rb @@ -0,0 +1,44 @@ +module Capybara + module Screenshot + module Callbacks + class CallbackSet < Array + def call *args + each do |callback| + callback.call *args + end + end + end + + module ClassMethods + def callbacks + @callbacks ||= {} + end + + def define_callback name + callbacks[name] ||= CallbackSet.new + + define_singleton_method name do |&block| + callbacks[name] << block + end + end + + def run_callbacks name, *args + if cb_set = callbacks[name] + cb_set.call *args + end + end + end + + module InstanceMethods + def run_callbacks name, *args + self.class.run_callbacks name, *args + end + end + + def self.included receiver + receiver.extend ClassMethods + receiver.send :include, InstanceMethods + end + end + end +end diff --git a/lib/capybara-screenshot/callbacks/integrations.rb b/lib/capybara-screenshot/callbacks/integrations.rb new file mode 100644 index 0000000..8032c25 --- /dev/null +++ b/lib/capybara-screenshot/callbacks/integrations.rb @@ -0,0 +1 @@ +require 'capybara-screenshot/callbacks/integrations/saver' diff --git a/lib/capybara-screenshot/callbacks/integrations/saver.rb b/lib/capybara-screenshot/callbacks/integrations/saver.rb new file mode 100644 index 0000000..961eee5 --- /dev/null +++ b/lib/capybara-screenshot/callbacks/integrations/saver.rb @@ -0,0 +1,23 @@ +require 'capybara-screenshot/saver' +require 'capybara-screenshot/callbacks' + +Capybara::Screenshot::Saver.class_eval do + include Capybara::Screenshot::Callbacks + + define_callback :after_save_html + define_callback :after_save_screenshot + + def save_html_with_after_callback + save_html_without_after_callback + run_callbacks :after_save_html, html_path if html_saved? + end + alias_method :save_html_without_after_callback, :save_html + alias_method :save_html, :save_html_with_after_callback + + def save_screenshot_with_after_callback + save_screenshot_without_after_callback + run_callbacks :after_save_screenshot, screenshot_path if screenshot_saved? + end + alias_method :save_screenshot_without_after_callback, :save_screenshot + alias_method :save_screenshot, :save_screenshot_with_after_callback +end diff --git a/spec/unit/saver_spec.rb b/spec/unit/saver_spec.rb index 8f97c41..f2057e6 100644 --- a/spec/unit/saver_spec.rb +++ b/spec/unit/saver_spec.rb @@ -154,6 +154,40 @@ end end + describe 'callbacks' do + let(:saver) { Capybara::Screenshot::Saver.new(capybara_mock, page_mock) } + + before do + allow(saver).to receive(:html_path) { 'page.html' } + allow(saver).to receive(:screenshot_path) { 'screenshot.png' } + end + + before :all do + Capybara::Screenshot.after_save_html do |path| + puts "after_save_html ran with #{path}" + end + Capybara::Screenshot.after_save_screenshot do |path| + puts "after_save_screenshot ran with #{path}" + end + end + + after :all do + Capybara::Screenshot::Saver.instance_eval { @callbacks = nil } + end + + it 'runs after_save_html callbacks' do + expect do + saver.save + end.to output(/after_save_html ran with page\.html/).to_stdout + end + + it 'runs after_save_screenshot callbacks' do + expect do + saver.save + end.to output(/after_save_screenshot ran with screenshot\.png/).to_stdout + end + end + describe "with selenium driver" do before do allow(capybara_mock).to receive(:current_driver).and_return(:selenium)