lib/snapshot/runner.rb in snapshot-1.6.0 vs lib/snapshot/runner.rb in snapshot-1.7.0
- old
+ new
@@ -1,62 +1,76 @@
require 'shellwords'
require 'plist'
module Snapshot
class Runner
- attr_accessor :number_of_retries
+ # The number of times we failed on launching the simulator... sigh
+ attr_accessor :number_of_retries_due_to_failing_simulator
+ # All the errors we experience while running snapshot
+ attr_accessor :collected_errors
+
def work
if File.exist?("./fastlane/snapshot.js") or File.exist?("./snapshot.js")
- Helper.log.warn "Found old snapshot configuration file 'snapshot.js'".red
- Helper.log.warn "You updated to snapshot 1.0 which now uses UI Automation".red
- Helper.log.warn "Please follow the migration guide: https://github.com/fastlane/snapshot/blob/master/MigrationGuide.md".red
- Helper.log.warn "And read the updated documentation: https://github.com/fastlane/snapshot".red
+ UI.error "Found old snapshot configuration file 'snapshot.js'"
+ UI.error "You updated to snapshot 1.0 which now uses UI Automation"
+ UI.error "Please follow the migration guide: https://github.com/fastlane/snapshot/blob/master/MigrationGuide.md"
+ UI.error "And read the updated documentation: https://github.com/fastlane/snapshot"
sleep 3 # to be sure the user sees this, as compiling clears the screen
end
verify_helper_is_current
FastlaneCore::PrintTable.print_values(config: Snapshot.config, hide_keys: [], title: "Summary for snapshot #{Snapshot::VERSION}")
clear_previous_screenshots if Snapshot.config[:clear_previous_screenshots]
- Helper.log.info "Building and running project - this might take some time...".green
+ UI.success "Building and running project - this might take some time..."
- self.number_of_retries = 0
- errors = []
+ self.number_of_retries_due_to_failing_simulator = 0
+ self.collected_errors = []
results = {} # collect all the results for a nice table
launch_arguments_set = config_launch_arguments
Snapshot.config[:devices].each do |device|
launch_arguments_set.each do |launch_arguments|
Snapshot.config[:languages].each do |language|
results[device] ||= {}
- begin
- results[device][language] = launch(language, device, launch_arguments)
- rescue => ex
- Helper.log.error ex # we should to show right here as well
- Helper.log.error "Backtrace:\n\t#{ex.backtrace.join("\n\t")}"
- errors << ex
- results[device][language] = false
- raise ex if Snapshot.config[:stop_after_first_error]
- end
+ results[device][language] = run_for_device_and_language(language, device, launch_arguments)
end
end
end
print_results(results)
- raise errors.join('; ') if errors.count > 0
+ raise self.collected_errors.join('; ') if self.collected_errors.count > 0
# Generate HTML report
ReportsGenerator.new.generate
# Clear the Derived Data
FileUtils.rm_rf(TestCommandGenerator.derived_data_path)
end
+ # This is its own method so that it can re-try if the tests fail randomly
+ # @return true/false depending on if the tests succeded
+ def run_for_device_and_language(language, device, launch_arguments, retries = 0)
+ return launch(language, device, launch_arguments)
+ rescue => ex
+ UI.error ex.to_s # show the reason for failure to the user, but still maybe retry
+
+ if retries < Snapshot.config[:number_of_retries]
+ UI.important "Tests failed, re-trying #{retries + 1} out of #{Snapshot.config[:number_of_retries] + 1} times"
+ run_for_device_and_language(language, device, launch_arguments, retries + 1)
+ else
+ UI.error "Backtrace:\n\t#{ex.backtrace.join("\n\t")}" if $verbose
+ self.collected_errors << ex
+ raise ex if Snapshot.config[:stop_after_first_error]
+ return false # for the results
+ end
+ end
+
def config_launch_arguments
launch_arguments = Array(Snapshot.config[:launch_arguments])
# if more than 1 set of arguments, use a tuple with an index
if launch_arguments.count == 1
[launch_arguments]
@@ -85,10 +99,11 @@
puts ""
puts Terminal::Table.new(params)
puts ""
end
+ # Returns true if it succeded
def launch(language, device_type, launch_arguments)
screenshots_path = TestCommandGenerator.derived_data_path
FileUtils.rm_rf(File.join(screenshots_path, "Logs"))
FileUtils.rm_rf(screenshots_path) if Snapshot.config[:clean]
FileUtils.mkdir_p(screenshots_path)
@@ -103,11 +118,11 @@
uninstall_app(device_type) if Snapshot.config[:reinstall_app]
command = TestCommandGenerator.generate(device_type: device_type)
- Helper.log_alert("#{device_type} - #{language}")
+ UI.header("#{device_type} - #{language}")
prefix_hash = [
{
prefix: "Running Tests: ",
block: proc do |value|
@@ -123,39 +138,39 @@
loading: "Loading...",
error: proc do |output, return_code|
ErrorHandler.handle_test_error(output, return_code)
# no exception raised... that means we need to retry
- Helper.log.info "Caught error... #{return_code}".red
+ UI.error "Caught error... #{return_code}"
- self.number_of_retries += 1
- if self.number_of_retries < 20
+ self.number_of_retries_due_to_failing_simulator += 1
+ if self.number_of_retries_due_to_failing_simulator < 20
launch(language, device_type, launch_arguments)
else
# It's important to raise an error, as we don't want to collect the screenshots
- raise "Too many errors... no more retries...".red
+ UI.crash!("Too many errors... no more retries...")
end
end)
raw_output = File.read(TestCommandGenerator.xcodebuild_log_path)
return Collector.fetch_screenshots(raw_output, language, device_type, launch_arguments.first)
end
def uninstall_app(device_type)
- Helper.log.debug "Uninstalling app '#{Snapshot.config[:app_identifier]}' from #{device_type}..."
+ UI.verbose "Uninstalling app '#{Snapshot.config[:app_identifier]}' from #{device_type}..."
Snapshot.config[:app_identifier] ||= ask("App Identifier: ")
device_udid = TestCommandGenerator.device_udid(device_type)
- Helper.log.info "Launch Simulator #{device_type}".yellow
- `xcrun instruments -w #{device_udid} &> /dev/null`
+ UI.message "Launch Simulator #{device_type}"
+ Helper.backticks("xcrun instruments -w #{device_udid} &> /dev/null")
- Helper.log.info "Uninstall application #{Snapshot.config[:app_identifier]}".yellow
- `xcrun simctl uninstall #{device_udid} #{Snapshot.config[:app_identifier]} &> /dev/null`
+ UI.message "Uninstall application #{Snapshot.config[:app_identifier]}"
+ Helper.backticks("xcrun simctl uninstall #{device_udid} #{Snapshot.config[:app_identifier]} &> /dev/null")
end
def clear_previous_screenshots
- Helper.log.info "Clearing previously generated screenshots".yellow
+ UI.important "Clearing previously generated screenshots"
path = File.join(".", Snapshot.config[:output_directory], "*", "*.png")
Dir[path].each do |current|
File.delete(current)
end
end
@@ -165,12 +180,12 @@
helper_files = Update.find_helper
helper_files.each do |path|
content = File.read(path)
if content.include?("start.pressForDuration(0, thenDragToCoordinate: finish)")
- Helper.log.error "Your '#{path}' is outdated, please run `snapshot update`".red
- Helper.log.error "to update your Helper file".red
- raise "Please update your Snapshot Helper file".red
+ UI.error "Your '#{path}' is outdated, please run `snapshot update`"
+ UI.error "to update your Helper file"
+ UI.user_error!("Please update your Snapshot Helper file")
end
end
end
# rubocop:enable Style/Next
end