leifcr-capybara-screenshot 1.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +13 -0
- data/Appraisals +19 -0
- data/CHANGELOG.md +256 -0
- data/Gemfile +9 -0
- data/LICENSE +19 -0
- data/README.md +315 -0
- data/Rakefile +40 -0
- data/capybara-screenshot.gemspec +39 -0
- data/gemfiles/cucumber.1.3.gemfile +11 -0
- data/gemfiles/cucumber.2.4.gemfile +11 -0
- data/gemfiles/latest.gemfile +10 -0
- data/gemfiles/rspec.3.0.gemfile +11 -0
- data/gemfiles/spinach.0.8.gemfile +11 -0
- data/lib/capybara-screenshot/callbacks.rb +44 -0
- data/lib/capybara-screenshot/capybara.rb +26 -0
- data/lib/capybara-screenshot/cucumber.rb +28 -0
- data/lib/capybara-screenshot/helpers.rb +28 -0
- data/lib/capybara-screenshot/minitest.rb +36 -0
- data/lib/capybara-screenshot/pruner.rb +48 -0
- data/lib/capybara-screenshot/rspec/base_reporter.rb +21 -0
- data/lib/capybara-screenshot/rspec/html_embed_reporter.rb +25 -0
- data/lib/capybara-screenshot/rspec/html_link_reporter.rb +37 -0
- data/lib/capybara-screenshot/rspec/json_reporter.rb +19 -0
- data/lib/capybara-screenshot/rspec/text_reporter.rb +39 -0
- data/lib/capybara-screenshot/rspec/textmate_link_reporter.rb +19 -0
- data/lib/capybara-screenshot/rspec.rb +95 -0
- data/lib/capybara-screenshot/s3_saver.rb +64 -0
- data/lib/capybara-screenshot/saver.rb +131 -0
- data/lib/capybara-screenshot/spinach.rb +26 -0
- data/lib/capybara-screenshot/testunit.rb +39 -0
- data/lib/capybara-screenshot/version.rb +5 -0
- data/lib/capybara-screenshot.rb +217 -0
- data/spec/cucumber/cucumber_spec.rb +89 -0
- data/spec/cucumber/step_definitions/step_definitions.rb +18 -0
- data/spec/cucumber/support/env.rb +17 -0
- data/spec/feature/minitest_spec.rb +79 -0
- data/spec/feature/testunit_spec.rb +77 -0
- data/spec/rspec/rspec_spec.rb +158 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/spinach/spinach_spec.rb +60 -0
- data/spec/spinach/support/spinach_failure.rb +41 -0
- data/spec/support/aruba.rb +2 -0
- data/spec/support/common_setup.rb +67 -0
- data/spec/support/html_reporter_context.rb +28 -0
- data/spec/support/test_app.rb +13 -0
- data/spec/unit/base_reporter_spec.rb +25 -0
- data/spec/unit/capybara-screenshot_rspec_spec.rb +48 -0
- data/spec/unit/capybara-screenshot_spec.rb +121 -0
- data/spec/unit/capybara_spec.rb +50 -0
- data/spec/unit/pruner_spec.rb +108 -0
- data/spec/unit/rspec_reporters/html_embed_reporter_spec.rb +18 -0
- data/spec/unit/rspec_reporters/html_link_reporter_spec.rb +27 -0
- data/spec/unit/rspec_reporters/text_reporter_spec.rb +98 -0
- data/spec/unit/rspec_reporters/textmate_link_reporter_spec.rb +39 -0
- data/spec/unit/s3_saver_spec.rb +132 -0
- data/spec/unit/saver_spec.rb +366 -0
- metadata +264 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'capybara-screenshot/rspec/base_reporter'
|
2
|
+
|
3
|
+
module Capybara
|
4
|
+
module Screenshot
|
5
|
+
module RSpec
|
6
|
+
module JsonReporter
|
7
|
+
extend BaseReporter
|
8
|
+
|
9
|
+
enhance_with_screenshot :format_example
|
10
|
+
|
11
|
+
def format_example_with_screenshot(example)
|
12
|
+
format_example_without_screenshot(example).merge({
|
13
|
+
screenshot: example.metadata[:screenshot]
|
14
|
+
})
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'capybara-screenshot/rspec/base_reporter'
|
2
|
+
require 'capybara-screenshot/helpers'
|
3
|
+
|
4
|
+
module Capybara
|
5
|
+
module Screenshot
|
6
|
+
module RSpec
|
7
|
+
module TextReporter
|
8
|
+
extend BaseReporter
|
9
|
+
|
10
|
+
if ::RSpec::Core::Version::STRING.to_i <= 2
|
11
|
+
enhance_with_screenshot :dump_failure_info
|
12
|
+
else
|
13
|
+
enhance_with_screenshot :example_failed
|
14
|
+
end
|
15
|
+
|
16
|
+
def dump_failure_info_with_screenshot(example)
|
17
|
+
dump_failure_info_without_screenshot example
|
18
|
+
output_screenshot_info(example)
|
19
|
+
end
|
20
|
+
|
21
|
+
def example_failed_with_screenshot(notification)
|
22
|
+
example_failed_without_screenshot notification
|
23
|
+
output_screenshot_info(notification.example)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def output_screenshot_info(example)
|
28
|
+
return unless (screenshot = example.metadata[:screenshot])
|
29
|
+
output.puts(long_padding + CapybaraScreenshot::Helpers.yellow("HTML screenshot: file://#{screenshot[:html]}")) if screenshot[:html]
|
30
|
+
output.puts(long_padding + CapybaraScreenshot::Helpers.yellow("Image screenshot: file://#{screenshot[:image]}")) if screenshot[:image]
|
31
|
+
end
|
32
|
+
|
33
|
+
def long_padding
|
34
|
+
" "
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'capybara-screenshot/rspec/base_reporter'
|
2
|
+
require 'capybara-screenshot/rspec/html_link_reporter'
|
3
|
+
require 'shellwords'
|
4
|
+
|
5
|
+
module Capybara
|
6
|
+
module Screenshot
|
7
|
+
module RSpec
|
8
|
+
module TextMateLinkReporter
|
9
|
+
extend BaseReporter
|
10
|
+
include HtmlLinkReporter
|
11
|
+
enhance_with_screenshot :extra_failure_content
|
12
|
+
|
13
|
+
def attributes_for_screenshot_link(url)
|
14
|
+
super.merge("onclick" => "TextMate.system('open #{Shellwords.escape(url)}'); return false;")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require "capybara-screenshot"
|
2
|
+
|
3
|
+
require "capybara-screenshot/rspec/text_reporter"
|
4
|
+
require "capybara-screenshot/rspec/html_link_reporter"
|
5
|
+
require "capybara-screenshot/rspec/html_embed_reporter"
|
6
|
+
require "capybara-screenshot/rspec/json_reporter"
|
7
|
+
require "capybara-screenshot/rspec/textmate_link_reporter"
|
8
|
+
|
9
|
+
module Capybara
|
10
|
+
module Screenshot
|
11
|
+
module RSpec
|
12
|
+
|
13
|
+
# Reporters extend RSpec formatters to display information about screenshots for failed
|
14
|
+
# examples.
|
15
|
+
#
|
16
|
+
# Technically, a reporter is a module that gets injected into a RSpec formatter class.
|
17
|
+
# It uses method aliasing to extend some (usually just one) of the formatter's methods.
|
18
|
+
#
|
19
|
+
# Implementing a custom reporter is as simple as creating a module and setting up the
|
20
|
+
# appropriate aliases. Use `BaseReporter.enhance_with_screenshot` if you don't want
|
21
|
+
# to set up the aliases manually:
|
22
|
+
#
|
23
|
+
# module MyReporter
|
24
|
+
# extend Capybara::Screenshot::RSpec::BaseReporter
|
25
|
+
#
|
26
|
+
# # Will replace the formatter's original `dump_failure_info` method with
|
27
|
+
# # `dump_failure_info_with_screenshot` from this module:
|
28
|
+
# enhance_with_screenshot :dump_failure_info
|
29
|
+
#
|
30
|
+
# def dump_failure_info_with_screenshot(example)
|
31
|
+
# dump_failure_info_without_screenshot(example) # call original implementation
|
32
|
+
# ... # your additions here
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# Finally customize `Capybara::Screenshot::RSpec::FORMATTERS` to make sure your reporter
|
37
|
+
# gets injected into the appropriate formatter.
|
38
|
+
|
39
|
+
REPORTERS = {
|
40
|
+
"RSpec::Core::Formatters::ProgressFormatter" => Capybara::Screenshot::RSpec::TextReporter,
|
41
|
+
"RSpec::Core::Formatters::DocumentationFormatter" => Capybara::Screenshot::RSpec::TextReporter,
|
42
|
+
"RSpec::Core::Formatters::HtmlFormatter" => Capybara::Screenshot::RSpec::HtmlLinkReporter,
|
43
|
+
"RSpec::Core::Formatters::JsonFormatter" => Capybara::Screenshot::RSpec::JsonReporter,
|
44
|
+
"RSpec::Core::Formatters::TextMateFormatter" => Capybara::Screenshot::RSpec::TextMateLinkReporter, # RSpec 2
|
45
|
+
"RSpec::Mate::Formatters::TextMateFormatter" => Capybara::Screenshot::RSpec::TextMateLinkReporter, # RSpec 3
|
46
|
+
"Fuubar" => Capybara::Screenshot::RSpec::TextReporter
|
47
|
+
}
|
48
|
+
|
49
|
+
class << self
|
50
|
+
attr_accessor :add_link_to_screenshot_for_failed_examples
|
51
|
+
|
52
|
+
def after_failed_example(example)
|
53
|
+
if example.example_group.include?(Capybara::DSL) # Capybara DSL method has been included for a feature we can snapshot
|
54
|
+
Capybara.using_session(Capybara::Screenshot.final_session_name) do
|
55
|
+
if Capybara.page.current_url != '' && Capybara::Screenshot.autosave_on_failure && example.exception
|
56
|
+
filename_prefix = Capybara::Screenshot.filename_prefix_for(:rspec, example)
|
57
|
+
|
58
|
+
saver = Capybara::Screenshot.new_saver(Capybara, Capybara.page, true, filename_prefix)
|
59
|
+
saver.save
|
60
|
+
|
61
|
+
example.metadata[:screenshot] = {}
|
62
|
+
example.metadata[:screenshot][:html] = saver.html_path if saver.html_saved?
|
63
|
+
example.metadata[:screenshot][:image] = saver.screenshot_path if saver.screenshot_saved?
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
self.add_link_to_screenshot_for_failed_examples = true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
RSpec.configure do |config|
|
76
|
+
config.before do
|
77
|
+
Capybara::Screenshot.final_session_name = nil
|
78
|
+
end
|
79
|
+
|
80
|
+
config.after do |example_from_block_arg|
|
81
|
+
# RSpec 3 no longer defines `example`, but passes the example as block argument instead
|
82
|
+
example = config.respond_to?(:expose_current_running_example_as) ? example_from_block_arg : self.example
|
83
|
+
|
84
|
+
Capybara::Screenshot::RSpec.after_failed_example(example)
|
85
|
+
end
|
86
|
+
|
87
|
+
config.before(:suite) do
|
88
|
+
if Capybara::Screenshot::RSpec.add_link_to_screenshot_for_failed_examples
|
89
|
+
RSpec.configuration.formatters.each do |formatter|
|
90
|
+
next unless (reporter_module = Capybara::Screenshot::RSpec::REPORTERS[formatter.class.to_s])
|
91
|
+
formatter.singleton_class.send :include, reporter_module
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
|
3
|
+
module Capybara
|
4
|
+
module Screenshot
|
5
|
+
class S3Saver
|
6
|
+
DEFAULT_REGION = 'us-east-1'
|
7
|
+
|
8
|
+
def initialize(saver, s3_client, bucket_name)
|
9
|
+
@saver = saver
|
10
|
+
@s3_client = s3_client
|
11
|
+
@bucket_name = bucket_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.new_with_configuration(saver, configuration)
|
15
|
+
default_s3_client_credentials = {
|
16
|
+
region: DEFAULT_REGION
|
17
|
+
}
|
18
|
+
|
19
|
+
s3_client_credentials = default_s3_client_credentials.merge(
|
20
|
+
configuration.fetch(:s3_client_credentials)
|
21
|
+
)
|
22
|
+
|
23
|
+
s3_client = Aws::S3::Client.new(s3_client_credentials)
|
24
|
+
bucket_name = configuration.fetch(:bucket_name)
|
25
|
+
|
26
|
+
new(saver, s3_client, bucket_name)
|
27
|
+
rescue KeyError
|
28
|
+
raise "Invalid S3 Configuration #{configuration}. Please refer to the documentation for the necessary configurations."
|
29
|
+
end
|
30
|
+
|
31
|
+
def save_and_upload_screenshot
|
32
|
+
save_and do |local_file_path|
|
33
|
+
File.open(local_file_path) do |file|
|
34
|
+
s3_client.put_object(
|
35
|
+
bucket: bucket_name,
|
36
|
+
key: File.basename(local_file_path),
|
37
|
+
body: file
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
alias_method :save, :save_and_upload_screenshot
|
43
|
+
|
44
|
+
def method_missing(method, *args)
|
45
|
+
# Need to use @saver instead of S3Saver#saver attr_reader method because
|
46
|
+
# using the method goes into infinite loop. Maybe attr_reader implements
|
47
|
+
# its methods via method_missing?
|
48
|
+
@saver.send(method, *args)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
attr_reader :saver,
|
53
|
+
:s3_client,
|
54
|
+
:bucket_name
|
55
|
+
|
56
|
+
def save_and
|
57
|
+
saver.save
|
58
|
+
|
59
|
+
yield(saver.html_path) if block_given? && saver.html_saved?
|
60
|
+
yield(saver.screenshot_path) if block_given? && saver.screenshot_saved?
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'capybara-screenshot/helpers'
|
2
|
+
require 'capybara-screenshot/callbacks'
|
3
|
+
|
4
|
+
module Capybara
|
5
|
+
module Screenshot
|
6
|
+
class Saver
|
7
|
+
include Capybara::Screenshot::Callbacks
|
8
|
+
|
9
|
+
define_callback :after_save_html
|
10
|
+
define_callback :after_save_screenshot
|
11
|
+
|
12
|
+
attr_reader :capybara, :page, :file_base_name
|
13
|
+
|
14
|
+
def initialize(capybara, page, html_save=true, filename_prefix='screenshot')
|
15
|
+
@capybara, @page, @html_save = capybara, page, html_save
|
16
|
+
time_now = Time.now
|
17
|
+
timestamp = "#{time_now.strftime('%Y-%m-%d-%H-%M-%S.')}#{'%03d' % (time_now.usec/1000).to_i}"
|
18
|
+
|
19
|
+
filename = [filename_prefix]
|
20
|
+
filename << timestamp if Capybara::Screenshot.append_timestamp
|
21
|
+
filename << SecureRandom.hex if Capybara::Screenshot.append_random
|
22
|
+
|
23
|
+
@file_base_name = filename.join('_')
|
24
|
+
|
25
|
+
Capybara::Screenshot.prune
|
26
|
+
end
|
27
|
+
|
28
|
+
def save
|
29
|
+
# if current_path empty then nothing to screen shot as browser has not loaded any URL
|
30
|
+
return if page.current_path.to_s.empty?
|
31
|
+
|
32
|
+
save_html if @html_save
|
33
|
+
save_screenshot
|
34
|
+
end
|
35
|
+
|
36
|
+
def save_html
|
37
|
+
path = html_path
|
38
|
+
clear_save_path do
|
39
|
+
if Capybara::VERSION.match(/^\d+/)[0] == '1'
|
40
|
+
capybara.save_page(page.body, "#{path}")
|
41
|
+
else
|
42
|
+
capybara.save_page("#{path}")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
@html_saved = true
|
46
|
+
run_callbacks :after_save_html, html_path if html_saved?
|
47
|
+
end
|
48
|
+
|
49
|
+
def save_screenshot
|
50
|
+
path = screenshot_path
|
51
|
+
clear_save_path do
|
52
|
+
result = Capybara::Screenshot.registered_drivers.fetch(capybara.current_driver) { |driver_name|
|
53
|
+
warn "capybara-screenshot could not detect a screenshot driver for '#{capybara.current_driver}'. Saving with default with unknown results."
|
54
|
+
Capybara::Screenshot.registered_drivers[:default]
|
55
|
+
}.call(page.driver, path)
|
56
|
+
@screenshot_saved = result != :not_supported
|
57
|
+
end
|
58
|
+
run_callbacks :after_save_screenshot, screenshot_path if screenshot_saved?
|
59
|
+
end
|
60
|
+
|
61
|
+
def html_path
|
62
|
+
File.join(Capybara::Screenshot.capybara_root, "#{file_base_name}.html")
|
63
|
+
end
|
64
|
+
|
65
|
+
def screenshot_path
|
66
|
+
File.join(Capybara::Screenshot.capybara_root, "#{file_base_name}.png")
|
67
|
+
end
|
68
|
+
|
69
|
+
def html_path_alt_root
|
70
|
+
File.join(Capybara::Screenshot.capybara_alt_root, "#{file_base_name}.html")
|
71
|
+
end
|
72
|
+
|
73
|
+
def screenshot_path_alt_root
|
74
|
+
File.join(Capybara::Screenshot.capybara_alt_root, "#{file_base_name}.png")
|
75
|
+
end
|
76
|
+
|
77
|
+
def html_saved?
|
78
|
+
@html_saved
|
79
|
+
end
|
80
|
+
|
81
|
+
def screenshot_saved?
|
82
|
+
@screenshot_saved
|
83
|
+
end
|
84
|
+
|
85
|
+
# If Capybara::Screenshot.capybara_tmp_path is set then
|
86
|
+
# the html_path or screenshot_path can be appended to this path in
|
87
|
+
# some versions of Capybara instead of using it as an absolute path
|
88
|
+
def clear_save_path
|
89
|
+
old_path = Capybara::Screenshot.capybara_tmp_path
|
90
|
+
Capybara::Screenshot.capybara_tmp_path = nil
|
91
|
+
yield
|
92
|
+
ensure
|
93
|
+
Capybara::Screenshot.capybara_tmp_path = old_path
|
94
|
+
end
|
95
|
+
|
96
|
+
def output_screenshot_path
|
97
|
+
output "HTML screenshot: #{html_path_alt_root}" if html_saved?
|
98
|
+
output "Image screenshot: #{screenshot_path_alt_root}" if screenshot_saved?
|
99
|
+
end
|
100
|
+
|
101
|
+
# Print image to screen, if imgcat is available
|
102
|
+
def display_image
|
103
|
+
system("#{imgcat} #{screenshot_path}") unless imgcat.nil?
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def output(message)
|
109
|
+
puts " #{CapybaraScreenshot::Helpers.yellow(message)}"
|
110
|
+
end
|
111
|
+
|
112
|
+
def imgcat
|
113
|
+
@imgcat ||= which('imgcat')
|
114
|
+
end
|
115
|
+
|
116
|
+
# Cross-platform way of finding an executable in the $PATH.
|
117
|
+
#
|
118
|
+
# which('ruby') #=> /usr/bin/ruby
|
119
|
+
def which(cmd)
|
120
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
121
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
122
|
+
exts.each { |ext|
|
123
|
+
exe = File.join(path, "#{cmd}#{ext}")
|
124
|
+
return exe if File.executable?(exe) && !File.directory?(exe)
|
125
|
+
}
|
126
|
+
end
|
127
|
+
return nil
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "capybara-screenshot"
|
2
|
+
|
3
|
+
Spinach.hooks.before_scenario do |scenario|
|
4
|
+
Capybara::Screenshot.final_session_name = nil
|
5
|
+
end
|
6
|
+
|
7
|
+
module Capybara::Screenshot::Spinach
|
8
|
+
def self.fail_with_screenshot(step_data, exception, location, step_definitions)
|
9
|
+
if Capybara::Screenshot.autosave_on_failure
|
10
|
+
Capybara.using_session(Capybara::Screenshot.final_session_name) do
|
11
|
+
filename_prefix = Capybara::Screenshot.filename_prefix_for(:spinach, step_data)
|
12
|
+
saver = Capybara::Screenshot.new_saver(Capybara, Capybara.page, true, filename_prefix)
|
13
|
+
saver.save
|
14
|
+
saver.output_screenshot_path
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Spinach.hooks.on_failed_step do |*args|
|
21
|
+
Capybara::Screenshot::Spinach.fail_with_screenshot(*args)
|
22
|
+
end
|
23
|
+
|
24
|
+
Spinach.hooks.on_error_step do |*args|
|
25
|
+
Capybara::Screenshot::Spinach.fail_with_screenshot(*args)
|
26
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test/unit/testresult'
|
2
|
+
|
3
|
+
module Capybara::Screenshot
|
4
|
+
class << self
|
5
|
+
attr_accessor :testunit_paths
|
6
|
+
end
|
7
|
+
|
8
|
+
self.testunit_paths = [%r{test/integration}]
|
9
|
+
end
|
10
|
+
|
11
|
+
Test::Unit::TestCase.class_eval do
|
12
|
+
setup do
|
13
|
+
Capybara::Screenshot.final_session_name = nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Test::Unit::TestResult.class_eval do
|
18
|
+
private
|
19
|
+
|
20
|
+
def notify_fault_with_screenshot(fault, *args)
|
21
|
+
notify_fault_without_screenshot fault, *args
|
22
|
+
is_integration_test = fault.location.any? do |location|
|
23
|
+
Capybara::Screenshot.testunit_paths.any? { |path| location.match(path) }
|
24
|
+
end
|
25
|
+
if is_integration_test
|
26
|
+
if Capybara::Screenshot.autosave_on_failure
|
27
|
+
Capybara.using_session(Capybara::Screenshot.final_session_name) do
|
28
|
+
filename_prefix = Capybara::Screenshot.filename_prefix_for(:testunit, fault)
|
29
|
+
|
30
|
+
saver = Capybara::Screenshot.new_saver(Capybara, Capybara.page, true, filename_prefix)
|
31
|
+
saver.save
|
32
|
+
saver.output_screenshot_path
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
alias notify_fault_without_screenshot notify_fault
|
38
|
+
alias notify_fault notify_fault_with_screenshot
|
39
|
+
end
|