diff --git a/gauge-proto b/gauge-proto index d1db453..cb92d9c 160000 --- a/gauge-proto +++ b/gauge-proto @@ -1 +1 @@ -Subproject commit d1db4535255eb47f1b77e4a022e854c5f1b7ee0d +Subproject commit cb92d9cb8bdcae8a426f747d06d005648531dc97 diff --git a/lib/gauge_screenshot.rb b/lib/gauge_screenshot.rb new file mode 100644 index 0000000..5634ddc --- /dev/null +++ b/lib/gauge_screenshot.rb @@ -0,0 +1,53 @@ +# Copyright 2018 ThoughtWorks, Inc. + +# This file is part of Gauge-Ruby. + +# Gauge-Ruby is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# Gauge-Ruby is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with Gauge-Ruby. If not, see . + +module Gauge + class << self + def capture + GaugeScreenshot.instance.capture + end + end + + class GaugeScreenshot + def initialize + @screenshots = [] + end + + def self.instance + @gauge_screenshots ||= GaugeScreenshot.new + end + + def capture + @screenshots.push(Configuration.instance.screengrabber.call) + end + + def pending_screenshot + pending_screenshot = @screenshots + clear + pending_screenshot + end + + def get + @screenshots + end + + def clear + @screenshots = [] + end + + end +end \ No newline at end of file diff --git a/lib/processors/execution_handler.rb b/lib/processors/execution_handler.rb index 75c6f68..dd4fa21 100644 --- a/lib/processors/execution_handler.rb +++ b/lib/processors/execution_handler.rb @@ -55,7 +55,7 @@ def handle_failure(message, exception, execution_time, recoverable) :stackTrace => code_snippet + stacktrace, :executionTime => execution_time)) screenshot = screenshot_bytes - execution_status_response.executionResult.screenShot = screenshot if !screenshot.nil? + execution_status_response.executionResult.screenShot.push(screenshot) if !screenshot.nil? Messages::Message.new(:messageType => :ExecutionStatusResponse, :messageId => message.messageId, :executionStatusResponse => execution_status_response) end diff --git a/lib/processors/execution_hook_processors.rb b/lib/processors/execution_hook_processors.rb index c9ab6d2..a14815e 100644 --- a/lib/processors/execution_hook_processors.rb +++ b/lib/processors/execution_hook_processors.rb @@ -17,6 +17,7 @@ require_relative "execution_handler" require_relative "../gauge_messages" +require_relative "../gauge_screenshot" require_relative "../executor" require_relative "../method_cache" require_relative "../util" @@ -28,30 +29,35 @@ def process_execution_start_request(message) Gauge::MethodCache.clear Executor.load_steps(Util.get_step_implementation_dir) response = handle_hooks_execution(MethodCache.get_before_suite_hooks, message,message.executionStartingRequest.currentExecutionInfo,false) + response.executionStatusResponse.executionResult.screenShot += Gauge::GaugeScreenshot.instance.pending_screenshot response.executionStatusResponse.executionResult.message += Gauge::GaugeMessages.instance.pending_messages return response end def process_execution_end_request(message) response = handle_hooks_execution(MethodCache.get_after_suite_hooks, message,message.executionEndingRequest.currentExecutionInfo, false) + response.executionStatusResponse.executionResult.screenShot += Gauge::GaugeScreenshot.instance.pending_screenshot response.executionStatusResponse.executionResult.message += Gauge::GaugeMessages.instance.pending_messages return response end def process_spec_execution_start_request(message) response = handle_hooks_execution(MethodCache.get_before_spec_hooks, message,message.specExecutionStartingRequest.currentExecutionInfo) + response.executionStatusResponse.executionResult.screenShot += Gauge::GaugeScreenshot.instance.pending_screenshot response.executionStatusResponse.executionResult.message += Gauge::GaugeMessages.instance.pending_messages return response end def process_spec_execution_end_request(message) response = handle_hooks_execution(MethodCache.get_after_spec_hooks, message,message.specExecutionEndingRequest.currentExecutionInfo) + response.executionStatusResponse.executionResult.screenShot += Gauge::GaugeScreenshot.instance.pending_screenshot response.executionStatusResponse.executionResult.message += Gauge::GaugeMessages.instance.pending_messages return response end def process_scenario_execution_start_request(message) response = handle_hooks_execution(MethodCache.get_before_scenario_hooks, message,message.scenarioExecutionStartingRequest.currentExecutionInfo) + response.executionStatusResponse.executionResult.screenShot += Gauge::GaugeScreenshot.instance.pending_screenshot response.executionStatusResponse.executionResult.message += Gauge::GaugeMessages.instance.pending_messages return response end @@ -59,18 +65,21 @@ def process_scenario_execution_start_request(message) def process_scenario_execution_end_request(message) response = handle_hooks_execution(MethodCache.get_after_scenario_hooks, message,message.scenarioExecutionEndingRequest.currentExecutionInfo) + response.executionStatusResponse.executionResult.screenShot += Gauge::GaugeScreenshot.instance.pending_screenshot response.executionStatusResponse.executionResult.message += Gauge::GaugeMessages.instance.pending_messages return response end def process_step_execution_start_request(message) response = handle_hooks_execution(MethodCache.get_before_step_hooks, message,message.stepExecutionStartingRequest.currentExecutionInfo) + response.executionStatusResponse.executionResult.screenShot += Gauge::GaugeScreenshot.instance.pending_screenshot response.executionStatusResponse.executionResult.message += Gauge::GaugeMessages.instance.pending_messages return response end def process_step_execution_end_request(message) response = handle_hooks_execution(MethodCache.get_after_step_hooks, message,message.stepExecutionEndingRequest.currentExecutionInfo) + response.executionStatusResponse.executionResult.screenShot += Gauge::GaugeScreenshot.instance.pending_screenshot response.executionStatusResponse.executionResult.message += Gauge::GaugeMessages.instance.pending_messages return response end diff --git a/lib/spec_pb.rb b/lib/spec_pb.rb index db5cdda..3ea3637 100644 --- a/lib/spec_pb.rb +++ b/lib/spec_pb.rb @@ -126,7 +126,7 @@ optional :recoverableError, :bool, 2 optional :errorMessage, :string, 3 optional :stackTrace, :string, 4 - optional :screenShot, :bytes, 5 + repeated :screenShot, :bytes, 5 optional :executionTime, :int64, 6 repeated :message, :string, 7 optional :errorType, :enum, 8, "gauge.messages.ProtoExecutionResult.ErrorType" diff --git a/spec/capture_screenshot_spec.rb b/spec/capture_screenshot_spec.rb new file mode 100644 index 0000000..94ccc93 --- /dev/null +++ b/spec/capture_screenshot_spec.rb @@ -0,0 +1,36 @@ +# Copyright 2015 ThoughtWorks, Inc. + +# This file is part of Gauge-Ruby. + +# Gauge-Ruby is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# Gauge-Ruby is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with Gauge-Ruby. If not, see . + +describe Gauge do + before(:each) { + Gauge.configure { |c| c.screengrabber = -> { return "foo" }} + } + context 'capture screenshot' do + it "should have a screenshot" do + Gauge.capture + expect(Gauge::GaugeScreenshot.instance.pending_screenshot).to match_array ["foo"] + end + end + context 'clear screenshot' do + it "should clear screenshot after collecting them" do + Gauge.capture + expect(Gauge::GaugeScreenshot.instance.pending_screenshot).to match_array ["foo"] + expect(Gauge::GaugeScreenshot.instance.pending_screenshot).to match_array [] + end + end +end + \ No newline at end of file diff --git a/spec/execution_hook_processors_spec.rb b/spec/execution_hook_processors_spec.rb index 4b2435e..d2e53a9 100644 --- a/spec/execution_hook_processors_spec.rb +++ b/spec/execution_hook_processors_spec.rb @@ -12,8 +12,11 @@ it 'should add custom message from before suite' do input = Gauge::Messages::Message.new(:executionStartingRequest => Gauge::Messages::ExecutionStartingRequest.new(:currentExecutionInfo => nil)) Gauge::GaugeMessages.instance.write('before suite') + Gauge.configure { |c| c.screengrabber = -> { return "before_suite" }} + Gauge::GaugeScreenshot.instance.capture() response = Gauge::Processors.process_execution_start_request(input) expect(response.executionStatusResponse.executionResult.message).to include 'before suite' + expect(response.executionStatusResponse.executionResult.screenShot).to match_array ["before_suite"] end end @@ -21,8 +24,11 @@ it 'should add custom message from after suite' do input = Gauge::Messages::Message.new(:executionEndingRequest => Gauge::Messages::ExecutionEndingRequest.new(:currentExecutionInfo => nil)) Gauge::GaugeMessages.instance.write('after suite') + Gauge.configure { |c| c.screengrabber = -> { return "after_suite" }} + Gauge::GaugeScreenshot.instance.capture() response = Gauge::Processors.process_execution_end_request(input) expect(response.executionStatusResponse.executionResult.message).to include 'after suite' + expect(response.executionStatusResponse.executionResult.screenShot).to match_array ["after_suite"] end end @@ -30,8 +36,11 @@ it 'should add custom message from before spec' do input = Gauge::Messages::Message.new(:specExecutionStartingRequest => Gauge::Messages::SpecExecutionStartingRequest.new(:currentExecutionInfo => nil)) Gauge::GaugeMessages.instance.write('before spec') + Gauge.configure { |c| c.screengrabber = -> { return "before_spec" }} + Gauge::GaugeScreenshot.instance.capture() response = Gauge::Processors.process_spec_execution_start_request(input) expect(response.executionStatusResponse.executionResult.message).to include 'before spec' + expect(response.executionStatusResponse.executionResult.screenShot).to match_array ["before_spec"] end end @@ -39,8 +48,11 @@ it 'should add custom message from after spec' do input = Gauge::Messages::Message.new(:specExecutionEndingRequest => Gauge::Messages::SpecExecutionEndingRequest.new(:currentExecutionInfo => nil)) Gauge::GaugeMessages.instance.write('after spec') + Gauge.configure { |c| c.screengrabber = -> { return "after_spec" }} + Gauge::GaugeScreenshot.instance.capture() response = Gauge::Processors.process_spec_execution_end_request(input) expect(response.executionStatusResponse.executionResult.message).to include 'after spec' + expect(response.executionStatusResponse.executionResult.screenShot).to match_array ["after_spec"] end end @@ -48,8 +60,11 @@ it 'should add custom message from before scenario' do input = Gauge::Messages::Message.new(:scenarioExecutionStartingRequest => Gauge::Messages::ScenarioExecutionStartingRequest.new(:currentExecutionInfo => nil)) Gauge::GaugeMessages.instance.write('before scenario') + Gauge.configure { |c| c.screengrabber = -> { return "before_scenario" }} + Gauge::GaugeScreenshot.instance.capture() response = Gauge::Processors.process_scenario_execution_start_request(input) expect(response.executionStatusResponse.executionResult.message).to include 'before scenario' + expect(response.executionStatusResponse.executionResult.screenShot).to match_array ["before_scenario"] end end @@ -57,8 +72,11 @@ it 'should add custom message from after scenario' do input = Gauge::Messages::Message.new(:scenarioExecutionEndingRequest => Gauge::Messages::ScenarioExecutionEndingRequest.new(:currentExecutionInfo => nil)) Gauge::GaugeMessages.instance.write('after scenario') + Gauge.configure { |c| c.screengrabber = -> { return "after_scenario" }} + Gauge::GaugeScreenshot.instance.capture() response = Gauge::Processors.process_scenario_execution_end_request(input) expect(response.executionStatusResponse.executionResult.message).to include 'after scenario' + expect(response.executionStatusResponse.executionResult.screenShot).to match_array ["after_scenario"] end end @@ -66,8 +84,11 @@ it 'should add custom message from before step' do input = Gauge::Messages::Message.new(:stepExecutionStartingRequest => Gauge::Messages::StepExecutionStartingRequest.new(:currentExecutionInfo => nil)) Gauge::GaugeMessages.instance.write('before step') + Gauge.configure { |c| c.screengrabber = -> { return "before_step" }} + Gauge::GaugeScreenshot.instance.capture() response = Gauge::Processors.process_step_execution_start_request(input) expect(response.executionStatusResponse.executionResult.message).to include 'before step' + expect(response.executionStatusResponse.executionResult.screenShot).to match_array ["before_step"] end end @@ -75,8 +96,11 @@ it 'should add custom message from after step' do input = Gauge::Messages::Message.new(:stepExecutionEndingRequest => Gauge::Messages::StepExecutionEndingRequest.new(:currentExecutionInfo => nil)) Gauge::GaugeMessages.instance.write('after step') + Gauge.configure { |c| c.screengrabber = -> { return "after_step" }} + Gauge::GaugeScreenshot.instance.capture() response = Gauge::Processors.process_step_execution_end_request(input) expect(response.executionStatusResponse.executionResult.message).to include 'after step' + expect(response.executionStatusResponse.executionResult.screenShot).to match_array ["after_step"] end end